Transform Component는 모든 GameObject에 존재하는 기본 컴포넌트로 Object의 위치(Position), 회전(Rotation), 크기(Scale)를 결정하는 컴포넌트이다.
Transform Component를 조작함으로 3D 공간의 Object를 어디에 배치하고 움직이고 변형시킬지에 대한 결정을 할 수 있다.
cs코드에서 Transform Component에 접근하는 방법은 매우 간단하다. transform이라는 변수를 사용하면된다. 또한, Transform Component를 가지고 있는 GameObject에 접근하는 방법은 transform.gameObject로 접근할 수 있다.
transfrom과transform.gameObject으로 접근하는 방법은 굉장히 많이 쓰인다.
transform의 position에 접근하는 방법은 위에서 설명했던 것과 같이 transfrom.position으로 접근할 수 있다. getter와 setter로 값을 변경하는 것이 아닌 transfrom.position = new Vector3(0.0f, 0.0f, 1.0f);와 같이 변수처럼 다룰 수 있다.
position 즉, 어떤 Object의 위치를 옮기기 위한 이벤트의 예로 WASD 이동이 있다. WASD 이동은 다음과 같은 이벤트의 일종의 Action으로 position을 변경하면서 구현할 수 있다.
1. W를 누르면 앞으로 이동한다.
2. S를 누르면 뒤로 이동한다.
3. A를 누르면 왼쪽으로 이동한다.
4. D를 누르면 오른쪽으로 이동한다.
이벤트가 동작할 조건을 정의했으면 각각의 조건에 맞는 transform을 조작함으로 WASD 이동을 구현할 수 있다.
if (Input.GetKey(KeyCode.W))
transform.position += new Vector3(0.0f, 0.0f, 1.0f);
if (Input.GetKey(KeyCode.S))
transform.position -= new Vector3(0.0f, 0.0f, 1.0f);
if (Input.GetKey(KeyCode.A))
transform.position -= new Vector3(1.0f, 0.0f, 0.0f);
if (Input.GetKey(KeyCode.D))
transform.position += new Vector3(1.0f, 0.0f, 0.0f);

