从Quaternion.LookRotation()和Quaternion.AngleAxis()开始

需求:

行星在自转的同时,围绕太阳(pos:vector3.zero)公转。点击鼠标以切换对不同行星的观察。要求摄像机方向向量与行星到太阳的方向向量始终垂直(这样看到的行星永远是一半白天一半黑夜)。


摄像机正在观察的物体为:

Transform  focus;


死路上首先要求出行星到太阳的方向向量:

focus.transform.position-vector3.zero;(也就是focus.transform.position)

然后怎么样把这个向量转换为摄像机的角度。

这里就用到了Quaternion.LookRotation()方法


public static  Quaternion  LookRotation( Vector3  forwardVector3  upwards = Vector3.up);

Parameters

forward The direction to look in.
upwards The vector that defines in which direction up is.

Description

Creates a rotation with the specified forward and upwards directions.

Returns the computed quaternion. If used to orient a Transform, the Z axis will be aligned with forward/ and the Y axis with upwards if these vectors are orthogonal. Logs an error if the forward direction is zero.

这是官方文档的内容,对于第一个参数forward的理解比较简单,决定了使用这个rotation的transform的z轴方向(正方向/看向的方向)。

而对于upwards,一直稀里糊涂,今天做了一组实验才搞明白,就是让这个transform的y轴,尽量尽量尽量靠近这个方向。


camera.transform.rotation=Quaternion.LookRotation(focus.transform.position,vector3.up); 


到这里摄像机的正方向便与太阳到行星的方向一致了。


然后我们需要再对摄像机绕y轴旋转+90度。

camera.rotation = Quaternion.AngleAxis(90,Vector3.up)*camera.rotation;

(这里需要注意的是,四元数的乘法不符合交换律,所以一定注意使用时的顺序)


最后,让摄像机在这个方向上进行一定的偏移,就得到了想要的结果。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UniversCamera : MonoBehaviour
{

    Transform focus;

    Star[] pObjects;
    int index;

    float DefaultZoom = 100;

    Vector3 cameraRotation;
    float zoomLevel;

    new Transform camera;

    void Awake()
    {
        camera = GetComponent<Transform>();
    }

    void Start()
    {
        zoomLevel += DefaultZoom;

        index = 0;
        pObjects = FindObjectsOfType<Planet>();
        focus = pObjects[0].transform;
    }

    public Vector2 GetMouse()
    {
        return new Vector2(Input.GetAxis("Mouse X"), -Input.GetAxis("Mouse Y"));
    }

    void LateUpdate()
    {
        if (Input.GetMouseButtonDown(0))
        {
            index++;
            if (index > pObjects.Length - 1)
                index = 0;

            focus = pObjects[index].transform;
            zoomLevel = focus.localScale.x * 3;
        }

        zoomLevel = Mathf.Clamp(zoomLevel, focus.localScale.x + focus.localScale.x / 3, 150f);
        camera.rotation = Quaternion.LookRotation(focus.transform.position, Vector3.up);
        camera.rotation = Quaternion.AngleAxis(90,Vector3.up)*camera.rotation;
        camera.position = focus.transform.position - camera.forward * zoomLevel;
    }
}


Quaternion提供的这两个方法用起来非常简单,比之前自己用欧拉角计算方便很多。一直以来习惯了使用欧拉角,对Quaternion一直没怎么上心,今天用了一下,还是很爽的。兴致一下子就高涨起来了。也算是从这两个方法开始吧,好好研究一下矩阵和四元数,为后面Shader的学习打下良好的数学基础。


猜你喜欢

转载自blog.csdn.net/u010133610/article/details/70213943