전체 코드
- Unity에서 모든 게임 오브젝트(GameObject)는 Transform 컴포넌트를 기본적으로 가진다.
- Transform은 오브젝트의 위치(Position), 회전(Rotation), 크기(Scale) 를 조작하는 역할을 한다.
- 오브젝트를 월드 좌표계(World) 또는 로컬 좌표계(Local) 기준으로 조작할 수 있다.
| 속성 | 설명 |
|---|
position | 월드 좌표 기준 오브젝트의 위치 |
localPosition | 로컬 좌표 기준 오브젝트의 위치 |
Translate(Vector3) | 로컬 좌표계 기준으로 위치 이동 |
TransformDirection(Vector3) | 로컬 좌표계를 월드 좌표로 변환 |
InverseTransformDirection(Vector3) | 월드 좌표를 로컬 좌표로 변환 |
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
private float _speed = 10.0f;
void Update()
{
if (Input.GetKey(KeyCode.W))
transform.position += Vector3.forward * Time.deltaTime * _speed;
if (Input.GetKey(KeyCode.S))
transform.position += Vector3.back * Time.deltaTime * _speed;
if (Input.GetKey(KeyCode.A))
transform.position += Vector3.left * Time.deltaTime * _speed;
if (Input.GetKey(KeyCode.D))
transform.position += Vector3.right * Time.deltaTime * _speed;
}
}
✅ 설명
transform.position += Vector3.forward * Time.deltaTime * _speed;
Vector3.forward (0, 0, 1): Z축 양수 방향으로 이동.
Time.deltaTime: 프레임 간 시간 간격을 보정하여 이동.
_speed: 이동 속도를 조절.
Vector3.left (-1, 0, 0), Vector3.right (1, 0, 0)을 이용해 좌우 이동 가능.
3. 이동 거리 계산
✅ 거리 공식
거리 = 시간 × 속력
Time.deltaTime: 이전 프레임과 현재 프레임 사이의 시간(초 단위).
_speed: 초당 이동 속도.
Time.deltaTime * _speed를 이용하면 프레임 독립적인 이동을 구현할 수 있다.
4. 월드 좌표계(World) vs 로컬 좌표계(Local)
✅ 월드 좌표계(World)
- Unity 씬의 절대적인 좌표계.
transform.position을 사용하면 월드 좌표 기준으로 이동.
✅ 로컬 좌표계(Local)
- 오브젝트가 바라보는 방향을 기준으로 한 좌표계.
transform.localPosition은 부모 오브젝트 기준으로 위치를 반환.
5. 회전(회전한 오브젝트의 이동 문제)
⚠ 문제점: position을 사용하면 방향이 고정됨
- 예제 코드에서
transform.position을 사용하면 회전(Rotation)이 적용되지 않음.
- 즉,
Vector3.forward는 항상 월드 좌표 기준 (0,0,1) 방향을 가리킴.
- 오브젝트가 회전하더라도 전진 방향이 변하지 않음.
✅ 로컬 좌표를 월드 좌표로 변환
void Update()
{
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);
}
✅ 설명
TransformDirection(Vector3.forward)을 사용하면 로컬 좌표 기준의 방향을 월드 좌표 기준으로 변환한다.
- 즉, 플레이어가 바라보는 방향을 기준으로 이동 가능해진다.
7. Translate(Vector3)를 사용한 이동
void Update()
{
if (Input.GetKey(KeyCode.W))
transform.Translate(Vector3.forward * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.S))
transform.Translate(Vector3.back * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.A))
transform.Translate(Vector3.left * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.D))
transform.Translate(Vector3.right * Time.deltaTime * _speed);
}
✅ 설명
Translate() 함수는 기본적으로 로컬 좌표계 기준으로 이동한다.
- 따라서
TransformDirection()을 사용하지 않아도 된다.
Translate(Vector3, Space.World)로 하면 월드 좌표계 기준으로 이동할 수 있다.
- 로컬 좌표를 월드 좌표로 변환.
- 예제:
transform.TransformDirection(Vector3.forward)
→ 플레이어가 회전한 경우, 현재 바라보는 방향을 기준으로 "앞"을 반환.
- 월드 좌표를 로컬 좌표로 변환.
- 예제:
transform.InverseTransformDirection(Vector3.forward)
→ 현재 오브젝트의 기준에서 "월드에서 앞"이 어디인지 계산.