使用CharacterController组件制作Fps角色控制器
2.1鼠标控制视角在X,Y轴旋转
新建FPMouseLook脚本
private Transform cameraTransform;
private Vector3 cameraRotation; //保存每一帧存储下的坐标信息
public float mouseSesitivity;//修改鼠标灵敏度
public Vector2 maxMinAngle;//限制垂直视角区域
void Start()
{
cameraTransform = transform;
}
void Update()
{
var mouseX = Input.GetAxis("Mouse X");//将鼠标输入的X值赋予mouseX
var mouseY = Input.GetAxis("Mouse Y"); //将鼠标输入的Y值赋予mouseY
cameraRotation.y += mouseX * mouseSesitivity;//Y轴想要旋转需要在X轴移动
cameraRotation.x -= mouseY * mouseSesitivity;//X轴想要旋转需要在Y轴移动
cameraRotation.x = Mathf.Clamp(cameraRotation.x, maxMinAngle.x, maxMinAngle.y);//cameraRotation.x的值控制在maxMinAngle.x和maxMinAngle.y两个值之间
cameraTransform.rotation = Quaternion.Euler(cameraRotation.x, cameraRotation.y, 0);//更新相机的旋转角度
2.2通过控制CharacterController组件,进行移动,跳跃
新建FPCharacterControllerMovement脚本


public class FPCharacterControllerMovement : MonoBehaviour
{
private CharacterController characterController; //玩家身上的CharacterController组件
private Transform characterTransform;//玩家位置信息
private Vector3 movementDirection;
public float movementSpeed;//移动速度
public float gravity = 9.8f;//重力
public float jumpHeight;//角色跳跃高度
void Start()
{
characterController = GetComponent<CharacterController>();//获取组件
characterTransform = transform;//获取玩家坐标信息
}
void Update()
{
if (characterController.isGrounded)//CharacterController的isGrounded函数,判断玩家是否处于地面,如果玩家不处于运动状态则不能更改isGrounded的值
{
var horizontal = Input.GetAxis("Horizontal");
var vertical = Input.GetAxis("Vertical");
movementDirection = characterTransform.TransformDirection(new Vector3(horizontal, 0, vertical));//移动的方向
if (Input.GetButtonDown("Jump"))//当摁下跳跃键,改变玩家的y轴
{
movementDirection.y = jumpHeight;
}
}
movementDirection.y -= gravity * Time.deltaTime;
characterController.Move(movementSpeed * Time.deltaTime * movementDirection);//以自定速度向指定方向移动,不具备重力
}
}
2.3完成下蹲,奔跑,行走功能
这里用到了三目运算Input.GetKey(KeyCode.LeftShift) ? runSpeed : walkSpeed;
“?后的是满足前面条件时,:后是不满足时。”
相当于if(KeyCode.LeftShift){runSpeed}else{walkSpeed}
下蹲主要修改玩家身上的Character Controller组件中的Height变量
实现下蹲功能,下蹲行走和奔跑速度的切换。判断是否下蹲,是的话再分别修改其行走和奔跑的速度。
修改FPCharacterControllerMovement脚本
public class FPCharacterControllerMovement : MonoBehaviour
{
private CharacterController characterController; //玩家身上的CharacterController组件
private Transform characterTransform;//玩家位置信息
private Vector3 movementDirection;
public float runSpeed;//奔跑速度
public float walkSpeed;//行走速度
public float gravity = 9.8f;//重力
public float jumpHeight;//角色跳跃高度
public float crouchHeight;//下蹲的高度
private float oldHeight;//原来高度
public bool isCrouched;//判断是否蹲下
public float crouchRunSpeed;//下蹲奔跑速度
public float crouchwalkSpeed;//下蹲行走速度
void Start()
{
characterController = GetComponent<CharacterController>();//获取组件
characterTransform = transform;//获取玩家坐标信息
oldHeight = characterController.height;//获取原来高度
}
void Update()
{
float currentSpeed = walkSpeed;//声明一个临时变量存储当前速度
if (characterController.isGrounded)//CharacterController的isGrounded函数,判断玩家是否处于地面,如果玩家不处于运动状态则不能更改isGrounded的值
{
var horizontal = Input.GetAxis("Horizontal");
var vertical = Input.GetAxis("Vertical");
movementDirection = characterTransform.TransformDirection(new Vector3(horizontal, 0, vertical));//移动的方向
if (Input.GetButtonDown("Jump"))//当摁下跳跃键,改变玩家的y轴
{
movementDirection.y = jumpHeight;
}
if (Input.GetKeyDown(KeyCode.C))
{
//判断是否蹲下,如果蹲下返回站立高度,如果目前是站立返回下蹲高度,将高度传入协程函数的参数中
var currentHight = isCrouched ? oldHeight : crouchHeight;
StartCoroutine(DoCrouch(currentHight));//使用协程函数
isCrouched = !isCrouched;//将下蹲状态重置为对立状态
}
if (isCrouched)//
{
//三目运算符,判断下蹲状态是否摁下LeftShift,是的话执行crouchRunSpeed,否crouchwalkSpeed,赋值给当前速度
currentSpeed = Input.GetKey(KeyCode.LeftShift) ? crouchRunSpeed : crouchwalkSpeed;
}
else
{
//三目运算符,判断是否摁下LeftShift,是的话执行runSpeed,否walkSpeed,赋值给当前速度
currentSpeed = Input.GetKey(KeyCode.LeftShift) ? runSpeed : walkSpeed;
}
}
movementDirection.y -= gravity * Time.deltaTime;//重力下落
characterController.Move(currentSpeed * Time.deltaTime * movementDirection);//以自定速度向指定方向移动,不具备重力
}
private IEnumerator DoCrouch(float target)//进行蹲起高度渐变修改的协程函数
{
while (Mathf.Abs(characterController.height - target) > 0.1f)//当当前角色高度减去1的时候大于0.1执行此代码
{
float currentHeight = 0;//定义一个高度返回值
yield return null;//要记得返回下 不然协程会卡掉
characterController.height =
Mathf.SmoothDamp(characterController.height, target,
ref currentHeight, Time.deltaTime * 5);//渐渐过度效果
}
}
}
