unity第三人稱視角下使用手柄的攝像機控制及防穿墻
有關手柄的設定參考下面這個帖子,這里不再重復
https://blog.csdn.net/qq_45919090/article/details/109397608
要讓相機跟隨角色,首先可以讓相機成為角色的子物體,或在初始時得到相機與角色的偏移量,在運動程序中讓角色的位置加上這個偏移量即可,為了更好適應角色所處環境及實作其他功能,可以采用以下方法:

創建一個空物體Empty,在Empty下創建一個子物體Position,最后使相機成為Position的子物體,接下來我們需要設定這幾個物體(在代碼中),讓Empty的position等于人物的position,讓Position的位置等于人物的位置的Y方向加1.0f(其實可以隨意設定),再把相機設定到合適的位置使之看向角色(設定相機可以在Scene模式下設定),
創建一個C#腳本,將其掛載在Empty上,定義以下變數,并在Start方法中獲取剛才設定的物體的Transform組件以及相機與Postion的偏移量
private Transform charactor;//獲取當前角色
private Transform pos;//獲取Empty的子物體pos
private Vector3 offset;//獲取初始時鏡頭相對于pos的偏移量
private float R_H;//獲取搖桿的回傳值-水平軸
private float R_V;//獲取搖桿的回傳值-垂直軸
private float lookAngle;//鏡頭說水平旋轉的角度
private float tiltAngle;//鏡頭垂直旋轉的角度(實質為父物體pos的垂直旋轉角度)
private float moveSpeed = 10f;//用于設定鏡頭跟隨的速度
private float turnSpeed = 1.5f;//用于設定鏡頭在兩個方向上旋轉的角度
private Transform mainCamera;
// Use this for initialization
void Start()
{
charactor = GameObject.FindGameObjectWithTag("Charactor").GetComponent<Transform>();
pos = GameObject.FindGameObjectWithTag("Pos").GetComponent<Transform>();
mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Transform>();
offset = mainCamera.position - pos.position;
}
相機跟隨角色可以采用以下方法:
private void FollowCharactor(float deltaTime)
{
//注意需要把offset轉為pos的區域坐標
mainCamera.position = Vector3.Lerp(mainCamera.position, pos.position + pos.TransformDirection(offset), deltaTime * moveSpeed);
}
引入deltaTime引數和Lerp方法可以使鏡頭變換更加平滑順暢
接下來是控制鏡頭左右和上下旋轉,鏡頭的水平方向旋轉由Empty控制,垂直方向的旋轉由pos控制,這么做可以防止鏡頭注視角色的時候旋轉出現問題,比如在自身Z軸上發生旋轉
private void HandleCameraRotate()
{
transform.position = charactor.position;//設定水平旋轉角度
lookAngle += R_H * turnSpeed;
transform.localEulerAngles = new Vector3(0, lookAngle, 0);//將得到的角度賦值給empty的localEulerAngles
tiltAngle -= turnSpeed * R_V;//設定垂直旋轉角度
tiltAngle = Mathf.Clamp(tiltAngle, -80, 50);//對旋轉角度加以限制
pos.localEulerAngles = new Vector3(tiltAngle, pos.localEulerAngles.y, pos.localEulerAngles.z);//將得到的角度賦值給pos的localEulerAngles
}
這樣基本的控制就做完了,可以在Update()方法中呼叫(實測FixedUpdate和LateUpdate方法中呼叫效果不好)
void Update()
{
R_H = Input.GetAxis("Horizontal_Right");
R_V = Input.GetAxis("Vertical_Right");
HandleCameraRotate();
FollowCharactor(Time.deltaTime);
}
對于防鏡頭穿墻的方法,這是我個人想出來的可能算是比較簡單的一種寫法,在Update中呼叫即可
從pos的位置開始,創建一條指向相機的射線,長度為offset,判斷射線碰撞到的物體的標簽
private void AvoidCrossWall()
{
RaycastHit hit;
if (Physics.Raycast(pos.position, mainCamera.position - pos.position, out hit, offset.magnitude))
{
if (hit.collider.tag == "Obstacle")
{
mainCamera.position = hit.point;
}
}
}
本方法需要把不想讓墻穿過的所有物體的標簽設定為Obstacle
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/198799.html
標籤:其他
上一篇:【概率】聰聰和可可
