1. 程式人生 > >Stealth行動中角色的移動和攝像機的跟隨

Stealth行動中角色的移動和攝像機的跟隨

看了官網的案例真的是學了不少的東西,就像這個角色移動官網使用了四元素來編寫角色的轉彎。各位大佬原諒我這個小白的無知大笑

先附上我寫的程式碼

發圖 

/// <summary>
/// 控制角色的移動類
/// </summary>
public class PlayerMove : MonoBehaviour
{
    public float turnSmoothing = 15f;   // 角色轉彎的平滑值
    private float speed = 1;            // 角色前進的速度
    private Animator anim;              // 引用角色的Animator元件


    void Awake()
    {
        anim = GetComponent<Animator>();//獲得角色身上的Animator元件
    }


    void Update()
    {
        //使用水平和垂直軸作為輸入
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        //角色的位置為我們水平和垂直的按鍵輸入
        gameObject.transform.position += new Vector3(h, 0, v) * Time.deltaTime * speed;
        anim.SetFloat("Speed",Mathf.Abs(h)+Mathf.Abs(v));//設定角色動畫狀態及中的速度引數過度,為水平和垂直的絕對值和Mathf.Abs(h+v)

        //如果水平和垂直不為0才能旋轉,如果不寫這個判斷會出現轉過去之後鬆開按鍵此時h=0 v=0,那麼角色的旋轉也為0也就是角色沒有旋轉又轉回來。
        if (h !=0 || v != 0)
        {
            Rotating(h, v);
        }
    }

    /// <summary>
    /// 控制角色的轉彎
    /// </summary>
    /// <param name="horizontal"> 水平</param>
    /// <param name="vertical">垂直</param>
    void Rotating(float horizontal, float vertical)
    {
        //設定玩家要轉向的目標方向
        Vector3 targetDirection = new Vector3(horizontal, 0f, vertical);
        //將上面的targetDirection設定為四元素。LookRotation可以使玩家的Z軸轉向到朝著targetDirection方向,Y軸向上
        Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
        //使玩家由當前的旋轉角度平滑的過渡到目標的旋轉角度,turnSmoothing*Time.deltaTime是旋轉速度,這裡乘上Time.deltaTime是減慢的作用
        Quaternion newRotation = Quaternion.Lerp(transform.rotation, targetRotation, turnSmoothing * Time.deltaTime);
        //將玩家當前的旋轉角度設定為我們的新角度
        gameObject.transform.localRotation = newRotation;

    }  
}
大家有什麼好的想法可以在下面給我一些指導,謝謝

下面是攝像機跟隨人物的移動

public class CameraMove : MonoBehaviour
{
    public GameObject player;     //儲存角色
    public float smooth = 1.5f;   //相機平滑移動
    private Vector3 relCameraPos; //攝像機與玩家的相對位置
    private float relCameraPosMag; //相對位置的向量長度
    private Vector3 newPos;       //攝像機移動的新位置
   
   void Awake ()
    {
        relCameraPos = transform.position - player.transform.position;//計算玩家和攝像機之間的距離 相當於A點距離B點相對位置為C求 B點位置=A點+C點
        relCameraPosMag = relCameraPos.magnitude - 0.5f;               //(小一點,因為玩家位置座標在腳上,之後光線檢測可能或接觸到地面,所以減去0.5可能碰撞到玩家的腹部)

    }
    void Update()
    {
        Vector3 standarPos = player.transform.position + relCameraPos;               //攝像機的初始位置等於玩家位置加上相對位置
        Vector3 abovePos   = player.transform.position + Vector3.up * relCameraPosMag;//攝像機的俯視位置
        Vector3[] checkPoint = new Vector3[5];                                       //儲存攝像機的位置陣列
        checkPoint[0] = standarPos;                                                  //設定攝像機初始位置
        checkPoint[1] = Vector3.Lerp(standarPos,abovePos,0.25f);                     //從攝像機的初始位置到角色正上方的位置之間的距離,該點為這段距離25%處的點,從攝像機的初始weihz
        checkPoint[2] = Vector3.Lerp(standarPos,abovePos,0.5f);                      //從攝像機的初始位置到角色正上方的位置之間的距離,該點為這段距離25%處的點,從攝像機的初始位置開始計算
        checkPoint[3] = Vector3.Lerp(standarPos,abovePos,0.75f);                     //從攝像機的初始位置到角色正上方的位置之間的距離,該點為這段距離25%處的點,從攝像機的初始位置開始計算      
        checkPoint[4] = abovePos;                                                    //從攝像機的初始位置到角色正上方的位置之間的距離,該點為這段距離25%處的點,從攝像機的初始位置開始計算
        //依次將我們設定的檢測點來檢測是否能看到角色,如果某個檢測點可以看到角色讓攝像機平滑移動帶這個監測點
        for (int i = 0; i < checkPoint.Length; i++)
        {
            //如果檢測到的是玩家則跳出當前迴圈
            if (ViewPosCheck(checkPoint[i]))
            {
                break;
            }
        }
        //讓攝像機平滑的移動到監測點
        transform.position = Vector3.Lerp(transform.position, newPos, smooth * Time.deltaTime);
        //讓攝像機轉向角色
        SmoothLookAt();

    }

    /// <summary>
    /// 利用射線檢測玩家, 原理就是從攝像機發射一條射線,沿著玩家到監測點的方向,射線長度是相對向量的長度。
    /// </summary>
    bool ViewPosCheck(Vector3 checkPos)
    {
        //使用射線檢測攝像機是否能夠檢測到玩家
        RaycastHit hit;    // 檢測位置  攝像機指向玩家的相對位置                  相對向量長度
        if (Physics.Raycast(checkPos,player.transform.position-checkPos,out hit,relCameraPosMag))
        {
            //如果檢測到不是玩家
            if (hit.transform.gameObject!=player) //如果檢測到的是不是玩家
            {
                return false;  //返回false
            }
           
        }
        //設定攝像機新位置為該檢測點的位置
        newPos = checkPos;
         return true;                   

    }

    /// <summary>
    /// 讓攝像機平滑的轉向玩家
    /// </summary>
    void SmoothLookAt()
    {
         //從攝像機的位置指向玩家的向量
         Vector3 relPlayerPosition = player.transform.position - transform.position;

        //根據攝像機到玩家的向量建立旋轉角度 也就是建立一個旋轉,使z軸朝向relPlayerPosition y軸朝向up。
         Quaternion lookAtRotation = Quaternion.LookRotation(relPlayerPosition, Vector3.up); 

         //從攝像機的旋轉角度旋轉到攝像機指向玩家的旋轉位置
         transform.rotation = Quaternion.Lerp(transform.rotation, lookAtRotation, smooth * Time.deltaTime);
    }
}

這是我自己的理解,有好的方法或者錯的地方希望大家給我指教,謝謝。