핵심 정리
| 항목 | 내용 |
|---|---|
| 역할 | 모든 GameObject가 반드시 가지는 위치, 회전, 스케일, 부모-자식 계층 컴포넌트 |
| 언제 쓰는가 | 오브젝트 배치, 회전, 계층 기준 좌표 변환, 자식 정렬을 다룰 때 |
| 기준 버전 | Unity 6.5 (6000.5) |
| 핵심 Inspector | Position, Rotation, Scale, Constrain Proportions |
| 자주 연결되는 API | position, localPosition, rotation, localRotation, SetParent, TransformPoint, InverseTransformPoint |
Inspector 설정
| 설정값 | 언제 바꾸는가 | 잘못 맞추면 생기는 문제 |
|---|---|---|
| Position | 부모 기준 배치점, 발사 위치, 부착 위치를 잡을 때 | 로컬/월드 좌표를 헷갈려 프리팹 내부와 런타임 위치가 달라짐 |
| Rotation | 오브젝트 방향, 총구 각도, 카메라 기준 축을 맞출 때 | 부모 회전과 섞여 예상과 다른 축으로 꺾임 |
| Scale | 프롭 크기 조정, UI 기준 오브젝트 크기 보정이 필요할 때 | 비균일 스케일로 자식 Collider, Light, Audio 범위가 어색해짐 |
| Constrain Proportions | 비율을 유지한 채 크기만 키우거나 줄일 때 | 한 축만 고쳐야 하는 오브젝트까지 같이 늘어나 배치가 틀어짐 |
Position
Inspector의 Position은 부모가 있으면 로컬 좌표입니다. 부모가 없을 때만 월드 좌표처럼 읽힙니다. 자식 무기, UI 기준점, 발사 위치처럼 "부모를 따라가야 하는 기준점"이면 로컬 Position을 조정하는 경우가 많습니다.
부모가 있는 오브젝트에서 Position을 월드 좌표처럼 착각하면, 프리팹 안에서는 맞는데 런타임 배치 후 어긋나는 문제가 자주 납니다.
Rotation
Inspector Rotation은 오일러 각도로 보이지만 내부적으로는 쿼터니언으로 저장됩니다. 작은 보정은 Inspector에서 하기 쉽지만, 코드에서는 transform.eulerAngles를 계속 읽고 더하는 방식보다 Rotate, rotation, Quaternion 계산이 더 안전합니다.
부모 회전이 있는 자식에서 local/world 회전을 섞으면 카메라 리그나 무기 부착물이 이상한 축으로 꺾일 수 있습니다.
Scale
(1,1,1)이 원본 크기입니다. 물리 오브젝트, 광원, 오디오 반경, 자식 본 구조에서는 비균일 스케일이 예상 밖 부작용을 만들기 쉽습니다. 특히 부모가 (2,1,1)처럼 비균일 스케일이면 자식 회전 시 찌그러져 보이거나 Collider가 메시와 덜 맞아 보일 수 있습니다.
축 하나를 0으로 두면 렌더링과 수학 계산이 깨질 수 있으므로, "숨기기" 용도로 Scale 0을 쓰는 방식은 피하는 편이 좋습니다.
Constrain Proportions
비율 잠금은 한 축을 바꿀 때 다른 축도 같은 비율로 따라오게 합니다. 간단한 프롭 배치에는 편하지만, 물리 크기나 UI 기준 오브젝트는 한 축만 바꾸는 편이 더 명시적일 수 있습니다.
스크립트 연결
| 필드/프로퍼티 | 언제 읽거나 쓰는가 | 주의할 점 |
|---|---|---|
position | 월드 좌표를 직접 맞출 때 | 부모가 있어도 결과는 월드 기준 |
localPosition | 부모 기준 상대 위치를 조정할 때 | 부모 이동/회전에 따라 실제 월드 위치가 바뀜 |
rotation / localRotation | 월드/부모 기준 회전을 나눠 제어할 때 | 쿼터니언과 오일러 각을 섞어 덮어쓰기 쉽다 |
forward, right, up | 발사 방향, 전진 방향, 기준 축이 필요할 때 | 부모 회전이 반영된 방향 벡터라는 점을 같이 봐야 함 |
lossyScale | 최종 월드 스케일을 읽어야 할 때 | 계산용 읽기에는 편하지만 정확한 쓰기 기준은 아님 |
| 메서드 | 언제 쓰는가 | 연결 지점 |
|---|---|---|
SetParent() | 런타임 장착, UI 재배치, 풀링 오브젝트 재소속 | Awake, 장착/해제 함수 |
TransformPoint() | 로컬 오프셋을 월드 좌표로 바꿀 때 | 추적 카메라, 발사 위치 계산 |
InverseTransformPoint() | 월드 좌표를 로컬 기준으로 환산할 때 | 히트 위치를 로컬 공간으로 저장할 때 |
LookAt() | 특정 대상을 향하게 만들 때 | Update, LateUpdate |
Rotate() / Translate() | 간단한 증분 이동, 회전 보정 | 물리 객체에는 남용하지 않는 편이 안전 |
자주 쓰는 연결은 "월드 좌표를 직접 세팅할지", "부모 기준으로 붙일지", "좌표 변환이 필요한지"를 먼저 나누는 것입니다.
using UnityEngine;
public class FollowAnchor : MonoBehaviour
{
[SerializeField] private Transform target;
[SerializeField] private Vector3 localOffset = new(0f, 1.5f, -3f);
private void LateUpdate()
{
if (target == null) return;
transform.position = target.TransformPoint(localOffset);
transform.rotation = Quaternion.LookRotation(target.forward, Vector3.up);
}
}Update는 일반적인 위치 보정에, LateUpdate는 카메라 추적처럼 "대상 이동이 끝난 뒤" 따라가야 할 때 자주 씁니다.
자주 틀리는 부분
- 부모가 있는 오브젝트에서 Inspector Position을 월드 좌표처럼 읽으면 프리팹 내부 배치가 어긋납니다.
- Rigidbody가 붙은 오브젝트를 물리 이동 용도로
Transform으로 직접 움직이면 충돌과 보간이 흔들립니다. - 비균일 Scale 아래 자식 Collider, Light, Audio Source를 두면 반경/형태가 기대와 다르게 느껴질 수 있습니다.
- Scale 0으로 숨기면 렌더링만이 아니라 계산 결과까지 깨질 수 있습니다.
관련 컴포넌트
Rigidbody, Collider, Camera, Unity Transform local vs world 좌표, GameObject, Component, Transform 관계
참고 링크
2 sources