Unity旋转之四元数(开关车门,第一人称控制器)

在Unity中,常用的旋转方式有三种,分别是transform.Rotate(参数),欧拉角旋转,和今天我们要聊的四元数。虽然四元数理解起来不如欧拉角那么直观,但是它却能很好的避免了万向锁问题,而且在限制旋转角度方面也是一把好手,同时,四元数自带球面线性插值(Slerp)。

一,使用四元数Slerp控制开关车门

1.创建车门,大概如下图所示:

2.创建一个脚本,直接挂在车门上,代码如下:

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

public class Test : MonoBehaviour
{
    /// <summary>
    /// 初始的旋转状态
    /// </summary>
    private Quaternion InitialRotation;
    /// <summary>
    /// 打开后的旋转状态
    /// </summary>
    private Quaternion OpenRotation;
    /// <summary>
    /// 门的当前状态
    /// </summary>
    private bool DoorCurrentState;


    void Start()
    {
        InitialRotation = transform.localRotation;
        OpenRotation = Quaternion.Euler(transform.localEulerAngles.x, transform.localEulerAngles.y, transform.localEulerAngles.z - 90f);
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.Alpha1))
        {
            float result = Quaternion.Dot(transform.localRotation, OpenRotation);

            if (result != 1 && result != -1)
            {
                transform.localRotation = Quaternion.Slerp(transform.localRotation, OpenRotation, 0.2f);
            }
            else
            {
                Debug.Log("完成开门");
                DoorCurrentState = true;

            }
        }
        if (Input.GetKey(KeyCode.Alpha2))
        {
            float result = Quaternion.Dot(transform.localRotation, InitialRotation);
            if (result != 1 && result != -1)
            {
                transform.localRotation = Quaternion.Slerp(transform.localRotation, InitialRotation, 0.2f);
            }
            else
            {
                Debug.Log("完成关门");
                DoorCurrentState = false;
            }
        }
    }
}

二,使用四元数制作简易的第一人称控制器

1.创建一个Cube并将主置为他的子物体,并将所有的旋转置零,如下图

 2.创建控制移动的脚本并拖到Cube上,代码如下:

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


public class FirstPersonMove : MonoBehaviour
{
    private float MoveSpeed = 8;
    private void FixedUpdate()
    {
        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");
        if (x != 0 || y != 0)
        {
            transform.Translate(Vector3.right * x * Time.deltaTime * MoveSpeed);
            transform.Translate(Vector3.forward * y * Time.deltaTime * MoveSpeed);
        }
    }

}

3.这样我们就能通过WASD键来控制Cube移动了,剩下的就是控制相机的旋转了,代码如下:

using UnityEngine;

public class FirstPersonLook : MonoBehaviour
{
    public float sensitivity = 2;
    public float smoothing = 1.5f;
    Vector2 velocity;
    Vector2 frameVelocity;
    private void FixedUpdate()
    {
        Vector2 mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
        Vector2 rawFrameVelocity = Vector2.Scale(mouseDelta, Vector2.one * sensitivity);
        frameVelocity = Vector2.Lerp(frameVelocity, rawFrameVelocity, 1 / smoothing);
        velocity += frameVelocity;
        velocity.y = Mathf.Clamp(velocity.y, -120, 90);

        transform.localRotation = Quaternion.AngleAxis(-velocity.y, Vector3.right);

        transform.parent.localRotation = Quaternion.AngleAxis(velocity.x, Vector3.up);
    }
}

该代码分为三部分,第一部分是为了获得一个平滑的velocoty,第二部分是控制相机的视角的上下移动,第三部分则是控制Cube的左右旋转,由于主相机是Cube的子物体,所以Cube左右旋转相对而言,我们看到的就是主相机视角的左右移动。

至此,一个简易的第一人称控制器就完成了(别忘了给Cube添加个刚体和摩檫力,否则不能上下坡了)。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值