Unity筆記-09-玩家控制器
WASD控制人物朝向行走以及滑鼠控制人物正方向
需求分析
攝像機跟隨
攝像機保持在人物的后方并且相對靜止,人物朝向旋轉,攝像機也能夠繞著人物進行旋轉并保持距離不變,也就是說攝像機位于以人物為圓心的r距離圓形軌道上
滑鼠移動控制攝像機鏡頭旋轉人物正方向
滑鼠移動能夠控制人物的正方向,例如滑鼠左移,人物朝向旋轉到左,并且攝像機能夠自動移動到對應位置,保持玩家視角不變
鍵盤控制人物朝向并能夠移動
WASD可以控制人物的朝向向前,左,后,右方向并能夠沿著朝向移動
功能拆解與逐步實作
實作:攝像機跟隨
游戲開始時,給予攝像機初始跟隨位置
獲得攝像機初始偏移量,該初始偏移量將會是攝像機跟隨人物的永久偏移量,模長是不變的,也就是由人物指向攝像機的方向向量,通過攝像機向量減去人物向量即可獲得偏移量
Vector3 relative = camera.transform.position - transform.position;
每次人物移動,滑鼠移動攝像機都必須保持跟隨,因此需要將偏移量加上人物位置即為攝像機位置
camera.transform.position = transform.position + relative;
實作:滑鼠控制鏡頭以及人物正方向
通過虛擬軸獲得滑鼠移動量
float x = Input.GetAxis("Mouse X");
float y = Input.GetAxis("Mouse Y");
滑鼠水平移動,控制人物朝向以及攝像機旋轉
更改人物正方向以及攝像機朝向,注意這里不能加入垂直旋轉,因此抬頭僅僅是視角向上以及人物的對應抬頭影片,人物的朝向不能有垂直方向的偏移,注意人物的正方向與攝像機朝向時時刻刻都是一致的
transform.forward = Quaternion.Euler(0, x, 0)*transform.forward;
camera.transform.forward = transform.forward;
攝像機旋轉,首先攝像機的偏移量應當旋轉,這是由人物指向物體的方向向量,對應旋轉控制攝像機旋轉后的位置
relative = Quaternion.Euler(0, x, 0) * relative; 偏移量旋轉
camera.transform.position = transform.position + relative; 旋轉后的偏移量加人物位置向量即為攝像機位置
實作:鍵盤控制人物朝向并移動
虛擬軸獲得鍵盤按鍵
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
注意,通過虛擬軸的獲得的人物移動方向向量應當以人物的坐標系為準,因此需要通過transform.TransformPoint方法將自身坐標系對應方向向量轉化為世界坐標系對應向量,再將此向量減去人物位置向量,即可獲得與人物坐標系對應方向向量方向一致的世界坐標系向量
Vector3 Direction = transform.TransformPoint(x, 0, y);
Direction =Direction-transform.position;
但是由于人物朝向與正方向設定的沖突,因此需要將腳本掛在人物的父空物體上,通過父空物體的移動來控制人物移動,人物朝向則另外控制,防止沖突,
控制父空物體移動
transform.Translate(x*Time.deltaTime, 0, y*Time.deltaTime);
調整人物對應朝向
Enemy.forward=Direction;
播放移動影片
滑鼠隱藏與位置鎖定
按下Command滑鼠顯示,解除鎖定,其余情況滑鼠隱藏,并鎖定在螢屏中央
if (!Input.GetKey(KeyCode.LeftCommand))
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
else
{
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
完整代碼
public class PlayerControl : MonoBehaviour
{
/// <summary>
/// 攝像機
/// </summary>
private Camera camera;
/// <summary>
/// 初始偏移量
/// </summary>
private Vector3 relative;
/// <summary>
/// 影片組件
/// </summary>
private Animation anim;
/// <summary>
/// 人物組件
/// </summary>
private Transform Enemy;
/// <summary>
/// 初始化
/// </summary>
private void Start()
{
Enemy = transform.GetChild(0);
anim = transform.GetChild(0).GetChild(0).GetComponent<Animation>();
camera = GameObject.FindObjectOfType<Camera>();
//初始偏移量初始化使用初始設定好的位置方便除錯
relative = camera.transform.position - transform.position;
}
/// <summary>
/// 攝像機跟隨
/// </summary>
private void CameraFollow()
{
camera.transform.position = transform.position + relative;
}
/// <summary>
/// 滑鼠控制
/// </summary>
private void MouseControlForward()
{
float x = Input.GetAxis("Mouse X");
float y = Input.GetAxis("Mouse Y");
if (x != 0 || y != 0)
{
transform.forward = Quaternion.Euler(0, x, 0)*transform.forward;
camera.transform.forward = transform.forward;
relative = Quaternion.Euler(0, x, 0) * relative;
camera.transform.position = transform.position + relative;
}
else
{
CameraFollow();
}
}
/// <summary>
/// 滑鼠隱藏
/// </summary>
private void MouseHide()
{
if (!Input.GetKey(KeyCode.LeftCommand))
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
else
{
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
}
/// <summary>
/// 人物移動
/// </summary>
private void move()
{
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D))
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
Vector3 Direction = transform.TransformPoint(x, 0, y);
Direction =Direction-transform.position;
transform.Translate(x*Time.deltaTime, 0, y*Time.deltaTime);
Enemy.forward=Direction;
anim.Play("EnemyRun");
}
else
{
anim.Stop("EnemyRun");
}
}
/// <summary>
/// 渲染更新
/// </summary>
private void Update()
{
move();
MouseControlForward();
MouseHide();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302579.html
標籤:其他
