CharacterController是一个基础的角色控制组件,通过它我们可以实现包括移动、奔跑、跳跃、爬楼梯和爬斜坡等基本的角色操作。它主要用于不基于刚体物理的第一人称或第三人称的角色控制。
注意事项:
1.Move 方法是基于世界坐标系的,并且没有重力支持;
2.SimpleMove方法也是基于世界坐标系的,有重力支持(重力为游戏项目的全局重力值,在Editor-Project Settings-Physics-Gravity设置);
3.跳跃应该采用Move方法;
4.isGrounded是基于射线检测的,并与Skin Width和Min Move Distance参数有关。例如对于标准的胶囊碰撞器而言,相当于以碰撞器的最下方的中心点作为射线发射的起始点,射线方向竖直向下,射线距离则为最下方中心点到Skin的竖直距离,当你觉得isGrounded的判断不精确时可以尝试调节Skin Width和Min Move Distance参数。官方建议Skin Width保持为Radius参数的10%,而Min Move Distance为0;
5.对于穿透、卡住、碰撞抖动等问题可以通过适当增大Skin Width的方式来解决。
总结自官方英文文档
脚本示例:
using UnityEngine; [RequireComponent(typeof(CharacterController))] public class Player : MonoBehaviour { [Header("必要属性")] [Tooltip("角色转向速度")] public float TurnSpeed = 100; [Tooltip("角色移动速度")] public float MoveSpeed = 13; [Tooltip("角色跳跃高度")] public float JumpHeight = 2.5f; [Tooltip("重力加速度值")] public float GravityValue = -9.81f; private CharacterController cc; private Vector3 playerVelocity; private void Start() { cc = GetComponent<CharacterController>(); } private void Update() { Movement(); Jump(); } // 角色转向 private void Turn(float hor) { Vector3 euler = transform.localRotation.eulerAngles; float yRotation = euler.y + hor * TurnSpeed * Time.deltaTime; transform.localRotation = Quaternion.Euler(euler.x, yRotation, euler.z); } // 基于CharacterController的Move方法 // private void Movement() // { // float hor = Input.GetAxisRaw("Horizontal"); // float ver = Input.GetAxisRaw("Vertical"); // if (hor != 0) Turn(hor); // Vector3 direction = transform.TransformDirection(Vector3.forward * ver); // cc.Move(direction * Time.deltaTime * MoveSpeed); // } // 基于CharacterController的SimpleMove方法 private void Movement() { float hor = Input.GetAxisRaw("Horizontal"); float ver = Input.GetAxisRaw("Vertical"); if (hor != 0) Turn(hor); Vector3 direction = transform.TransformDirection(Vector3.forward * ver); cc.SimpleMove(direction * MoveSpeed); } // 角色跳跃 private void Jump() { if (cc.isGrounded) { if (playerVelocity.y < 0) playerVelocity.y = 0; if (Input.GetButtonDown("Jump")) { playerVelocity.y += Mathf.Sqrt(JumpHeight * -3.0f * GravityValue); } } playerVelocity.y += GravityValue * Time.deltaTime; cc.Move(playerVelocity * Time.deltaTime); } }
如果这篇文章对你有帮助,请给作者点个赞吧!