相机跟随的一些方法函数

1. LateUpdate

MonoBehaviour.LateUpdate()

[Description]
LateUpdate is called every frame, if the Behaviour is enabled.

LateUpdate is called after all Update functions have been called. This is useful to order script execution. For example a follow camera should always be implemented in LateUpdate because it tracks objects that might have moved inside Update.

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    void LateUpdate()
    {
        transform.Translate(0, Time.deltaTime, 0);
    }
}

In order to get the elapsed time since last call to LateUpdate, use Time.deltaTime. This function is only called if the Behaviour is enabled. Override this function in order to provide your component’s functionality.

这里官方说的几个点:
首先要调用LateUpdate得保证有Behaviour;
然后调用时间是在所有Update函数被调用完后再调用;
所以很适合用来做相机跟随(因为相机跟随目标的行为写在Update里面);
时间上用Time.deltaTime;

2. Quaternion

[Description]
Quaternions are used to represent rotations.

They are compact, don’t suffer from gimbal lock and can easily be interpolated. Unity internally uses Quaternions to represent all rotations.

They are based on complex numbers and are not easy to understand intuitively. You almost never access or modify individual Quaternion components (x,y,z,w); most often you would just take existing rotations (e.g. from the Transform) and use them to construct new rotations (e.g. to smoothly interpolate between two rotations). The Quaternion functions that you use 99% of the time are: Quaternion.LookRotation, Quaternion.Angle, Quaternion.Euler, Quaternion.Slerp, Quaternion.FromToRotation, and Quaternion.identity. (The other functions are only for exotic uses.)

You can use the Quaternion.operator * to rotate one rotation by another, or to rotate a vector by a rotation.

Note that Unity expects Quaternions to be normalized.

重要信息:
Quaternions用来表示角度;
最重要的就是用来实现平滑的角度旋转(插值);
最常用的几个:
Quaternion.LookRotation,
Quaternion.Angle,
Quaternion.Euler,
Quaternion.Slerp,
Quaternion.FromToRotation,
Quaternion.identity

e.g:

private Quaternion currentRotation;
currentRotation = Quaternion.Euler(0, currentRotationAngle, 0); //从角度值转为角度

e.g

Quaternion camRotation = Quaternion.LookRotation(target.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, camRotation, Time.deltaTime * camSpeed);

具体文档见Scripting API吧: https://docs.unity3d.com/ScriptReference/Quaternion.Slerp.html

3. Transform.eulerAngles

Transform.eulerAngles

public Vector3 eulerAngles;

Description

The rotation as Euler angles in degrees.

The x, y, and z angles represent a rotation z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis.

Only use this variable to read and set the angles to absolute values. Don’t increment them, as it will fail when the angle exceeds 360 degrees. Use Transform.Rotate instead.

using UnityEngine;

public class Example : MonoBehaviour
{
    // Assign an absolute rotation using eulerAngles
    float yRotation = 5.0f;

    void Start()
    {
        // Print the rotation around the global X Axis
        print(transform.eulerAngles.x);
        // Print the rotation around the global Y Axis
        print(transform.eulerAngles.y);
        // Print the rotation around the global Z Axis
        print(transform.eulerAngles.z);
    }

    void Update()
    {
        yRotation += Input.GetAxis("Horizontal");
        transform.eulerAngles = new Vector3(10, yRotation, 0);
    }
}

Do not set one of the eulerAngles axis separately (eg. eulerAngles.x = 10; ) since this will lead to drift and undesired rotations. When setting them to a new value set them all at once as shown above. Unity will convert the angles to and from the rotation stored in Transform.rotation.

这一段不是很懂,为什么这一个向量中的值可以用键盘的上箭头输入来表示???
“unity可以自动将角度从Transform.rotation里面转换”????
不要分别对其进行置值???像上面代码那样设置????什么意思?????

4. Mathf.LerpAngle

public static float LerpAngle(float a, float b, float t);

Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.

The parameter t is clamped to the range [0, 1]. Variables a and b are assumed to be in degrees.

using UnityEngine;

public class Example : MonoBehaviour
{
    float minAngle = 0.0f;
    float maxAngle = 90.0f;

    void Update()
    {
        float angle = Mathf.LerpAngle(minAngle, maxAngle, Time.time);
        transform.eulerAngles = new Vector3(0, angle, 0);
    }
}

今日完整代码:

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

public class Widget_Camera : MonoBehaviour {

    public Transform target; //the target object

    public float distance = 10.0f;  //距离
    public float height = 5.0f;     //高度
    public float heightDamping = 2.0f;   //摄像机高度上进行调整时候的阻尼
    public float rotationDamping = 3.0f;  //摄像机旋转时候进行调整的阻尼
    public float distanceDampingX = 0.5f;  //摄像机X轴上进行调整时候的阻尼
    public float distanceDampingZ = 0.2f;   //摄像机Z轴上进行调整时候的阻尼
    public float camSpeed = 2.0f;   //摄像机移动的速度

    public bool smoothed = true;    //摄像机是否平滑

    private float wantedRotationAngle;  //摄像机要到达的角度值
    private float wantedHeight;         //要到达的高度
    private float wantedDistanceZ;      //要到达的Z轴位置
    private float wantedDistanceX;       //要到达的X轴位置

    private float currentRotationAngle;  //摄像机当前的角度值
    private float currentHeight;         //摄像机当前的高度
    private float currentDistanceZ;      //摄像机当前的Z轴位置
    private float currentDistanceX;      //摄像机当前的X轴位置

    private Quaternion currentRotation;

    void LateUpdate()
    {
        if (!target)
        {
            return;
        }
        else
        {
            wantedRotationAngle = target.eulerAngles.y;   //取得当前摄像机要到达的角度值
            wantedHeight = target.position.y + height;  //取得摄像机要到达的高度
            wantedDistanceZ = target.position.z - distance;   //取得摄像机要到达的Z轴位置
            wantedDistanceX = target.position.x - distance;   //取得摄像机要到达的

            currentRotationAngle = transform.eulerAngles.y;   //取得当前摄像机的角度和位置
            currentHeight = transform.position.y;
            currentDistanceZ = transform.position.z;
            currentDistanceX = transform.position.x;

            currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping*Time.deltaTime);
            //平滑移动到新的角度值,置为当前角度
            currentHeight = Mathf.LerpAngle(currentHeight, wantedHeight, heightDamping * Time.deltaTime);
            //平滑到新的高度,置为当前高度;
            currentDistanceZ = Mathf.LerpAngle(currentDistanceZ, wantedDistanceZ, distanceDampingZ * Time.deltaTime);
            //平滑到新的Z轴位置,置为当前Z轴位置
            currentDistanceX = Mathf.LerpAngle(currentDistanceX, wantedDistanceX, distanceDampingX * Time.deltaTime);
            //平滑到新的X轴位置,置为当前X轴位置

            currentRotation = Quaternion.Euler(0, currentRotationAngle, 0); //从角度值转为角度

            transform.position -= currentRotation * Vector3.forward * distance;  //摄像机往目标位置移动
            transform.position = new Vector3(currentDistanceX, currentHeight, currentDistanceZ);  //不断更新摄像机位置

            LookAtMe();


        }

    }

    void LookAtMe()
    {
        if (smoothed)
        {
            Quaternion camRotation = Quaternion.LookRotation(target.position - transform.position);
            transform.rotation = Quaternion.Slerp(transform.rotation, camRotation, Time.deltaTime * camSpeed);
        }
        else
        {
            transform.LookAt(target);   //始终盯着目标物体
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值