Unity3d第一人称移动及旋转

实现第一人称移动之前,我是将摄像机作为主角(游戏物体)的子物体,并设置好了合适的位置及高度。

1:第一人称移动

移动主要是通过position累加改变实现


    //第一人称移动
    public void Move()
    {
        float x = Input.GetAxis("Horizontal");  //输入水平,左右
        float z = Input.GetAxis("Vertical");    //输入纵向,前后

        Vector3 fwd = transform.forward;
        Vector3 f = new Vector3(fwd.x, 0, fwd.z).normalized;

        Vector3 r = transform.right;
        Vector3 move = f * z + r * x;

        transform.position += move *  20.0f * Time.deltaTime;
    }

2:第一人称旋转

    //第一人称旋转
    public void MouseLook()
    {
        float mx = Input.GetAxis("Mouse X");
        float my = -Input.GetAxis("Mouse Y");
        Quaternion qx = Quaternion.Euler(0, mx, 0);
        Quaternion qy = Quaternion.Euler(my, 0, 0);
        /*
         镜头水平旋转实际上是沿世界坐标系的y轴旋转,而镜头俯仰旋转则是围绕角色的局部坐标系的x轴旋转
        注意四元数乘以向量时,必须四元数在前,向量在后——世界坐标系.
        四元数相乘不符合交换律,相乘顺序不同会影响结果
        通过交换四元数相乘的顺序,可以让物体沿不同坐标系的坐标轴进行旋转。
         */
        transform.rotation = qx * transform.rotation;   //世界坐标系旋转
        transform.rotation = transform.rotation * qy;   //局部坐标系旋转

        float angle = transform.eulerAngles.x;
        /*
        用四元数表示的旋转角度是唯一的,但转成欧拉角就不唯一了,导致有时候是-1°,有时候又突然变成359°。
        如果angle是359°,那么后续判断就全乱套了。
        解决方案就是通过巧妙的方式判断angle的范围,如果超出-180~180,
        就要加上或减去一个周期(360°),以控制angle的取值范围。
         */
        if (angle > 180) angle -= 360;
        if (angle < -180) angle += 360;

        if (angle >80)
        {
            transform.eulerAngles = new Vector3(80, transform.eulerAngles.y, 0);
        }
        if (angle <-80)
        {
            transform.eulerAngles = new Vector3(-80, transform.eulerAngles.y, 0);
        }


    }


3:完整代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FPSCharacter : MonoBehaviour
{

    void Start()
    {
        //隐藏鼠标
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
    }

   
    void Update()
    {
        Move();
        MouseLook();
    }

    public void Move()
    {
        float x = Input.GetAxis("Horizontal");  //输入水平,左右
        float z = Input.GetAxis("Vertical");    //输入纵向,前后

        Vector3 fwd = transform.forward;
        Vector3 f = new Vector3(fwd.x, 0, fwd.z).normalized;

        Vector3 r = transform.right;
        Vector3 move = f * z + r * x;

        transform.position += move *  20.0f * Time.deltaTime;
    }

    public void MouseLook()
    {
        float mx = Input.GetAxis("Mouse X");
        float my = -Input.GetAxis("Mouse Y");
        Quaternion qx = Quaternion.Euler(0, mx, 0);
        Quaternion qy = Quaternion.Euler(my, 0, 0);
        /*
         镜头水平旋转实际上是沿世界坐标系的y轴旋转,而镜头俯仰旋转则是围绕角色的局部坐标系的x轴旋转
        注意四元数乘以向量时,必须四元数在前,向量在后——世界坐标系.
        四元数相乘不符合交换律,相乘顺序不同会影响结果
        通过交换四元数相乘的顺序,可以让物体沿不同坐标系的坐标轴进行旋转。
         */
        transform.rotation = qx * transform.rotation;   //世界坐标系旋转
        transform.rotation = transform.rotation * qy;   //局部坐标系旋转

        float angle = transform.eulerAngles.x;
        /*
        用四元数表示的旋转角度是唯一的,但转成欧拉角就不唯一了,导致有时候是-1°,有时候又突然变成359°。
        如果angle是359°,那么后续判断就全乱套了。
        解决方案就是通过巧妙的方式判断angle的范围,如果超出-180~180,
        就要加上或减去一个周期(360°),以控制angle的取值范围。
         */
        if (angle > 180) angle -= 360;
        if (angle < -180) angle += 360;

        if (angle >80)
        {
            transform.eulerAngles = new Vector3(80, transform.eulerAngles.y, 0);
        }
        if (angle <-80)
        {
            transform.eulerAngles = new Vector3(-80, transform.eulerAngles.y, 0);
        }


    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值