FPS(First-person Shooting game)第一人称视角射击游戏,想要进行比较合理的移动控制
这里简单实现一个简易方案
需求分析:
摄像机就在人物身后,人物在移动时保持直立(不随着坡度变化而变为斜着站立)
实现分析:
需要分别控制摄像机和人物
——1、人物方面:
FPS游戏的人物一般不显示在屏幕里,人物移动时,基于【局部坐标】进行移动,通过水平输入轴和垂直输入轴(wasd键)进行前后左右平移。
为实现完全操作,主角重力也完全由脚本控制。
主角朝向的时候,自身面向:
不能上下抬头(不能绕x旋转),
也不能歪头(不能绕z轴旋转),
=====只能允许左右摇头(绕y轴旋转)。
——2、摄像头方面:
摄像头高度要保证大约在人物头部;
鼠标移动的时候,要以此控制摄像头上下左右的旋转(绕x轴和y轴)
——3、其他
鼠标指针在操作时不能显示
实操:
1、提前挂载CharacterController组件(很方便的官方组件,操作主角)、Rigidbody组件(物理需要)
为了完全的脚本控制,需要取消勾选Use Gravity,并勾选Is Kinematic
2、脚本实例
using UnityEngine;
public class f_zanyongPlayer : MonoBehaviour
{
//自身组件
public Transform myTransform; //获取自身Transform
CharacterController myCharactor; // 获取角色控制器组件
//------------基础属性-----------
float speed = 3.0f; // 角色移动速度
float gravity = 2.0f; // 重力
public int m_life = 5; // 生命值
//-----------摄像机控制-----------
Transform camTransform; // 获取摄像机Transform
Vector3 camRotation; // 获取摄像机旋转角度
float m_camHeight = 1.4f; // 摄像机高度(主角身高)
void Start()
{
myTransform = this.transform;
myCharactor = this.GetComponent<CharacterController>();
//摄像机
camTransform = Camera.main.transform;
camTransform.position = myTransform.TransformPoint(0, m_camHeight, 0);
camTransform.rotation = myTransform.rotation;
camRotation = camTransform.eulerAngles;
//锁定鼠标
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
//等有需要显示鼠标的时候再分别调回true、CursorLockMode.None即可
}
void Update()
{
Control();
}
void Control()
{
//------镜头处理
//获取鼠标移动距离,并由此控制相机移动角度
float mouseHorizontal = Input.GetAxis("Mouse X");
float mouseVertical = Input.GetAxis("Mouse Y");
//还能添加1、角度控制;2、角速度*Time.deltaTime;
camRotation.x -= mouseVertical; //绕x轴抬头低头
camRotation.y += mouseHorizontal;//绕y轴左右摇头
camTransform.eulerAngles = camRotation;
//-----主角面向处理,要和摄像机保持一致
Vector3 camrot = camTransform.eulerAngles;
camrot.x = 0;
camrot.z = 0;
myTransform.eulerAngles = camrot;
//------主角移动
Vector3 motion = Vector3.zero; //移动方向
motion.x = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
motion.z = Input.GetAxis("Vertical") * speed * Time.deltaTime;
motion.y -= gravity * Time.deltaTime; //控制重力
myCharactor.Move(myTransform.TransformDirection(motion));
}
private void LateUpdate()
{
//高度设置为主角身高
camTransform.position = myTransform.TransformPoint(0, m_camHeight, 0);
}
}
小提示:
1、CharactController.Move(Vector3 motion),这里面的motion用的是【世界坐标】,而我们通过按键获取到的是【局部坐标】的相对移动。
需要先把【局部坐标】转为【世界坐标】,再传值给Move函数,否则移动会出现问题:
这里用了Transform.TransformDirection(motion)方法。
2、因为我担心摄像机出现运动抖动和不平滑的问题,避免摄像机在主角移动之前更新位置,特意把摄像机的移动放到LateUpdate。或许也可以不必这样做呢?
如果有考虑不周或者谬误,欢迎指正~