第一人称视角
程序每天就该有需要干的的事情
- 前言
FPS游戏的第一件事就是视角问题,所以我的第一步就是做一个第一人称控制器,将他封装起来,可以随时替换模型调整,做成prefab。
- 思路
相机的旋转
第一人称控制器就是控制相机在水平和竖直方向旋转,在人物移动的时候,可以用鼠标控制人物走动的方向,获取到Mouse X 和Mouse Y,这是Unity自己封装好的,自己也可以修改Edit -> projectSettings ->Input 中修改,在旋转中我用的时四原数旋转,避免产生万向锁。(想了解万向锁及四原数的小伙伴可以点击这里)
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
人物的移动
可以用Rigibody施加力使人物移动,或者是用CharacterControl 施加速度来使人物移动,我这里选择的是第二种,在第二种中方便调整人物在爬楼梯或者是跳高台的情况。
- 地面检测
地面检测用的是LayerMask,调用 Physics.CheckSphere 这个方法就可以获取一个球形的检测,在Scence场景中创建一个空的GameObject,修改名字为GroundCheck,我这里是拖在组件上的,你可以添加一个后缀,然后去寻找这个GameObject,这样可以降低错误的风险,我这里为了方便就直接拖了。
然后在Layer中添加Ground,给地面设置为Ground。
思路到这里基本上就差不多了,下面我放一下源码,可以参考一下,如果有写的不好的请指教
MouseLook.cs
using UnityEngine;
public class MouseLook : MonoBehaviour
{
[SerializeField]
private float mouseSensitity = 100f;
private float xRotation;
public Transform _playerBody;
private bool isClickESC;
void Start()
{
isClickESC = false;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
//没有按下ESC执行旋转,按下ESC鼠标光标不旋转
if (!isClickESC)
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitity * Time.deltaTime;
xRotation -= mouseY;
//限制视角上下的旋转
xRotation = Mathf.Clamp(xRotation, -60f, 60f);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
_playerBody.Rotate(Vector3.up * mouseX);
}
//这个是我后面讲的,可以不用理会
/*
if (Input.GetKeyDown(KeyCode.Escape))
{
isClickESC = true;
}
*/
}
}
Movement.cs
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class Movement : MonoBehaviour
{
[SerializeField]
private float moveSpeed = 20f;//行走时的速度
[SerializeField]
private float jumpHeight = 2f;//向上跳的最大高度
[SerializeField]
private float gravity = -9.8f;//重力
private CharacterController _characterController;
public Transform groundCheck;//碰撞检测
private float groundRadius = 0.5f;//球形碰撞检测的范围
[SerializeField]
private LayerMask groundMask;//层级
Vector3 velocity;//向上跳定义的矢量
bool isGround;
void Start()
{
_characterController = GetComponent<CharacterController>();
}
void Update()
{
isGround = Physics.CheckSphere(groundCheck.position, groundRadius,groundMask);
if (isGround && velocity.y < 0)
{
velocity.y = -2f;
}
float horMovement = Input.GetAxis("Horizontal");
float verMovement = Input.GetAxis("Vertical");
//保证可以同时在x和z方向上运动
Vector3 move = transform.right * horMovement + transform.forward * verMovement;
//调用character的move方法
_characterController.Move(move * moveSpeed * Time.deltaTime);
if (Input.GetButtonDown("Jump"))
{
//速度位移关系式:Vt平方 - V0平方 = -2gh;所有这里会这样写,因为用的是charactercontrol所以用速度位移。
velocity.y += Mathf.Sqrt(jumpHeight * -2f * gravity);
}
//v = gt;下落的时候
velocity.y += gravity * Time.deltaTime;
_characterController.Move(velocity * Time.deltaTime);
}
}
网盘链接:https://pan.baidu.com/s/18tD7OV6cRhMzvT2HymUAow
提取码:fjzd
我用的Unity2018.3.5,有什么问题可以留言或者在评论区,如果哪有错误欢迎指正。