unity 第三人稱控制移動


鍵盤WSAD控制行走

最簡單的就是使用Input.GetKeyDown()函數接收鍵盤
值輸入,但在這里還有更簡單的方法去實現。

利用Input.GetAxis()來獲取坐標軸的改變。在InputManager中有許多參數,對應目前的需求只要HorizontalVertical這兩個,前者對應坐標系的左右,后者對應前后。

float H = Input.GetAxis("Horizontal");
float V = Input.GetAxis("Vertical");
//Debug.Log("H: " + H + " V: " + V);
Vector3 direction = H * m_transform.right + V * m_transform.forward;
Vector3 NewPosition = m_rigidbody.position + direction;
m_rigidbody.MovePosition(NewPosition);

攝像機固定在主角的后上方

代碼需要綁定在主攝像機上,基本思想就是在Update()中檢測主角的坐標軸,然后根據主角的坐標算出攝像機應該所在的位置,在利用LookAt()函數使攝像機角度轉向主角。

這里為了使攝像機的轉向趨於平滑,可以使用Lerp()函數。

Vector3 NextPos = target.forward * -1 * distance + target.up * high + target.position;
m_trans.position = Vector3.Lerp(this.transform.position, NextPos, smoothSpeed);     // 平滑跟進
m_trans.LookAt(target);

鼠標控制主角在水平方向旋轉

目前采用的方法是Input.GetAxis()來獲取鼠標的Mouse X參數值,再配合Rotate()函數可以實現旋轉效果。

float h = 10.0f * Input.GetAxis("Mouse X");
transform.Rotate(0, h, 0);

添加鼠標控制攝像機上下旋轉功能

想要添加這個功能,我差不多要把前面的代碼全部重構一遍。因為之前的代碼為了讓攝像機跟隨人物,我使用了LookAt()函數;而左右旋轉只是主角的操作,攝像機只需要跟隨就好。

但涉及攝像機上下旋轉之時,我們不可能也給主角添加一個上下旋轉的功能。LookAt()是不可以使用的了,但為了讓攝像機跟隨主角,我們需要用其他方式實現同樣的功能。

我在網上看到一個很巧妙的解決方式,利用的是三角函數:

// 通過camera的Y軸旋轉角度(即左右偏轉角)及確定的直角斜邊distance,計算直角三角形的兩條直角邊(分別對應x, z的后移量)
// 該方法可保證相機位置永遠在player后方,但相機鏡頭需要對准player或與之朝向一致
float angle = m_transform.eulerAngles.y;

float distance_X = distance * Mathf.Sin(angle * Mathf.PI / 180);
float distance_Z = distance * Mathf.Cos(angle * Mathf.PI / 180);

Vector3 newPosition = new Vector3(player.position.x - distance_X, player.position.y + high, player.position.z - distance_Z);
// 平滑移動
m_transform.position = Vector3.Lerp(m_transform.position, newPosition, smoothMoveTime);

此處有兩個坑需要注意:
其一,用這種計算的方式找到位置,對性能消耗可能比較大;
其二,就這幾天上網搜索的結果看,簡單的移動有太多方法了,而且這些方法還涉及到性能的問題,emmm,以后填吧。

上面說到需要借助camera的Y偏轉角來實現跟隨,其實也可以通過player的偏轉角來實現。兩者間的性能差距我看不出來。

下面是利用GetAxis()來獲得鼠標的偏移量,從而實現偏轉。

float Mouse_X = Input.GetAxis("Mouse X") * smoothRotateAmount;
float Mouse_Y = Input.GetAxis("Mouse Y") * smoothRotateAmount;

rotation.x -= Mouse_Y;
rotation.y += Mouse_X;   // 使之與鼠標移動方向一致
rotation.z = 0;          // 固定z軸

//m_transform.Rotate(rotation, Space.Self);     // Rotate()會產生天翻地覆的效果,原因不知,猜測是它太快了
m_transform.eulerAngles = rotation;             // 會有卡頓現象,可能性能消耗大,但是在本項目中離奇有用

// 放在PlayController上比較好,因為不能基於camera來計算偏轉角
//float horizontal = smoothRotateAmount * Input.GetAxis("Mouse X");
//player.eulerAngles = new Vector3(0, horizontal, 0);

這里有坑,已經踩了很久了。暫時先這樣,等下次再遇到的時候解決,附上一篇還看得不是很懂的文章:Unity學習筆記10——旋轉(四元數和歐拉角)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM