Unity之四元数计算

发布时间:2024年01月19日

四元数相乘

#region 四元数相乘
Quaternion q = Quaternion.AngleAxis(20, Vector3.up);
this.transform.rotation *= q;
#endregion

四元数乘向量

Vector3 v = Vector3.forward;
print(v);
//四元数乘向量的顺序不能改变,也就是说不能用向量去乘四元数,只能是四元数乘向量
v = Quaternion.AngleAxis(45,Vector3.up) * v;
print(v);
v = Quaternion.AngleAxis(45, Vector3.up) * v;
print(v);

例一

模拟飞机发射不同类型子弹的方法,单发,双发,扇形,环形

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


public enum E_FireType
{
    One,
    Two,
    Three,
    Round
}
public class AirPlane : MonoBehaviour
{
    private E_FireType nowType;
    public GameObject bullet;
    public int roundNum = 4;
    // Start is called before the first frame update
    void Start()
    {
        nowType = E_FireType.One;
    }

    // Update is called once per frame
    void Update()
    {
        //切换开火方式
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            nowType = E_FireType.One;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            nowType = E_FireType.Two;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            nowType = E_FireType.Three;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            nowType = E_FireType.Round;
        }

        if(Input.GetKeyDown(KeyCode.Space))
        {
            Fire();
        }
        
    }

    private void Fire()
    {
        switch (nowType)
        {
            case E_FireType.One:
                Instantiate(bullet,transform.position,transform.rotation);
                break;
            case E_FireType.Two:
                //让发射位置分别向两边的方向偏移一点
                Instantiate(bullet, transform.position - transform.right * 1, transform.rotation);
                Instantiate(bullet, transform.position + transform.right * 1, transform.rotation);
                break;
            case E_FireType.Three:
                Instantiate(bullet, transform.position, transform.rotation);
                Instantiate(bullet, transform.position - transform.right * 1, transform.rotation * Quaternion.AngleAxis(-20, Vector3.up));
                Instantiate(bullet, transform.position + transform.right * 1, transform.rotation * Quaternion.AngleAxis(20, Vector3.up));
                break;
            case E_FireType.Round:
                float angle = 360/roundNum;
                for(int i = 0; i < roundNum; i++)
                {
                    Instantiate(bullet, this.transform.position, this.transform.rotation * Quaternion.AngleAxis(i * angle, Vector3.up));
                }

                break;
        }
    }
}

练习二

用3D数学知识实现摄像机跟随效果

1.摄像机在人物斜后方,通过角度控制倾斜率

2.通过鼠标滚轮控制摄像机距离人物的距离(有最大最小限制)

3.摄像机看向任务头顶上方的一个位置(可调节)

4.Vector3.Lerp实现相机跟随任务

5.Quaternion.Slerp实现摄像机看向人物

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

public class CameraMove2 : MonoBehaviour
{
    //目标对象
    public Transform target;
    //相对头顶偏移多少
    public float headOffsetH = 1;
    //倾斜角度
    public float angle = 45;
    //默认的摄像机里观测点的距离
    public float dis = 5;
    //距离必须是3和10之间 
    public float minDis = 3;
    public float maxDis = 10;

    //当前摄像机应该在的位置
    private Vector3 nowPos;
    private Vector3 nowDir;
    private float time;
    private Vector3 startPos;
    private Vector3 endPos;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //鼠标中键滚动控制摄像机远近的逻辑
        dis += Input.GetAxis("Mouse ScrollWheel");
        dis = Mathf.Clamp(dis, minDis, maxDis);

        //向头顶偏移位置
        nowPos = target.position + target.up * headOffsetH;
        //往后方偏移位置 
        nowDir = Quaternion.AngleAxis(angle, target.right) * -target.forward;
        nowPos = nowPos + nowDir * dis;
        //直接把算出来的位置赋值
        if(endPos != nowPos) 
        { 
            startPos = this.transform.position;
            endPos = nowPos;
            time = 0;
        }
        time += Time.deltaTime;
        //this.transform.position = nowPos;
        //先快后慢
        //this.transform.position = Vector3.Lerp(this.transform.position,nowPos,Time.deltaTime*dis);
        //匀速
        this.transform.position = Vector3.Lerp(startPos, endPos, time);

        Quaternion.LookRotation(nowDir);
        this.transform.rotation = Quaternion.Slerp(this.transform.rotation, Quaternion.LookRotation(-nowDir),Time.deltaTime);
        
    }
}

文章来源:https://blog.csdn.net/lqd201314/article/details/135680369
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。