【第015问 Unity中如何使用矩阵对Transform进行变换?】

一、背景

物体的变换包括旋转、缩放、位移;平时都是直接使用各种现有的api进行操作,但没有使用矩阵的方式来实践操作;实践的目的在于对一些基础知识的总结和学习,因此在此记录,方便查阅…

二、效果演示

在这里插入图片描述

三、源码

/*
 功能:
 作者:valaki
 B站分享:https://space.bilibili.com/275988336?spm_id_from=333.1007.0.0
 创建时间:2022-5-22 9:52:4
 版本:1.0.0   
*/


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

[ExecuteAlways]
public class MatrixRotateTest : MonoBehaviour
{
    public enum MatrixType
    {
        None,

        //对象移动
        Move = 1,

        //对象沿x轴旋转
        Roate_X = 2,

        //对象沿y轴旋转
        Roate_Y = 3,

        //对象沿Z轴旋转
        Roate_Z = 4,

        //缩放
        Scale = 5,

        //移动 旋转聚合为一个矩阵
        ALl = 6,
    }


    public MatrixType matrixType = MatrixType.None;

    public Vector3 rotateOffset;

    public Vector3 moveOffset = Vector3.zero;

    public Vector3 scaleOffset = Vector3.one;

    private Vector3 defaultPos = Vector3.zero;

    private Vector3 defaultScale = Vector3.one;


    private void OnDrawGizmos()
    {
        if (defaultPos == Vector3.zero)
            defaultPos = transform.position;


        Matrix4x4 matrix4X4 = Matrix4x4.identity;

        if (matrixType == MatrixType.ALl)
        {
            matrix4X4 = GetGroupMatrix();
        }
        else
        {
            matrix4X4 = GetMatrix(matrixType);
        }

        Vector4 vector4 = defaultPos;
        vector4.w = 1;
        if (matrixType == MatrixType.Scale)
        {
            vector4 = defaultScale;
            vector4.w = 1;
            transform.localScale = matrix4X4 * vector4;
        }
        else
        {
            transform.position = matrix4X4 * vector4;
        }
    }


    /// <summary>
    /// 获取矩阵
    /// </summary>
    /// <returns></returns>
    Matrix4x4 GetMatrix(MatrixType _matrixType)
    {
        Matrix4x4 matrix4X4 = Matrix4x4.identity;
        float cos = 0;
        float sin = 0;
        switch (_matrixType)
        {
            case MatrixType.Roate_X:
            {
                /*
                 *  沿x轴旋转矩阵的矩阵形式
                 *[1    0            0             0]
                 *[0    cos(角度)    -sin(角度)    0]    
                 *[0    sin(角度)    cos(角度)     0]
                 *[0    0            0             1]  
                 */
                cos = Mathf.Cos(rotateOffset.x);
                sin = Mathf.Sin(rotateOffset.x);

                matrix4X4.m11 = cos;
                matrix4X4.m12 = -sin;

                matrix4X4.m21 = sin;
                matrix4X4.m22 = cos;
                break;
            }

            case MatrixType.Roate_Y:
            {
                /*
                 * 沿y轴旋转矩阵的矩阵形式
                 *[cos(角度)     0    sin(角度)    0]
                 *[0            1    0            0]
                 *[-sin(角度)    0    cos(角度)    0]
                 *[0            0    0           1] 
                 */

                cos = Mathf.Cos(rotateOffset.y);
                sin = Mathf.Sin(rotateOffset.y);

                matrix4X4.m00 = cos;
                matrix4X4.m03 = sin;

                matrix4X4.m20 = -sin;
                matrix4X4.m23 = cos;

                break;
            }

            case MatrixType.Roate_Z:
            {
                /*
                 * 沿z旋转矩阵的矩阵形式
                 *[cos(角度)    -sin(角度)    0    0]
                 *[sin(角度)    cos(角度)     0    0]
                 *[0            0            1    0]
                 *[0            0            0    1]  
                 */

                cos = Mathf.Cos(rotateOffset.z);
                sin = Mathf.Sin(rotateOffset.z);

                matrix4X4.m00 = cos;
                matrix4X4.m01 = -sin;

                matrix4X4.m10 = sin;
                matrix4X4.m11 = cos;
                break;
            }

            case MatrixType.Move:
            {
                /*
                 * 平移矩阵
                 *[1    0    0    x]
                 *[0    1    0    y]
                 *[0    0    1    z]
                 *[0    0    0    1]
                 *
                 * 
                 *
                 * *
                 */

                matrix4X4.m03 = moveOffset.x;
                matrix4X4.m13 = moveOffset.y;
                matrix4X4.m23 = moveOffset.z;
                break;
            }

            case MatrixType.Scale:
            {
                /*
                 *    缩放矩阵表现形式
                 *[ scalex    0         0        0]
                 *[0          scaley    0        0]
                 *[0          0        scalez    0]
                 *[0          0         0        1] 
                 * 
                 */


                matrix4X4.m00 = scaleOffset.x;
                matrix4X4.m11 = scaleOffset.y;
                matrix4X4.m22 = scaleOffset.z;
            }
                break;
        }

        return matrix4X4;
    }

    /// <summary>
    /// 获取组合矩阵 包括缩放,旋转 平移、
    /// </summary>
    /// <returns></returns>
    Matrix4x4 GetGroupMatrix()
    {
        Matrix4x4 matrix4X4 = Matrix4x4.identity;
        //缩放矩阵
        Matrix4x4 scaleMatrix = GetMatrix(MatrixType.Scale);
        //z轴旋转矩阵
        Matrix4x4 zRoateMatrix = GetMatrix(MatrixType.Roate_Z);
        //x旋转矩阵
        Matrix4x4 xRoateMatrix = GetMatrix(MatrixType.Roate_X);
        //y轴旋转矩阵
        Matrix4x4 yRoateMatrix = GetMatrix(MatrixType.Roate_Y);
        //移动矩阵
        Matrix4x4 moveMatrix = GetMatrix(MatrixType.Move);

        matrix4X4 = moveMatrix * zRoateMatrix * xRoateMatrix * yRoateMatrix * scaleMatrix;

        return matrix4X4;
    }
}

结语

valaki----实践一下不会有什么遗憾

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值