Unity3d--第三人稱角色移動控制
阿新 • • 發佈:2018-11-09
第三人稱的角色移動控制方案有很多種:
- 前提:相機Camera已經為角色Player的子物體【自行調節第三人稱角度】
1. rigidbody.velocity() : 通過控制剛體的速度 來實現對角色的移動控制
public GameObject thirdPersonPlayer; //角色
public float MoveSpeed = 10.0f; //移動速度
public float RotateSpeed = 10.0f; //旋轉速度
private Rigidbody PlayerRigidbody; //角色的剛體元件
void Start()
{
PlayerRigidbody = thirdPersonPlayer.GetComponent<Rigidbody>();
}
void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))//跳躍
{
PlayerRigidbody.velocity = new Vector3(0, 5, 0);
}
//獲取WSAD鍵
float h = Input.GetAxis("Horizontal"); //左右
float v = Input.GetAxis("Vertical" ); //前後
Vector3 GlobalPos = thirdPersonPlayer.transform.position;//物體所處的世界座標
//方案1:
//通過transform.TransformPoint()求出相對與物體前方距離為-1-的世界座標
//通過兩座標向量相減得到 物體需要移動的方向
//Vector3 GlobalPosForward = thirdPersonPlayer.transform.TransformPoint(Vector3.forward);
//Vector3 ForwardDirection = v * (GlobalPosForward - GlobalPos);//物體前後移動的方向
//求出物體右方距離為-1-的世界座標
//Vector3 GlobalPosRight = thirdPersonPlayer.transform.TransformPoint(Vector3.right);
//Vector3 RightDirection = h * (GlobalPosRight - GlobalPos);//物體左右移動的方向
//方案2:
//通過transform.TransformDirection()求出相對與物體前方方向的世界方向
Vector3 GlobalDirectionForward = thirdPersonPlayer.transform.TransformDirection(Vector3.forward);
Vector3 ForwardDirection = v * GlobalDirectionForward;//物體前後移動的方向
//求出相對於物體右方方向的世界方向
Vector3 GlobalDirectionRight = thirdPersonPlayer.transform.TransformDirection(Vector3.right);
Vector3 RightDirection = h * GlobalDirectionRight;//物體左右移動的方向
//再將前後左右需要移動的方向都加起來 得出 最終要移動的方向
Vector3 MainDirection = ForwardDirection + RightDirection;
//通過給剛體的 指定的方向 施加速度,得以控制角色運動
PlayerRigidbody.velocity = new Vector3(
MoveSpeed * MainDirection.x,
PlayerRigidbody.velocity.y,
MoveSpeed * MainDirection.z
);
//另外,一般第三人稱角色控制的遊戲,可通過滑鼠左右移動控制旋轉
float x = RotateSpeed * Input.GetAxis("Mouse X");
thirdPersonPlayer.transform.rotation = Quaternion.Euler(
thirdPersonPlayer.transform.rotation.eulerAngles +
Quaternion.AngleAxis(x, Vector3.up).eulerAngles
);
}
- 小提示: 對於角色控制,也可以通過控制Player的剛體元件的 Drag/AngularDrag【阻力】 來限制角色的移動
可能有人會問,用一次rigidbody.velocity()這麼麻煩!!
確實,使用這個介面所改變的速度的方向始終是世界座標的方向,真是麻煩~~~
2. rigidbody.MovePosition() : 通過調整剛體的Position 來實現對角色的移動控制
- 提示 1: 不直接修改剛體的position而是通過呼叫公共函式MovePosition() : 使運動更加平滑(使用內插值)
- 提示 2: 不使用transform.position而是使用剛體的position : 前者會導致物體的Colliders重新計算相對於剛體的位置,會更加耗費效能
public GameObject thirdPersonPlayer; //角色
public float MoveSpeed = 10.0f; //移動速度
public float RotateSpeed = 10.0f; //旋轉速度
private Rigidbody PlayerRigidbody; //角色的剛體元件
void Start()
{
PlayerRigidbody = thirdPersonPlayer.GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = Input.GetAxis("Horizontal"); //左右
float v = Input.GetAxis("Vertical"); //前後
Vector3 GlobalDirectionForward = thirdPersonPlayer.transform.TransformDirection(Vector3.forward);
Vector3 ForwardDirection = v * GlobalDirectionForward * Time.fixedDeltaTime;//物體前後移動的方向
Vector3 GlobalDirectionRight = thirdPersonPlayer.transform.TransformDirection(Vector3.right);
Vector3 RightDirection = h * GlobalDirectionRight * Time.fixedDeltaTime;//物體左右移動的方向
Vector3 MainDirection = ForwardDirection + RightDirection;
PlayerRigidbody.MovePosition(PlayerRigidbody.position + MainDirection * MoveSpeed);
}
3. rigidbody.AddForce() / AddRelativeForce(): 通過給剛體的施加力,來實現對角色的移動控制,模擬慣性(例如:開車)
public GameObject thirdPersonPlayer; //角色
private Rigidbody PlayerRigidbody; //角色的剛體元件
public float MoveForce = 10.0f; //施加的力的大小
void Start()
{
PlayerRigidbody = thirdPersonPlayer.GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = Input.GetAxis("Horizontal"); //左右
float v = Input.GetAxis("Vertical"); //前後
//方案1 :
Vector3 GlobalDirectionForward = thirdPersonPlayer.transform.TransformDirection(Vector3.forward);
Vector3 ForwardDirection = v * GlobalDirectionForward;//物體前後移動的方向
Vector3 GlobalDirectionRight = thirdPersonPlayer.transform.TransformDirection(Vector3.right);
Vector3 RightDirection = h * GlobalDirectionRight;//物體左右移動的方向
Vector3 MainDirection = ForwardDirection + RightDirection;
PlayerRigidbody.AddForce(MainDirection * MoveForce , ForceMode.Force);
//方案2 :
PlayerRigidbody.AddRelativeForce((h * Vector3.right + v * Vector3.forward) * MoveForce,ForceMode.Force);
}