1. 通过代码直接修改物体位置的方式
主要方法如trnasform.position+=offset
、transform.Translate(offset)
等,offset为角色每帧位置的偏移量,给角色添加碰撞体和刚体后,可作为角色控制器使用。
使用此种方式时,移动代码写道Update中时,角色和碰撞体交互时会产生抖动现象,写到FixedUpdate中可解决。
示例:
void FixedUpdate()
{
float horizontal=Input.GetAxis("Horizontal");
float vertical=Input.GetAxis("Vertical");
transform.Translate(new Vector3(horizontal,0f,vertical),Space.World);
}
2. 通过CharacterController
主要方法如CharacterController.Move(offset)
、CharacterController.SimpleMove(Speed)
等,CharacterController
无法对其他物体施加力(不能推开箱子),也不会受到力的影响,一个很明显的表现就是给角色添加刚体组件后,角色不会像一般的碰撞体没那样下落,所以需要使用代码模拟重力来控制角色下落。
示例:
void Update()
{
float horizontal=Input.GetAxis("Horizontal");
float vertical=Input.GetAxis("Vertical");
Vector3 horizontalVelocity=new Vector3(horizontal,0f,vertical);//水平速度
float verticalVelocity=CharacterController.velocity.y;//垂直速度
if(CharacterController.isGrounded&&verticalVelocity<0f)
{
verticalVelocity=0f;
}
verticalVelocity-=Time.deltaTime*gravity;//gravity重力加速度
CharacterController.Move((horizontalVelocity+verticalVelocity*Vector3.up)*Time.deltaTime);
}
虽然CharacterController
继承自Collider
,但无法触发碰撞类回调函数,如OnTriggerEnter
、OnColliderEnter
等,即使添加刚体组件也不行。CharacterController
使用OnControllerColliderHit
回调函数获取碰撞对象,(角色和碰撞对象都不需要添加刚体组件)。
CharacterController
组件适用于非真实风格的游戏,如角色可以从跑步状态瞬间切换为停止状态或角色可以实现瞬间转弯等,刚体方式更适用于真实风格的游戏。
3. 刚体移动
主要方法为Rigidbody.AddForce()
、MovePosition()
等。
示例:
void FixedUpdate()
{
float horizontal=Input.GetAxis("Horizontal");
float vertical=Input.GetAxis("Vertical");
Vector3 horizontalVelocity=mRigidbody.velocity;
horizontalVelocity.y=0;
mRigidbody.AddForce(new Vector3(horizontal,0,vertical)-horizontalVelocity,ForceMode.VelocityChange);
}
4. 通过NavMeshAgent
主要方法为NavMeshAgent.SetDestination()
等。
示例:
void Update()
{
float horizontal=Input.GetAxis("Horizontal");
float vertical=Input.GetAxis("Vertical");
meshAgent.SetDestination(transform.position+new Vector3(horizontal,0,vertical));
}