움직이는 것을 보면 잠깐만 눌렀음에도 너무 빠르게 움직인다. 속도 조절할 방법이 필요하다.
WASD 이동을 구현할 때의 코드를 보면 Update()안에 각각의 키를 눌렀을 때 position에 특정 벡터만큼 더하거나 빼줌으로 구현한 것을 알 수 있다.
void Update(){
if (Input.GetKey(KeyCode.W))
transform.position += new Vector3(0.0f, 0.0f, 1.0f);
if (Input.GetKey(KeyCode.S))
transform.position -= new Vector3(0.0f, 0.0f, 1.0f);
if (Input.GetKey(KeyCode.A))
transform.position -= new Vector3(1.0f, 0.0f, 0.0f);
if (Input.GetKey(KeyCode.D))
transform.position += new Vector3(1.0f, 0.0f, 0.0f);
}
그렇다는 것은 각 프레임마다 Update가 실행된다는 것이고 만약 10프레임(60fps기준 1/6초)동안 W를 누르고 있다면 총 10.0f만큼 앞으로 이동할 것이다.
이전 프레임과 현재 프레임 사이의 시간을 나타내는 Time.deltaTime을 사용하자
Time.deltaTime은 뜻 그대로 이전 프레임과 현재 프레임 사이의 시간을 반환하는 변수로 하드웨어 환경마다 프레임 속도가 다를 수 있기 때문에 사용한다. Time.deltaTime을 사용함으로 프레임 속도에 관계 없이 일관된 게임로직을 제공할 수 있다.
if (Input.GetKey(KeyCode.W))
transform.position += new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime;
생각해보면 Time.deltaTime은 다양한 fps환경에서의 일반화를 시켜준 것이지 속도조절에 관련된 직접적인 기능은 아니다.
속도 조절을 위한 방법으로 가장 간단한 방법은
speed라는 상수를 하나 정의하는 것이다.
속도를 높이거나 줄이고 싶을 때 speed를 변경하면 된다.
float _speed = 10.0f;
if (Input.GetKey(KeyCode.W))
transform.position += Vector3.forward * Time.deltaTime * _speed;
하드웨어 환경적인 요소를 Time.deltaTIme으로, 속도의 크기 조절은 speed라는 상수를 통해 다양한 환경에서의 일정한 속도를 보장할 수 있다.
Rotate는 Transform Component에서 Object의 회전을 나타내는 요소로 x,y,z 축에 대한 회전한 각도를 나타낸다. Rotate의 접근 방법은 transfrom.rotate 변수로 직접 수정이 가능하다.
회전하는 각도는 각도를 나타내기 때문에 음수와 양수로 나타낼 수 있고 절대값이 같으면 방향만 반대인 Vector라고 생각하면 된다.
방향이 헷갈린다면
플레밍의 왼손법칙을 생각하자
엄지를 회전하고자 하는 축으로 생각하고 왼손으로 감싸는 방향이+이다.
Position에서 구현한 WASD 이동을 Rotate된 상태에서 적용하면 놀랍게도 캐릭터가 바라보는 방향이 아닌 다른 방향으로 움직인다. 이러한 상황이 발생한 이유는 좌표계의 차이로 인해 발생하는데 일반적인 물리학에서 다루는 그 좌표계로 생각하면 된다.
'어떻게 지평좌표계로 고정을 하셨죠?'라는 말이 떠오른다면 정답이다!
앞선 단계에서 WASD 이동의 Action은 다음과 같이 정의했다.
1. W를 누르면 앞으로 이동한다.
2. S를 누르면 뒤로 이동한다.
3. A를 누르면 왼쪽으로 이동한다.
4. D를 누르면 오른쪽으로 이동한다.
이동하는 방향을 보면 앞,뒤,왼쪽,오른쪽으로 되어 있을 뿐 무엇을 기준으로 앞,뒤,왼쪽,오른쪽정해주질 않았다.
Unity는 따로 지정해주지 않으면 World좌표계를 기준으로 계산한다.
즉,W를 누르면 앞으로 이동한다.는W를 누르면 (절대 좌표 기준)앞으로 이동한다.로 행동한다.
만들고자 하는 것은캐릭터가 바라보는 방향을 기준으로 하는 이동이다.
Unity에는 이를 위해 transform.TranformDirection이라는 함수를 제공한다.
transform.TranformDirection은 Local좌표를 World좌표로 좌표계산을 해준다.transform.TranformDirection은 회전에 대한 계산을 한다. 즉, 스칼라값에 영향을 미치지 않는다.위 내용을 반영한 WASD 이동의 구현은 다음과 같이 바꿀 수 있다.
if (Input.GetKey(KeyCode.W))
transform.position += transform.TransformDirection(Vector3.forward * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.S))
transform.position -= transform.TransformDirection(Vector3.back * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.A))
transform.position -= transform.TransformDirection(Vector3.left * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.D))
transform.position += transform.TransformDirection(Vector3.right * Time.deltaTime * _speed);
Vector3.forward는 Unity에서 제공하는 예약어로 Vector3(0.0f, 0.0f, 1.0f)와 같다.
Local -> World는
transform.TranformDirection을 사용하고
World -> Local은transform.InverseTranformDirection을 사용하면 된다.
World좌표계와 Local좌표계의 계산이 너무 복잡하다면 transform.Translate()라는 함수를 사용하면 된다.
transform.Translate()는 방향과 크기(벡터)를 입력하면 '바라보는 방향'을 기준으로 이동을 하기 때문에 좌표계를 신경쓰지 않아도 된다.Scale은 Transform Component에서 Object의 크기를 나타내는 요소로 Vector3 형식으로 x,y,z축에 대한 상대적인 크기값을 나타낸다.
기본 값은 x,y,z=(1,1,1)이지만 (0.5,0.5,0.5)로 하면 크기가 절반, (2,2,2)로하면 크기가 2배가 되는 것이다.