반응형
[게임이론] 행렬에 이어 이번엔 실재 Unity상에서 관련된 코드들을 확인해본다.
행렬은 DirectX, OpenGL 그래픽스 API를 학습하게 되면 많이 다루게 되지만 Unity 내에서는 Mesh 값을 직접 변경하지 않는 이상 사용할 일이 별로 없다. Shader등의 심화된 내용을 다루게 될때 더 빈번히 사용될 수 있겠다. 본 예제를 통해 Transform 값이 행렬을 이용해서 연산이 되고 있음을 알아두자.
Unity의 Inspector에서 확인할 수 있는 다음의 Transform 속성을 행렬 변환을 통해 좌표 값이 어떻게 변하는지 확인하겠다.
먼저 앞서 학습한 TRS를 이용한 행렬을 도출하는 과정을 보겠다.
행렬 값 설정
이동(T), 회전(R), 스케일(S) 값을 변수에 부여해서 Matrix4x4.TRS 매서드를 이용한 행렬 도출 방식이다. 회전 값에는 오일러 각을 이용하여 더 직관적으로 각도를 설정해줄 수 있으며, 짐벌락 문제 때문에 오일러 각을 쿼터니언(사원수)으로 변환, 사용된다.
private Matrix4x4 worldMat;
// 이동 값
Vector3 tran = new Vector3(2, 1, 0);
// 회전 값(쿼터니언)
Quaternion rot = Quaternion.Euler(45, 0, 45);
// 스케일 값
Vector3 scal = new Vector3(3, 3, 3);
// World Matrix 생성
worldMat = Matrix4x4.TRS(tran, rot, scal);
Debug.Log("=== World Matrix ===");
for (int i = 0; i < 4; i++)
{
//Debug.Log(worldMat.GetColumn(i));
Debug.Log(worldMat.GetRow(i));
}
이동행렬, 회전행렬, 크기 변환 행렬을 직접 계산 하는 방식이다. TRS 순서에 맞게 행렬을 곱한 다음 Matrix4x4.Translate 메서드에 입력해주면 된다.
private Matrix4x4 worldMat;
// 회전 값(쿼터니언)
Quaternion rot = Quaternion.Euler(45, 0, 45);
worldMat = Matrix4x4.Translate(new Vector3(2, 1, 0)) * Matrix4x4.Rotate(rot)
* Matrix4x4.Scale(new Vector3(3,3,3));
Debug.Log("=== World Matrix ===");
for (int i = 0; i < 4; i++)
{
//Debug.Log(worldMat.GetColumn(i));
Debug.Log(worldMat.GetRow(i));
}
행렬 값 추출
객체의 transform 속성의 localToWorldMatrix 를 사용해서 변환 행렬 값을 얻는다. 이 값은 위의 TRS와 동일하다. 그리고 이 행렬을 이용해서 각각의 위치, 회전 , 스케일 값을 획득한다.
// localToWorld Matrix를 저장
// TRS == localToWorldMatrix
Matrix4x4 matrix = transform.localToWorldMatrix;
Debug.Log("=== Extraction Matrix ===");
for (int i = 0; i < 4; i++)
{
// Colum 행, row 열
//Debug.Log(matrix.GetColumn(i));
Debug.Log(matrix.GetRow(i));
}
// 변환 행렬에서 Position, Rotation, Scale 값을 얻는다.
Vector3 position = matrix.GetColumn(3);
Debug.Log("=== Position ===");
Debug.Log(position);
Quaternion rotation = Quaternion.LookRotation(
matrix.GetColumn(2),
matrix.GetColumn(1)
);
Debug.Log("=== Rotation ===");
Debug.Log(rotation.eulerAngles);
Debug.Log("=== Scale ===");
Vector3 scale = new Vector3(
matrix.GetColumn(0).magnitude,
matrix.GetColumn(1).magnitude,
matrix.GetColumn(2).magnitude
);
Debug.Log(scale);
반응형