CharacterController是unity中内置组件,使用需添加该组件
在CharacterController中,本文主要通过CharacterController中的move函数进行移动
整个脚本分为三个部分,视角旋转,水平移动,竖直移动
视角的旋转通过对鼠标的移动进行获取并处理得到
private void PlayerRotateViewControl()
{
transform.Rotate(Vector3.up * Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime);
}
首先我们通过定义一个基础向量MoveVector3;此值即为move函数的参数,水平和竖直方向的位移将加到该值中体现出来。
水平方向的代码
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
MoveVector3=(transform.forward*v+transform.right*h)*moveSpeed*Time.deltaTime;
在CharacterController中需要自行模拟重力的存在。
首先我们需要了解垂直方向的运动情况,分为两种
1、上升情况,且必须在isground情况下进行弹跳
2、下降情况
第一个问题便是人物是否踩在地面上,本文通过设置一个empty物体在脚底,并进行Physics.CheckSphere函数检测进行判断,但是这种方式有一点问题,即人物跳起了但是在某段时间内依旧为在地面上,影响了后续判断。而通过对垂直方向移动两种情况的分析,我们可以得出上升过程中不需要进行地面检测,便可获得一下代码,以下代码即使在踏空情况下依然能够进行。
if(Input.GetKeyUp(KeyCode.Space))
{
verticalVelocity = initalVerticalVelocity;
isGrounded = false;
isJumping = true;
}
if(!isGrounded&&verticalVelocity<0.1f)
{
isGrounded=Physics.CheckSphere(isGroundCheckPoint.position, checkRadius, groundMask);
isJumping=false;
}
if(isGrounded&&!isJumping) verticalVelocity = 0;
else
{
verticalVelocity-=gravity*Time.deltaTime;
}
MoveVector3 += verticalVelocity * transform.up*Time.deltaTime;
以下是完整代码
public class PlayerMovementController : MonoBehaviour
{
private CharacterController characterController;
//旋转
public float rotateSpeed = 120;
//移动
public float moveSpeed = 3;
private Vector3 MoveVector3;
//跳跃
public float gravity = 9.8f;
public float verticalVelocity = 0;
public float maxJumpHeight = 1.7f;
public bool isJumping = false;
private float initalVerticalVelocity;
//地面检测
public Transform isGroundCheckPoint;
private float checkRadius = 0.1f;
public LayerMask groundMask;
public bool isGrounded;
private void Awake()
{
characterController = GetComponent<CharacterController>();
}
private void Start()
{
isGroundCheckPoint = transform.Find("IsGroundCheckPoint");
isGrounded = Physics.CheckSphere(isGroundCheckPoint.position, checkRadius, groundMask);
//通过2gh=v*v这个公式可以求得多少起始速度可以获得固定跳跃高度
initalVerticalVelocity = Mathf.Sqrt(2 * gravity * maxJumpHeight);
}
private void Update()
{
PlayerRotateViewControl();
PlayerMoveController();
}
private void PlayerRotateViewControl()
{
transform.Rotate(Vector3.up * Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime);
}
private void PlayerMoveController()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
MoveVector3=(transform.forward*v+transform.right*h)*moveSpeed*Time.deltaTime;
//我的跳跃写法
//首先在start中获取isground的值(防止出现踩空但是判定在地面上的情况)
//对于人物的垂直方向的速度,分为两种情况
//1.跳跃情况会给予一个向上的速度然后不断递减直至为0然后转为负数坠落
//2.踩空直接坠落
//对于以上两种情况,只需要在速度减到0时再进行isground的判断即可
if(Input.GetKeyUp(KeyCode.Space))
{
//给予初始速度
verticalVelocity = initalVerticalVelocity;
//修改判定,开始跳跃过程
isGrounded = false;
isJumping = true;
}
//仅在非地面且速度小于0.1时进行地面判断,有效减少检测区间
if(!isGrounded&&verticalVelocity<0.1f)
{
isGrounded=Physics.CheckSphere(isGroundCheckPoint.position, checkRadius, groundMask);
isJumping=false;
}
//当处于地面时速度设为0,即不再进行垂直方向运动
if(isGrounded&&!isJumping) verticalVelocity = 0;
else
{
//不管是什么情况,只要player在空中,便给予一个重力
verticalVelocity-=gravity*Time.deltaTime;
}
MoveVector3 += verticalVelocity * transform.up*Time.deltaTime;
characterController.Move(MoveVector3);
}
}
附上小白求职