Transform
Unity의 모든 GameObject에 자동으로 포함된 기본 컴포넌트다.
이는 단순히 위치를 저장하는 데이터 구조 뿐만 아니라 씬 내에서 공간적 존재를 정의하는 근본적인 컴포넌트다.
구성 요소
| Position | 오브젝트 위치 | Vector |
| Rotation | 오브젝트 회전 | Quaternion |
| Scale | 오브젝트 크기 | Vector |
자식 오브젝트는 부모의 Transform 영향을 함께 받는다.
즉 부모가 회전하거나 이동하면 자식도 같이 회전하거나 이동하는 것이다.
이것을 월드 좌표와 로컬 좌표로 설명할 수 있다.
월드 좌표 (World Space) : 씬 전체의 기준 좌표계. (0,0,0)은 씬의 절대 원점.
로컬 좌표 (Local Space) : 부모 Transform을 기준으로 한 상대 좌표. 부모가 회전하면 자신의 방향 벡터도 함께 회전.
주요 속성
| position | 월드 공간(World Space) 상의 오브젝트 위치 | Vector3 |
| localPosition | 부모를 기준으로 한 로컬 공간(Local Space) 위치 | Vector3 |
| rotation | 오브젝트의 월드 회전(Quaternion) | Quaternion |
| localRotation | 부모를 기준으로 한 회전 값 | Quaternion |
| localScale | 부모 스케일에 상대적인 크기 비율 | Vector3 |
| forward | 전방(Z+) 방향 벡터 | Vector3 |
| right | 오른쪽(X+) 방향 벡터 | Vector3 |
| up | 위쪽(Y+) 방향 벡터 | Vector3 |
주요 메서드
| Translate(Vector3 move) | 현재 위치를 기준으로 이동 |
| Rotate(Vector3 euler) | 지정한 각도만큼 회전 (Euler 각 기반) |
| LookAt(Transform target) | 대상 방향으로 회전 |
| TransformPoint(Vector3 localPos) | 로컬 좌표 → 월드 좌표 변환 |
| InverseTransformPoint(Vector3 worldPos) | 월드 좌표 → 로컬 좌표 변환 |
부모-자식 계층 구조를 신경써야 하는 건 C# 클래스 다루는 것과 굉장히 비슷한 느낌을 받는다.
Unity가 굉장히 많은 걸 해결해준 건 맞지만 신경 써야 할 것도 더 많아진 것 같다...
Vector
크기(Magnitude)와 방향(Direction)을 나타내는 수학적 개념이다.
Unity에서는 공간상의 점, 방향, 이동량 등을 표현하는 구조체다.
| Vector3.zero | (0, 0, 0) - 원점 |
| Vector3.one | (1, 1, 1) - 모든 축 1 |
| Vector3.up / Vector3.down | (0, 1, 0) / (0, -1, 0) |
| Vector3.right / Vector3.left | (1, 0, 0) / (-1, 0, 0) |
| Vector3.forward / Vector3.back | (0, 0, 1) / (0, 0, -1) |
Unity에서 앞(forward)는 z축에 해당한다
주요 메서드
| magnitude | 벡터의 크기 (거리) |
| normalized | 단위 벡터 (크기 1로 정규화된 방향) |
| Dot(a, b) | 내적 — 두 벡터의 방향 유사도 계산 |
| Cross(a, b) | 외적 — 두 벡터에 수직인 벡터 계산 |
| Lerp(a, b, t) | 선형 보간 (a→b 사이를 t만큼 보간) |
| MoveTowards(a, b, maxDistance) | 일정 거리만큼 b 방향으로 이동 |
| ClampMagnitude(v, maxLen) | 벡터의 최대 길이 제한 |
Vector3.Lerp()
transform.position = Vector3.Lerp(startPos, targetPos, 0.5f);
선형 보간 (선형 가감속 생각하면 됨)
targetPos에 가까워 질수록 느려짐
카메라 추적 등에 어울려 보인다.
Normalize()
Vector3 dir = (target - transform.position).normalized;
transform.position += dir * speed * Time.deltaTime;
방향 벡터를 길이 1로 만들어 순수한 방향만 남긴다.
대각선 이동시 가로, 세로 각각 1씩 이동하면, 이동거리는 1이 아니라 루트2가 된다.
이런거 방지하고자 하는 연산.
Quaternion
3차원 공간에서의 회전을 나타내는데 사용되는 4개개의 실수로 구성된 4차원 복소수로 이루어진 수학적 개념이다.
| x, y, z, w | 4차원 좌표 (단위 쿼터니언) |
| identity | 회전이 없는 상태 (0,0,0,1) |
Euler vs Quaternion
Euler(오일러) 각도는 사람이 이해하기에 더 직관적이고 쉽지만,
Pitch(상하)가 90도 근처에 도달하면 축이 겹치면서 Gmbal Lock이 발생한다.
이는 세 축 중 하나가 겹쳐져서 회전 자유도를 상실하는 상태를 말한다.
Quaternion은 이를 방지하며, 축-각 회전(axis-angle rotation) 기반으로
복잡한 회전 계산을 안정적으로 수행한다.
주요 메서드
| Translate(Vector3 translation) | 현재 위치에서 상대 이동 |
| Rotate(Vector3 eulers) | 현재 회전에 상대 회전 적용 |
| LookAt(transform target) | 대상 Transform 바라보기 |
| SetParent(Transform parent) | 부모 Transform 설정 |
| Find(string name) | 자식 중 이름으로 Transform 탐색 |
| Euler(x,y,z) | Euler 각도 → Quaternion 변환 |
| LookRotation(forward) | 지정 방향을 바라보는 회전 생성 |
| Slerp(a, b, t) | 구면 선형 보간 (부드러운 회전 전환) |
| AngleAxis(angle, axis) | 축과 각도로 회전 정의 |
예시
transform.rotation = Quaternion.Euler(0, 180, 0);
transform.rotation = Quaternion.LookRotation(targetDir);
주요 속성
| position | 월드 좌표 기준 위치 |
| localPosition | 부모 Transform 기준의 위치 |
| rotation | 월드 좌표 기준 회전 |
| local Rotation | 부모 Transform 기준 회전 |
| localScale | 부모 transform 기준 크기 |
| parent | 부모 Transform 참조. 없으면 씬 루트에 속함 |
| childCount | 자식 오브젝트 수 |
| GetChild(index) | 특정 인덱스 자식 Transform 반환 |
| SetParent(parent) | 부모 Transform 지정 / 변경 |
Input Class
Transform에 대해 알았으니 이제 이동을 구현할 수 있다.
Unity의 Input 클래스는 키보드, 마우스, 조이스틱 입력을 감지한다.
| Input.GetKey(KeyCode.W) | 키를 누르고 있는 동안 true |
| Input.GetKeyDown(KeyCode.Space) | 눌린 순간 한 프레임만 true |
| Input.GetKeyUp(KeyCode.Space) | 떼는 순간 한 프레임만 true |
| Input.GetAxis("Horizontal") | -1 ~ 1 사이 값으로 방향 감지 (부드러운 전환) |
| Input.GetAxisRaw("Horizontal") | 즉시 반응 (-1, 0, 1 값만 반환) |
GetAxis vs GetAxisRaw
float moveX = Input.GetAxis("Horizontal"); // 부드럽게
float moveX = Input.GetAxisRaw("Horizontal"); // 즉각적으로
| GetAxis | GetAxisRaw | |
| 감도(Smoothing) | 있음 | 없음 |
| 반응속도 | 느림 | 즉시 |
| 주 사용처 | 캐릭터 이동, 카메라 | 메뉴 조작, 입력 감지 |
레이싱, 천천히 걷거나 빨리 뛰기를 키 하나로 조작하는 것 같은 "입력 강도"와 비슷한 것을 구현할 때는 GetAxis가 적절하고, 단순하고 정확한 이동을 원한다면 GetAxisRaw가 적절하다.
입력 클래스 구현 예시
void Update()
{
_horInput = Input.GetAxisRaw("Horizontal");
_verInput = Input.GetAxisRaw("Vertical");
_spacebarInput = Input.GetKey(KeyCode.Space);
}
입력을 이동으로 구현 예시
private void Move()
{
Vector3 inputVec = new Vector3(_inputComponent.HorInput, 0f, _inputComponent.VerInput).normalized;
Vector3 deltaMovement = moveSpeed * Time.deltaTime * inputVec;
Vector3 nextPosition = transform.position + deltaMovement;
float xGap = xBoundValue * _playerExtents.x;
float zGap = zBoundValue * _playerExtents.z;
nextPosition.x = Mathf.Clamp(nextPosition.x, _minWorldBounds.x + xGap, _maxWorldBounds.x - xGap);
nextPosition.z = Mathf.Clamp(nextPosition.z, _minWorldBounds.z + zGap, _maxWorldBounds.z - zGap);
transform.position = nextPosition;
}
여기에 Clamp라는 게 적용돼있다.
이는 오브젝트가 특정 영역 안에서만 위치하도록 제한하는 대표적인 방법이다.
Mathf.Clamp() 를 통해 최소~최대 범위를 지정할 수 있다.

클램프 지정을 통해 맵 밖으로 비행기가 나가지 않는 것이 제대로 구현된 모습이다.
Time.deltaTime
또한 이동을 계산할 때 Time.deltaTime을 곱해주는 것을 볼 수 있다.
이는 프레임 사이의 시간 값으로, 이것을 곱해줌으로서 Update 마다 Move()가 호출됐을때, 서로 다른 프레임의 환경에서도 동일한 이동거리를 보장해준다.
이게 없으면... 60FPS 나오는 컴퓨터와 180FPS 나오는 컴퓨터는 3배 정도의 이동량 차이가 나기 때문에 꼭 잘 알아두고 필요한 곳에 적절히 쓰도록 하자.
'Unity' 카테고리의 다른 글
| Unity - EventSystem (이벤트 시스템) (0) | 2025.10.20 |
|---|---|
| Unity - Coroutine, yield, Invoke, IEnumerator (0) | 2025.10.17 |
| Unity - Rigidbody, Collider - 물리, 충돌 처리 (0) | 2025.10.16 |
| Unity - 오브젝트(Object), 컴포넌트(Component), 오브젝트 풀링(Object Pooling) (0) | 2025.10.14 |
| Unity - 생명주기 (Life Cycle) (1) | 2025.10.13 |