【unity】游戏的第一人称编写,限制角色视野范围,unity的Rotate使用情况区分一次搞懂

刚开始学习unity的时候很容易对众多的API搞糊涂,特别是博客里很多博主的写作思路十分混乱,完全不能看懂,看了书之后感觉清晰了很多,总结一下。

如果你还分不清世界坐标系和Self坐标系,建议先去看下基础,

基础的unity入门 先推荐一个博主,讲得深入浅出,很清晰详细:Unity基础:非常基础的Unity入门

先放第一人称视角实现的整体的代码,
绑定脚本在作用物体上:
【unity】游戏的第一人称编写,限制角色视野范围,unity的Rotate使用情况区分一次搞懂_第1张图片

实现效果:

(虽然希望录多一点,但是由于图片大小限制,只能这样,,,)可以在Scene里看到,没有限制四周的方向,限制了上下的视野。

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

public class MouseLook : MonoBehaviour
{
    //注意枚举的使用,可以用名称设置值,而不是用魔术数字,这样有利于代码的理解和阅读,是良好的习惯
    public enum RotationAxes
    {
        MouseXAndY = 0,
        MouseX = 1,
        MouseY = 2
    }

    public float sensitivityHor = 9.0f;//水平旋转速度
    public float sensitivityVert = 9.0f; //垂直旋转速度,灵敏度

    public float minimumVert = -45.0f;
    public float maximumVert = 45.0f;

    private float _rotationX = 0;//为垂直角度声明一个变量

    public RotationAxes axes = RotationAxes.MouseXAndY; //使得变量暴露在组件里,可以在Unity里可视化更改
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(axes == RotationAxes.MouseX)
        {
            transform.Rotate(0,Input.GetAxis("Mouse X") * sensitivityHor, 0);
            //水平旋转,所以固定了z轴,绕着z轴在四周旋转。
        }
        else if (axes == RotationAxes.MouseY)
        {   //垂直方向旋转的代码
            _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert; //基于鼠标增加垂直角度
            _rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert); //限制上下看的范围

            float rotationY = transform.localEulerAngles.y;//保持y的角度
            transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0); //使用新的值存储固定了的旋转前的水平旋转信息并增加上下方向旋转的移动
            
        }
        else
        {
            // 同时可以水平和垂直方向的旋转
            _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
            _rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);

            float delta = Input.GetAxis("Mouse X") * sensitivityHor; //delta是旋转的变化量,一般数学上也会把变化量协作delta
            float rotationY = transform.localEulerAngles.y+ delta;
            transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
        }
    }
}

第一人称视角的编写,也就是所谓的MouseLook(视野跟着鼠标的方向移动)首先要理清旋转的概念。
例如:下面这个略倾斜的立方体(略倾斜是为了使得世界World坐标系和自身sELF坐标系不一样)
【unity】游戏的第一人称编写,限制角色视野范围,unity的Rotate使用情况区分一次搞懂_第2张图片【unity】游戏的第一人称编写,限制角色视野范围,unity的Rotate使用情况区分一次搞懂_第3张图片

transform.Rotate(speed, 0, 0,Space.Self);
transform.Rotate(speed, 0, 0,Space.World);

1.沿着World坐标旋转时,是沿着世界坐标系(右上角的那个坐标)在旋转,整体的旋转方向垂直于屏幕
【unity】游戏的第一人称编写,限制角色视野范围,unity的Rotate使用情况区分一次搞懂_第4张图片
2,沿着Self坐标旋转时,可以看出,是沿着自身的x轴在旋转,红色的轴没有变动,
【unity】游戏的第一人称编写,限制角色视野范围,unity的Rotate使用情况区分一次搞懂_第5张图片

Rotate的含义和使用情况:

Rotate()的实际含义是 ”增加当前的旋转“,由于在水平方向的旋转我们的确需要增加就行了,所以可以用Rotate,
而我们的垂直方向的旋转需要限制旋转的范围,
所以,显然Rotate就不合适了,因为即使限制了旋转的增加的幅度,,也会导致角度的增加,

这样会发生什么呢?(思考)

会导致莫名奇妙的翻车

所以受限制的垂直方向上的旋转需要使用其他的方法”——写死增加的值,固定住需要旋转的角度的幅度。

Rotate可以理解为增加transform.localEulerAngles可以理解为设置角度为XX度。

1.利用Input.GetAxis("Mouse Y")来获取在垂直方向上的鼠标的位移,乘上一个灵敏度,免得过度灵敏,
得到的这个角度只是一个固定值,但是还没有和原有角度组合应用,所以需要将过去的值减去变化值 --->当前值

private float _rotationX = 0;//为垂直角度声明一个变量
 _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert; //基于鼠标增加垂直角度
 
 _rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert); //限制上下看的范围,Math.Clamp限制了取值范围,防止了过度旋转,

2.然后获取当前的y轴的角度,因为在进行受限制的垂直视角变换时,其实水平方向上是不变的,所以需要写死增加的值,固定住需要旋转的角度的幅度的时候,水平角度固定住。

float rotationY = transform.localEulerAngles.y;//获取y的角度
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0); //使用新的值存储固定了的旋转前的水平旋转信息并增加上下方向旋转的移动

3.最后,结合水平方向上无限制和垂直方向上受到限制的控制和变化,
利用 transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);来自己定义角度变化,
注意,由于垂直角度被限制了,导致了水平旋转也不能用Rotate去增加了(因为最后都必须用transform.localEulerAngles来进行设置),所以只能老实地求值了。

// 同时可以水平和垂直方向的旋转
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);

float delta = Input.GetAxis("Mouse X") * sensitivityHor; //delta是旋转的变化量,一般数学上也会把变化量协作delta
float rotationY = transform.localEulerAngles.y+ delta;
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);

注意的一些:

1.我们需要创建新的Vector3, 而不是修改Transform已经存在的值,因为transform里的值是只读的,这是常犯的错误。
2.记住。Rotate是增加角度!!
3.对玩家进行禁止物理旋转: 当玩家是刚体,和其他碰撞体进行接触时,轻微的碰撞也会导致玩家被反弹,跌倒等等,这种碰撞的行为显然不符合预期(我们假设人是柔软的),
所以我们需要加入:

   void Start()
    {
        //.....其他代码
        Rigidbody body = GetComponent<Rigidbody>();
        if(body!= null)
        {
            body.freezeRotation = true; //设置物理旋转无效。
        }
        //...其他代码
    }

你可能感兴趣的:(unity,游戏制作,unity,游戏)