3d 数学(叉乘、四元素、四元素旋转、四元素和四元素相乘、鼠标控制物体旋转、发射子弹、环形发射子弹、子弹缓冲池)

目录

1、叉乘

 2、四元素

3、四元素旋转

 4、四元素和四元素相乘

5、鼠标控制物体旋转

6、发射子弹

7、环形发射子弹

 8、子弹缓冲池


 

1、叉乘

两个向量叉乘,得到一个新的向量,新向量跟原始两个向量都垂直,也就是得到由两个向量所确定平面的法向量。

a(x, y , z)    b(i , j , k)

a  *  b   =    (y * k  -  z * j  ,   x * k -  z  *  i  ,  x * j - y * i)

public class CrossTest : MonoBehaviour
{
    public GameObject cube;
    public GameObject sphere;

    void Update()
    {
        Vector3 v = sphere.transform.position - cube.transform.position;
        Vector3 cross = Vector3.Cross(cube.transform.forward, v);

        Debug.DrawLine(cube.transform.position, cube.transform.forward * 10, Color.blue);
        Debug.DrawLine(cube.transform.position, sphere.transform.position , Color.red);

        Debug.DrawRay(cube.transform.position, cross, Color.green);
        if (cross.y > 0)
        {
            Debug.Log("在右边");
        }
        else
        {
            Debug.Log("在左边");
        }
    }
}

3240d0aecfe84858b70a1cfd7060cf2d.png

 1ff4f55118b04cc29634189fcb117124.png

 2、四元素

万向节死锁  <x,y,z>gif.latex?%7B%5Ccolor%7BBlue%7D%20%5Ctheta%20%7D

实数:分为有理数和无理数

虚数:i ^ 2 = -1

复数:实数 + 虚数

超复数:(x,y,z,w)

        X = n * x * sin(gif.latex?%7B%5Ccolor%7BBlue%7D%20%5Ctheta%20%7D/2)

        Y = n * y * sin(gif.latex?%7B%5Ccolor%7BBlue%7D%20%5Ctheta%20%7D/2)

        Z = n * z * sin(gif.latex?%7B%5Ccolor%7BBlue%7D%20%5Ctheta%20%7D/2)

        W = cos(gif.latex?%7B%5Ccolor%7BBlue%7D%20%5Ctheta%20%7D/ 2)

public class QuaternionTest : MonoBehaviour
{
    public GameObject cube;
    void Start()
    {
        cube.transform.rotation = new Quaternion(0, 0, Mathf.Sin(30 * Mathf.Deg2Rad),
            Mathf.Cos(30 * Mathf.Deg2Rad));//cube绕z轴旋转60度

        Quaternion q1 = Quaternion.Euler(0, 30, 0);
        cube.transform.rotation = q1;//cube绕y轴旋转30度

        Quaternion q2 = Quaternion.Euler(new Vector3(0, 30, 0));
        cube.transform.rotation = q2;

        Quaternion q3 = Quaternion.AngleAxis(30, Vector3.forward);
        cube.transform.rotation = q3;

    }

}

3、四元素旋转

1)、cube位置rest,cube 从沿y轴从0度到60度旋转(Lerp(差值))

public class QuaternionRotate : MonoBehaviour
{
    public GameObject cube;
    public Transform target;

    void Update()
    {
        Quaternion q2 = Quaternion.Euler(0, 60, 0);
        cube.transform.rotation = Quaternion.Lerp(cube.transform.rotation, q2, 0.1f);
        Debug.Log("旋转角度:" + cube.transform.rotation.eulerAngles.y);//0-60
        Debug.Log("cube.transform.rotation.y" + cube.transform.rotation.y);//0-0.5
    }
}

2)、用下面这个方法是错误的,q1的y值一直都是从0 - 32.975变化,没更新一次都执行:Quaternion q1 = Quaternion.Euler(0, 30, 0);

public class QuaternionRotate : MonoBehaviour
{
    public GameObject cube;

    void Update()
    {
        Quaternion q1 = Quaternion.Euler(0, 30, 0);
        Quaternion q2 = Quaternion.Euler(0, 60, 0);
        q1 = Quaternion.Lerp(q1, q2, 0.1f);
        cube.transform.rotation = q1;//cube.transform.rotation.eulerAngles.y = 32.975
    }
}

