1. 程式人生 > >Unity學習之Stealth學習筆記

Unity學習之Stealth學習筆記

      在學習unity官方教程Stealth時發現了一個非常好的攝像機跟隨,於是記下來。

public class CameraMovement : MonoBehaviour {

    public float smooth = 1.5f;                                                                        // 攝像機跟蹤速度

    public Transform player;                                                                            //主角的位置
    public Vector3 ralCameraPos;                                                                        //攝像機位置相對位置
    public float ralCameraPosMag;                                                                       //攝像機到主角的距離
    public Vector3 newPos;                                                                              //攝像機需要移動的新位置

    void Awake()
    {
        //獲取主角的transform元件
        player = GameObject.FindGameObjectWithTag(Tags.player).transform;
        // 相對位置 = 角色位置- 攝像機位置  也可以 = 攝像機位置- 角色位置 具體看怎麼用
        ralCameraPos = player.position - transform.position;                                        
        ralCameraPosMag = ralCameraPos.magnitude - 0.5f;
    }

    void FixedUpdate()
    { 
        //計算出初始攝像機位置
        Vector3 standardPos = player.position - ralCameraPos;
        //計算出主角頭頂的攝像機位置
        Vector3 abovePos = player.position + Vector3.up * ralCameraPosMag;
        Vector3 [] checkPoints = new Vector3[5];
        //攝像機標準位置
        checkPoints[0] = standardPos;
        // 這三個檢測位置為 標準位置到俯視位置之間的三個位置 插值分別為25% 50% 75%
        checkPoints[1] = Vector3.Lerp(standardPos,abovePos,0.25f);
        checkPoints[2] = Vector3.Lerp(standardPos, abovePos, 0.5f);
        checkPoints[3] = Vector3.Lerp(standardPos, abovePos, 0.75f);
        //攝像機在角色頭頂位置
        checkPoints[4] = abovePos;
        // 通過迴圈檢測每個位置是否可以看到角色
        for (int i = 0; i < checkPoints.Length; i++)
        {
            // 如果可以看到角色
            if (ViewingPosCheck(checkPoints[i]))
            {

                break;
            }
        }
        // 讓攝像機位置 從當前位置 平滑轉至 新位置
        transform.position = Vector3.Lerp(transform.position,newPos,smooth* Time.deltaTime);
        //讓攝像機平滑的照向角色位置
        SmoothLookAt();
    }


    void SmoothLookAt()
    {
        //建立從攝像機到角色的向量
        Vector3 vec = player.position - transform.position;
        //計算旋轉角度
        Quaternion roataion = Quaternion.LookRotation(vec, Vector3.up);
        //平滑旋轉攝像機
        transform.rotation = Quaternion.Lerp(transform.rotation,roataion,smooth * Time.deltaTime);
    }

    bool ViewingPosCheck(Vector3 checkPos)
    {

        RaycastHit hit;
        //從檢測點發出一條指向主角的射線,能否檢測到主角
        if (Physics.Raycast(checkPos, player.position - checkPos, out hit, ralCameraPosMag))
        {
            if (hit.transform != player)
                return false;
        }
        //如果沒有檢測到任何東西 說明人物與檢測點中間沒有障礙物,所以這個點可用
        newPos = checkPos;
        return true;
    }

}
實現的效果主要是兩個 一是平滑的到一個能看到主角的點 (這些點到主角的位置是相同的)二是 平滑的“看”向主角。