1. 程式人生 > >[Unity3D 版本5.X]實現一個跟隨攝像機,聚焦到客戶端主角身上

[Unity3D 版本5.X]實現一個跟隨攝像機,聚焦到客戶端主角身上

bsp mono pan 歐拉角 cnblogs button 右鍵 span htk

遊戲中的攝像機,都是聚焦到客戶端主角身上。

為了實現這個功能,我寫了兩個腳本,第一個腳本用來控制客戶端主角的位置和旋轉,使用WSAD鍵控制主角的前後左右移動,使用鼠標右鍵控制主角的旋轉。

第二個腳本是根據客戶端主角的transform,設置攝像機的transform,使得攝像機聚焦在主角身上。

這兩個腳本都是設置成客戶端主角的組件。

第一個腳本 FiMainPlayerMoveCtrl.cs

//-----------------------------------------------------------------  
//1,客戶端主角的移動控制,使用WSAD鍵控制上下左右移動,使用鼠標右鍵控制旋轉。  
//2,左手坐標系。 //3,歐拉角使用的單位是角度,不是弧度。 //----------------------------------------------------------------- using System.Collections; using System.Collections.Generic; using UnityEngine; //----------------------------------------------------------------- public class FiMainPlayerMoveCtrl : MonoBehaviour {
public float moveSpeed = 30.0f; public float rotateSpeed = 0.2f; public float mouseWheelSpeed = 50.0f; public static Vector3 kUpDirection = new Vector3(0.0f, 1.0f, 0.0f); //記錄角色的旋轉角度。 //以上方向為軸的旋轉角度。 private float m_fEulerAngleUpDir = 0.0f; //以右方向為軸的旋轉角度。 //這個歐拉角不會施加在角色身上,當攝像機聚焦在本角色上時,會施加到攝像機上。
private float m_fEulerAngleRightDir = 0.0f; //當攝像機聚焦在本角色上時,記錄本角色與攝像機之間的直線距離。 private float m_fDistanceFromCamera = 100.0f; //控制角色旋轉的成員變量。 private float m_fLastMousePosX = 0.0f; private float m_fLastMousePosY = 0.0f; private bool m_bMouseRightKeyDown = false; //記錄本幀內Transform是否發生了變化。 //當攝像機聚焦在本角色上時,只有本Transform發生了變化,才更新攝像機的Transform。 private bool m_bTransformChanged = false; //----------------------------------------------------------------- void Start() { Vector3 kEulerAngles = transform.eulerAngles; m_fEulerAngleRightDir = kEulerAngles.x; m_fEulerAngleUpDir = kEulerAngles.y; } //----------------------------------------------------------------- void Update() { m_bTransformChanged = false; //判斷旋轉 if (Input.GetMouseButtonDown(1)) //鼠標右鍵剛剛按下了 { if (m_bMouseRightKeyDown == false) { m_bMouseRightKeyDown = true; Vector3 kMousePos = Input.mousePosition; m_fLastMousePosX = kMousePos.x; m_fLastMousePosY = kMousePos.y; } } else if (Input.GetMouseButtonUp(1)) //鼠標右鍵剛剛擡起了 { if (m_bMouseRightKeyDown == true) { m_bMouseRightKeyDown = false; m_fLastMousePosX = 0; m_fLastMousePosY = 0; } } else if (Input.GetMouseButton(1)) //鼠標右鍵處於按下狀態中 { if (m_bMouseRightKeyDown) { Vector3 kMousePos = Input.mousePosition; float fDeltaX = kMousePos.x - m_fLastMousePosX; float fDeltaY = kMousePos.y - m_fLastMousePosY; m_fLastMousePosX = kMousePos.x; m_fLastMousePosY = kMousePos.y; m_fEulerAngleRightDir -= (fDeltaY * rotateSpeed); m_fEulerAngleUpDir -= -(fDeltaX * rotateSpeed); Vector3 kNewEuler = new Vector3(0.0f, m_fEulerAngleUpDir, 0.0f); transform.eulerAngles = kNewEuler; m_bTransformChanged = true; } } //判斷位移 float fMoveDeltaX = 0.0f; float fMoveDeltaZ = 0.0f; float fDeltaTime = Time.deltaTime; if (Input.GetKey(KeyCode.A)) { fMoveDeltaX -= moveSpeed * fDeltaTime; } if (Input.GetKey(KeyCode.D)) { fMoveDeltaX += moveSpeed * fDeltaTime; } if (Input.GetKey(KeyCode.W)) { fMoveDeltaZ += moveSpeed * fDeltaTime; } if (Input.GetKey(KeyCode.S)) { fMoveDeltaZ -= moveSpeed * fDeltaTime; } if (fMoveDeltaX != 0.0f || fMoveDeltaZ != 0.0f) { Vector3 kForward = transform.forward; Vector3 kRight = Vector3.Cross(kUpDirection, kForward); Vector3 kNewPos = transform.position; kNewPos += kRight * fMoveDeltaX; kNewPos += kForward * fMoveDeltaZ; //把Y值設置成0,只能在平面上移動。 kNewPos.y = 0.0f; transform.position = kNewPos; m_bTransformChanged = true; } float fWheel = Input.GetAxis("Mouse ScrollWheel"); if (fWheel != 0.0f) { m_fDistanceFromCamera -= fWheel * mouseWheelSpeed; m_bTransformChanged = true; } } //----------------------------------------------------------------- public float GetEulerAngleRightDir() { return m_fEulerAngleRightDir; } //----------------------------------------------------------------- public float GetEulerAngleUpDir() { return m_fEulerAngleUpDir; } //----------------------------------------------------------------- public float GetDistanceFromCamera() { return m_fDistanceFromCamera; } //----------------------------------------------------------------- public bool IsTransformChanged() { return m_bTransformChanged; } } //-----------------------------------------------------------------