正确的做法:q1变量放方法外。

public class QuaternionRotate : MonoBehaviour
{
    public GameObject cube;
    Quaternion q1 = Quaternion.Euler(0, 30, 0);
    void Update()
    {
        Quaternion q2 = Quaternion.Euler(0, 60, 0);
        q1 = Quaternion.Lerp(q1, q2, 0.1f);
        cube.transform.rotation = q1;//0 - 60
    }
}

3)、旋转看向目标物体

1.LookAt

​
public class QuaternionLookRotate : MonoBehaviour
{
    public GameObject cube;
    public Transform target;
    void Update()
    {
        //cube主角z轴瞬间看向目标物体
        cube.transform.LookAt(target);
    }
}

​

2.public static Quaternion LookRotation(Vector3 forward);

public class QuaternionLookRotate : MonoBehaviour
{
    public GameObject cube;
    void Update()
    {
        Vector3 dir = new Vector3(30, 0, 0);//(30,0,0)相当于(1,0,0)
        //cube主角的z轴看向目标物体(dir)即x轴正方向
        cube.transform.rotation = Quaternion.LookRotation(dir);
    }
}

        08735a1b31334b768beb7adefc1fc3dc.png5d7f3c0c5bb54ab9b45413d4f33c6906.png

当改变dir的值时,cube的z轴正方向看向的位置也改变

public class QuaternionLookRotate : MonoBehaviour
{
    public GameObject cube;
    void Update()
    {
        Vector3 dir = new Vector3(0, 10, 0);
        cube.transform.rotation = Quaternion.LookRotation(dir);
    }
}

a6a71dab361e4f8180553ecc18b8d95e.png8502d0fded9746b7a81ec964b5f27f57.png 

3.public static Quaternion LookRotation(Vector3 forward, [DefaultValue("Vector3.up")] Vector3 upwards);

public class QuaternionLookRotate : MonoBehaviour
{
    public GameObject cube;
    public Transform target;
    private void Start()
    {
        Debug.Log("Vector3.up:" + Vector3.up);//(0,1,0)
    }
    void Update()
    {
        Quaternion q1 = Quaternion.LookRotation(target.position - cube.transform.position);
        cube.transform.rotation = Quaternion.Lerp(cube.transform.rotation, q1, 0.1f);//最后cube的z轴指向target
        Debug.DrawLine(cube.transform.position, target.position,Color.blue);
    }
}

3d857c28ee3344be97bd7a240babd03d.png

 72317db99966449899472d57f311588a.png

 4、四元素和四元素相乘

就是两个相加

    public GameObject cube;
    public Transform target;
    void Start()
    {
        Quaternion q1 = Quaternion.Euler(0, 30, 0);
        Quaternion q2 = Quaternion.Euler(0, 60, 0);
        Quaternion q3 = q1 * q2;
        cube.transform.rotation = q3;
        Debug.Log("cube.transfor.rotation.eulerAngles: " +                 
        cube.transform.rotation.eulerAngles);
    }

3b19cc1ad3754dc685c8c143934b7656.png

5、鼠标控制物体旋转

public class MouseRotate : MonoBehaviour
{
    public GameObject cube;
    private float mousex;
    void Update()
    {
        mousex = Input.GetAxis("Mouse X");
        Quaternion q = Quaternion.AngleAxis(mousex, Vector3.up);
        cube.transform.rotation *= q;
    }
}

6、发射子弹

4eb6ba5c589c4bd7b7914e0809cf06be.png

 

biubullet类挂载在发射子弹的主角物体上,一定角度生成子弹

public class biubullet : MonoBehaviour
{
    public GameObject bullet;
    private float timer;
    void Start()
    {
        bullet = Resources.Load<GameObject>("Prefabs/bullet");
    }

    void Update()
    {
        timer += Time.deltaTime;
        if(timer > 3)
        {
           
             Vector3 dir = Quaternion.AngleAxis(-15, Vector3.up) * transform.forward;
             GameObject go = Instantiate(bullet);
             go.transform.position = transform.position;
             go.transform.rotation = Quaternion.LookRotation(dir);

             timer = 0;
        }
        

    }
}

BulletController类挂载在子弹上,控制子弹的移动

public class BulletController : MonoBehaviour
{
    
