使用Rigbody&Capsule Collider制作FPS角色控制器
1.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);//更新相机的旋转角度
}
1.2玩家移动的脚本
给玩家即(新建的空物体)添加此脚本,目前玩家的移动朝向不可跟随相机方向的旋转移动,锁定X,Z轴.
新建【FPMovement】脚本
public class FPMovement : MonoBehaviour
{
private Transform myTransform;
public float speed;
private Rigidbody myRigbody;
void Start()
{
myTransform = transform;
myRigbody = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
var h = Input.GetAxis("Horizontal");
var v = Input.GetAxis("Vertical");
var currentDirection= new Vector3(h, 0, v);
//从自身坐标转为世界坐标
currentDirection = myTransform.TransformDirection(currentDirection);
currentDirection *= speed;//当前方向乘以速度
var currentVelocity = myRigbody.velocity;//获取当前的速度
var velocityChange = currentDirection - currentVelocity;//得出需要以多少的速度进行行走
velocityChange.y = 0;//不需要计算y轴的数值
myRigbody.AddForce(velocityChange, ForceMode.VelocityChange);//添加力到刚体,让它随之移动
}
1.3 玩家随相机旋转方向移动
修改【FPMouseLook】脚本
public class FPMouseLook : MonoBehaviour
{
private Transform cameraTransform;
[SerializeField] private Transform characterTransform;//记录玩家的位置,序列化到检视视图上或者使用public修饰
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);//更新相机的旋转角度
characterTransform.rotation = Quaternion.Euler(0, cameraRotation.y, 0);//只需改变玩家旋转角度的Y值
}
}
至此可以进行第一人称正常移动
1.4 控制玩家才地面才可移动,实现玩家跳跃的功能
修改【FPMovement】脚本
public class FPMovement : MonoBehaviour
{
private Transform myTransform;
public float speed;
public float gravity;//定义一个重力,自己赋值
public float jumpHeight;//定义跳跃的高度
private Rigidbody myRigbody;
private bool isGrounded;//判断是否玩家触地
void Start()
{
myTransform = transform;
myRigbody = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
if (isGrounded)
{
var h = Input.GetAxis("Horizontal");
var v = Input.GetAxis("Vertical");
var currentDirection = new Vector3(h, 0, v);
//从自身坐标转为世界坐标
currentDirection = myTransform.TransformDirection(currentDirection);
currentDirection *= speed;//当前方向乘以速度
var currentVelocity = myRigbody.velocity;//获取当前的速度
var velocityChange = currentDirection - currentVelocity;//得出需要以多少的速度进行行走
velocityChange.y = 0;//不需要计算y轴的数值
myRigbody.AddForce(velocityChange, ForceMode.VelocityChange);//添加力到刚体,让它随之移动
if (Input.GetButtonDown("Jump"))//判断是否摁下跳跃键
{
myRigbody.velocity = new Vector3(currentVelocity.x, JumpHeightSpeed(), currentVelocity.z);//跳跃,玩家坐标的x与z轴均使用自身坐标,y轴为自己写的方法
}
}
myRigbody.AddForce(new Vector3(0, -gravity * myRigbody.mass, 0));//如果未触地,则下坠
}
private float JumpHeightSpeed()//返回平方根,其数值作为玩家跳跃的y轴的值
{
return Mathf.Sqrt(2 * gravity * jumpHeight);
}
private void OnCollisionStay(Collision collision)
{
isGrounded = true;
}
private void OnCollisionExit(Collision collision)
{
isGrounded = false;
}
}