第二個腳本 FiCameraControl.cs

//-----------------------------------------------------------------  
//1,攝像機要聚焦在GameObjectA上,那麽就把本腳本作為一個組件,添加到GameObjectA中。  
//2,GameObjectA中必須包含 FiMainPlayerMoveCtrl 組件。  
//3,左手坐標系。  
//-----------------------------------------------------------------  
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
//-----------------------------------------------------------------  
public class FiCameraControl : MonoBehaviour  
{  
    //本Object必須有一個 FiMainPlayerMoveCtrl 組件。  
    private FiMainPlayerMoveCtrl m_kMainPlayerMoveCtrl = null;  
    //攝像機的 Transform 組件。  
    private Transform m_kMainCameraTransform = null;  
  
    //記錄是否為第一幀。  
    //如果是第一幀,必須更新攝像機的Transform,使得攝像機聚焦在本Object上。  
    private bool m_bFirstFrame = true;  
  
    //-----------------------------------------------------------------  
    void Start()  
    {  
        m_kMainPlayerMoveCtrl = GetComponent<FiMainPlayerMoveCtrl>();  
        m_kMainCameraTransform = Camera.main.transform;  
        m_bFirstFrame = true;  
    }  
    //-----------------------------------------------------------------  
    void Update()  
    {  
          
    }  
    //-----------------------------------------------------------------  
    void LateUpdate()  
    {  
        if (m_kMainPlayerMoveCtrl == null)  
        {  
            return;  
        }  
        if (m_kMainPlayerMoveCtrl.IsTransformChanged() == false)  
        {  
            if (m_bFirstFrame == false)  
            {  
                return;  
            }  
        }  
        m_bFirstFrame = false;  
  
        //設置攝像機的旋轉。  
        float fEulerAngleRightDir = m_kMainPlayerMoveCtrl.GetEulerAngleRightDir();  
        float fEulerAngleUpDir = m_kMainPlayerMoveCtrl.GetEulerAngleUpDir();  
        Vector3 kEulerAngle = new Vector3(fEulerAngleRightDir, fEulerAngleUpDir, 0.0f);  
        m_kMainCameraTransform.eulerAngles = kEulerAngle;  
  
        //設置攝像機的位置。  
        Vector3 kPos = transform.position;  
        float fDistance = m_kMainPlayerMoveCtrl.GetDistanceFromCamera();  
        kPos -= m_kMainCameraTransform.forward * fDistance;  
        m_kMainCameraTransform.position = kPos;     
    }  
}  
//-----------------------------------------------------------------  

[Unity3D 版本5.X]實現一個跟隨攝像機,聚焦到客戶端主角身上