    void Update()
    {
        transform.Translate(Vector3.forward * 0.01f, Space.Self);
    }
}

7、环形发射子弹

设置timer的时间,3秒后发射一次环形子弹,发射完一次环形子弹就将timer设置回0

9b7c7ac71dc1483797a177aea6e803a2.png

 

public class biubullet : MonoBehaviour
{
    public GameObject bullet;
    private float timer;
    void Start()
    {
        bullet = Resources.Load<GameObject>("Prefabs/bullet");
    }

    void Update()
    {
        timer += Time.deltaTime;
        if(timer > 3)
        {
            //for(int i = 0; i < 5; i++)
            //{
            //    Vector3 dir = Quaternion.AngleAxis(-30 + i *15, Vector3.up) * transform.forward;
            //    GameObject go = Instantiate(bullet);
            //    go.transform.position = transform.position;
            //    go.transform.rotation = Quaternion.LookRotation(dir);
            //}

            //timer = 0;
            for (int i = 0; i < 24; i++)
            {
                Vector3 dir = Quaternion.AngleAxis(-30 + i * 15, Vector3.up) * transform.forward;
                GameObject go = Instantiate(bullet);
                go.transform.position = transform.position;
                go.transform.rotation = Quaternion.LookRotation(dir);
            }

            timer = 0;
        }
        

    }
}
public class BulletController : MonoBehaviour
{
    
    void Update()
    {
        transform.Translate(Vector3.forward * 0.01f, Space.Self);
    }
}

 8、子弹缓冲池

1)、PoolMain    缓冲池单例;挂载在创建的缓冲池空物体上

public class PoolMain : MonoBehaviour
{

    public static PoolMain Instance;
   
    private void Awake()
    {
        Instance = this;
    }

    GameObject bulletPool;

    public GameObject GetBulletPool()
    {
        if(bulletPool == null)
        {
            bulletPool = GameObject.Find("bulletPool");
        }
        return bulletPool;
    }
}

2)、biubullet   主角控制子弹的生成,缓冲池里没有子物体时克隆子弹(因为每3秒生成一圈子弹,而每5秒后将已生成的子弹设为缓冲池的子物体,所以克隆一圈子弹),缓冲池里有子物体时,就取出子物体。

public class biubullet : MonoBehaviour
{
    public GameObject bullet;
    private float timer;
    void Start()
    {
        bullet = Resources.Load<GameObject>("Prefabs/bullet");
    }

    void Update()
    {
        timer += Time.deltaTime;
        if(timer > 3)
        {
            for (int i = 0; i < 24; i++)
            {
                GameObject go = null;
                //找到缓冲池父物体
                GameObject pool = PoolMain.Instance.GetBulletPool();
                //判断缓冲池子物体数量是否足够
                if(pool.transform.childCount >0)
                {
                    //取缓冲池里的第一个子物体
                    go = pool.transform.GetChild(0).gameObject;
                    //把子弹物体迅速从缓冲池物体内取出
                    go.transform.parent = null;
                    //将游戏物体(子弹)设置为激活状态
                    go.SetActive(true);
                }
                else
                {
                    //缓冲池里没有子物体,就需要克隆子弹
                    go = Instantiate(bullet);
                }

                Vector3 dir = Quaternion.AngleAxis(-30 + i * 15, Vector3.up) * transform.forward;
                
                go.transform.position = transform.position;
                go.transform.rotation = Quaternion.LookRotation(dir);
            }

            timer = 0;
        }
        

    }
}

 3)、BulletController   控制子弹的移动,每5秒后将生成的子弹设置缓冲池物体的子物体,并失活

public class BulletController : MonoBehaviour
{
    private float timer;
    private GameObject pool;//缓冲池(空物体)

    private void Start()
    {
        pool = PoolMain.Instance.GetBulletPool();
    }

    void Update()
    {
        timer += Time.deltaTime;
        if(timer > 5)
        {
            //将生成的子弹的父物体设置为缓冲池物体
            transform.parent = pool.transform;
            timer = 0;
            //作为缓冲池物体的子物体后失活
            gameObject.SetActive(false);
        }
        transform.Translate(Vector3.forward * 0.01f, Space.Self);
    }
}

902eb7fe975e436f9ac2f13f61933ba6.png

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ོꦿ映ꦿ言᭄﹆ོོོ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值