프로그래밍 농장

백터 연산 기초 /물체의 이동(좌표,평행)+ 쿼터니언 [ Unity ] 본문

Unity

백터 연산 기초 /물체의 이동(좌표,평행)+ 쿼터니언 [ Unity ]

Tennessee201 2022. 7. 7.
728x90

유니티에서는 보통 좌표, 위치등을 설정하기 위하여 Vector3, Vector2 를 통하여 접하게 된다. 

단순하게 Vector란, 정해진 갯수의 원소를 가지고 있는것을 뜻한다.

ex) Vector3의 경우 (x, y, z) 세가지의 원소를 가지고 있는 경우

 

유니티 게임에서의 Vector란, '길이'와 '방향'을 가지는 존재이다. 

(2,3) 의 경우 :

1. 내가 (2,3) 지점에 있다 (절대좌표 : 시작지점 )

2. 내 위치에 "상대적으로" (2,3)만큼 가고 있다. (현재 내 위치는 중요 x )


좌표가 아래와 같이 (4,-3) 이라고 가정할떄, 백터의 크기 (Magnitude)는 5라고 할수있다. (속도, 거리 . .)

 

Vector는 내 위치에서 '얼마만큼 가야' 목표위치에 도달할 수 있는지를 알수있다. 

y - x = z 

(4,-3) = (0.8,-0.6) * 5 -> 길이가 "1" 인 Vector * 속도 


- 물체의 좌표 이동, 평행이동 ( Global space, Local space )

Global : 절대적 / Local : 상대적 좌표계

위와 같이 Cube가 있다고 가정할때, Input Keycode(space) 시 큐브의 이동방향은 지정해주는 좌표계 방식에 따라 달라진다. 

+ 만약 Update() 에서 큐브가 Time.deltaTime 만큼씩 Rotate(x,y,z)만큼 돌떄 space를 누른다면 :

좌표계에 따라서 이동한다. ( Object의 좌표계는 고정되어있음 )

 

space.self : 오브젝트 자체를 기준으로 좌표계 설정 ( 상대적 )

space.world : 게임 씬을 기준으로 좌표계 설정 (절대적 )

Object의 위치는 상대적 (localspace : 부모기준)

사용방식 :

new Vector3 (x, y, z);

new Vector2 (x, y); . .


- 회전 / 쿼터니언

아래와 같이 Cube의 Rotation을 60,60,60으로 지정하였을때, 이는 단순히 Vector3를 통해서 Inspector에서 지정한다. 

 하지만 Script 상에서 Cube의 Rotation을 변경해주려 한다면 아래와 같이 에러가 발생한다.

'Quaternion'

이 경우 아래와 같이 Quaternion.Euler() 를 통하여 오일러 함수가 Quternion 타입으로 형변환을 해준다. 

 

Euler ? : x, y, z (vertor3)를 통해서 공간의 회전을 표시할수있도록 한 수학자 


- 짐벌락 현상 

 : 특정 Object를 회전시켰을떄, x, y, z 축 중 일부가 겹치게 되면 기존의 축정보가 소실되는 현상 

 : 예전 비행기게임들은 오일러각에서 좌표축이 회전될때 이전 축과 겹치지 않도록 조금씩 차이를 두었다. 


- Quaternion(쿼터니언) 란 ?

-> 쿼터니언 컴포넌트 : (x, y, z, w) 로 구분되고 이는 복잡한 구성으로 되어있기에 유니티에서는 Vector3()를 통하여 이를 구성하도록 하였다.

Quaternion newRotation = Quarternion.Euler(new Vector3(45,60,90));

//2
Quarternion targetRotation = Quarternion.LookRotation(new Vector3(0,1,0));

transfrom.rotation = newRotation;

해당 오브젝트의 앞쪽인 Z축이 해당방향으로 전환되어 겹치는 축데이터가 변경됨. 


: Quaternion -> Vector3 로도 변환이 가능하다. 

Quaternion originalRotation = transfrom.rotation; //현재 object기준 

Vector3 originalRotationInVector3 = originalRotation.eulerAngles;
Vector3 targetRotationVec = originalRotationInVector3 + new Vector3(30,0,0);

Quaternion targetRotation = Quaternion.Euler(targetRotationVec);

transform.rotation = targetRotation;

그 외 Quaternion 끼리 곱하는 방식으로의 전환도 가능하지만, 가장 간단한 방법은 위와 같이 Vector3()의 값을 더해주는 것이다. 

 


+ 그렇다면 만약에 (30,45,60)의 rotation을 가진 Object를 Script에서 아래와 같이 선언해주면 (60,45,60)으로 바뀔까?

transform.Rotate(new Vector3(30,0,0));

Why? : 원래 큐브는 (30,45,60) 인 상태에서 Script에서는 나 자신 (transfrom .~~ )을 기준으로 회전하였기 떄문.

728x90