Unity技术笔记:FPS游戏简易移动控制方案

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。或许也可以不必这样做呢?

如果有考虑不周或者谬误,欢迎指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值