2025. 1. 10. 07:38ㆍUnity 게임 프로그래밍/Unity 이해하기
1. Transform 이동 개요
● Transform 컴포넌트는 Unity에서 객체의 위치, 회전, 크기를 제어하는 핵심 요소이다.
● Transform 이동은 비물리적 방식으로, 물리엔진의 영향을 받지 않고 충돌 검사나 물리적인 상호작용을 무시한다.
1.1 좌표 체계
① 월드 좌표 (World Coordinates): Unity 씬(scene) 전체를 기준으로 한 객체의 위치를 나타낸다.
예: (5, 1, 0)은 씬의 원점을 기준으로 X축으로 5, Y축으로 1인 지점에 위치한다.
② 로컬 좌표 (Local Coordinates): 부모 객체를 기준으로 객체의 위치를 나타낸다.
예: 부모 객체가 (5, 1, 0)에 있고 자식 객체가 부모 객체를 기준으로 (1, 0, 3)에 있다면,
자식 객체의 월드 좌표는 (6, 1, 3)
1.2 벡터 연산
① 일반 이동: 현재 위치를 나타내는 좌표에 위치 벡터를 더하는 방식으로 객체를 이동한다.
예: 객체가 (0, 0, 0)에 있을 때 (1, 1, 1) 만큼 이동하면 새로운 위치는 (1, 1, 1)
② 보간 이동: 객체를 부드럽게 이동하기 위해 사용된다.
● 선형 보간 (Linear Interpolation, Lerp): 두 점 사이를 일정한 비율로 이동할 때 사용된다.
● 구면 보간 (Spherical Interpolation, Slerp): 두 점 사이의 곡선을 따라 이동할 때 사용되며, 각도와 방향 벡터를 사용하여 보다 자연스러운 이동을 구현할 수 있다.
2. Transform 이동 구현 방법
2.1. Transform.position으로 이동
● 객체의 현재 위치를 설정하는 가장 기본적인 방법으로, 객체의 현재 위치좌표에 벡터 값을 더하거나 설정하여 이동을 구현한다.
① 월드 좌표 기준 예제 코드
void Update()
{
transform.position += new Vector3(1, 0, 0) * Time.deltaTime; // 매 프레임마다 x축으로 이동
}
② 로컬 좌표 기준 예제 코드
void Update()
{
transform.localPosition += new Vector3(1, 0, 0) * Time.deltaTime; // 부모 객체 기준으로 x축 이동
}
● transform.position: 현재 객체의 위치
● new Vector3(1, 0, 0): x축 방향으로 1만큼 이동시키는 벡터
● transform.localPosition: 부모 객체를 기준으로 이동
● Time.deltaTime: 프레임 독립성을 보장하기 위해 각 프레임 시간에 비례하여 이동 속도를 조정
③ 추천 사용처
● 월드 좌표: 전역 위치를 기준으로 이동해야 하는 경우
● 로컬 좌표: 부모 객체를 기준으로 상대적 이동이 필요한 경우
2.2. Transform.Translate로 이동
● 객체의 위치를 상대적으로 변경하는 함수
① 월드 좌표 기준 예제 코드
void Update()
{
transform.Translate(Vector3.right * Time.deltaTime, Space.World); // 월드 좌표 기준으로 전방 이동
}
② 로컬 좌표 기준 예제 코드
void Update()
{
transform.Translate(Vector3.right * Time.deltaTime, Space.Self); // 객체의 로컬 좌표 기준으로 전방 이동
}
● Vector3.forward: 객체의 전방(로컬 z축)을 나타내는 벡터
● Space.World: 월드 좌표를 기준으로 이동
● Space.Self: 로컬 좌표를 기준으로 이동
● Time.deltaTime: 프레임 독립성을 유지하기 위해 사용
● transform.Translate: 현재 객체의 위치를 기준으로 지정한 벡터만큼 상대적으로 이동
③ 추천 사용처
● 월드 좌표: 고정된 방향으로 이동할 때
● 로컬 좌표: 객체의 현재 회전 방향에 따라 이동할 때
2.3. Transform.MovePosition으로 이동
● 지정된 위치로 객체를 이동시키는 함수이며, 월드 좌표를 기준으로 객체의 위치를 설정한다.
① 예제 코드
void Update()
{
// 현재 위치에서 목표 위치로 이동
transform.position = Vector3.MoveTowards(transform.position, targetPosition.position, velocity * Time.deltaTime);
}
● Vector3.MoveTowards: 현재 위치에서 목표 위치로 일정 속도로 이동
● transform.position: 객체의 현재 위치
● new Vector3(10, 0, 0): 목표 위치
● Time.deltaTime: 이동 속도를 시간에 따라 조정하여 프레임 독립성을 유지
② 추천 사용처
● 특정 위치로의 이동이 필요한 경우
● 간단한 이동 경로를 가진 객체
2.4 Lerp와 Slerp를 활용한 Transform 이동
● Lerp는 두 점 사이의 선형 보간을 통해 이동을 구현한다.
● Slerp는 두 점 사이의 구면 보간을 통해 보다 자연스러운 곡선 이동을 구현한다.
① Lerp를 사용한 선형 이동
void Update()
{
// 현재 위치에서 목표 위치로 이동
transform.position = Vector3.Lerp(transform.position, targetPosition.position, velocityInterpolation);
}
② Slerp를 사용한 선형 이동
void Update()
{
// 현재 위치에서 목표 위치로 이동
transform.position = Vector3.Slerp(transform.position, targetPosition.position, velocityInterpolation);
}
● Vector3.Lerp: 현재 위치와 목표 위치 사이를 일정 비율로 보간
● Vector3.Slerp: 현재 위치와 목표 위치를 구면 상에서 보간하여 곡선 이동을 구현
● 0.1f: 보간 비율로, 값이 클수록 빠르게 목표 위치에 도달
③ 추천 사용처
● Lerp: 일정한 속도로 목표 위치로 이동
● Slerp: 자연스러운 곡선 이동이 필요한 경우
3. Transform 이동의 장단점
3.1 장점
① 간단한 구현: Transform.position 또는 Translate 함수 등를 사용하여 직관적으로 이동을 구현할 수 있다.
② 가벼운 연산: 물리엔진의 영향을 받지 않으므로 계산 비용이 낮다.
③ 유연성: 특정 위치로의 이동, 상대적 이동 등 다양한 방법으로 활용할 수 있다.
3.2 단점
① 충돌 및 상호작용 제한: 물리 엔진과의 통합이 이루어지지 않아 충돌 감지나 물리적 상호작용이 불가능하다.
② 예상치 못한 결과 발생: 다른 물리 기반 객체와 함께 사용 시 충돌이 무시되어 비현실적인 결과가 나올 가능성이 있다.
③ 프레임 종속성: 이동 구현 시 Time.deltaTime을 사용하지 않으면 프레임 속도(컴퓨터 사양)에 따라 이동 속도가 달라질 수 있다.
4. Transform 이동 시 주의사항
4.1 정확한 이동 계산 (Time.deltaTime 미사용 시 문제)
문제 코드
void Update()
{
transform.position += new Vector3(1, 0, 0); // 프레임에 따라 이동 속도가 달라짐
}
● 프레임 속도 의존적 이동: 프레임 속도가 높을수록 객체가 더 빠르게 이동한다.
● 결과적으로 비일관된 이동 속도: 사용 중인 컴퓨터의 사양에 따라 이동 속도가 달라지는 문제가 발생한다.
올바른 코드
void Update()
{
transform.position += new Vector3(1, 0, 0) * Time.deltaTime; // 프레임 독립성 유지
}
● 프레임 독립적 이동: 모든 프레임에서 동일한 속도로 이동하며, 결과적으로 컴퓨터 사양과 상관없이 일관된 이동 속도를 가진다.
4.2 충돌 무시 문제
문제 코드
void Update()
{
transform.position += Vector3.forward * Time.deltaTime * 10; // 빠르게 이동하며 충돌 무시
}
● 충돌 무시: 이동 경로에 있는 객체를 무시하고 그대로 통과한다.
● 물리적 상호작용 없음: 벽이나 다른 객체에 충돌하지 않고 이동하므로 비현실적인 결과를 초래할 수 있다.
해결 방법
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, transform.position + Vector3.forward, 10 * Time.deltaTime);
}
● 단계적 이동: 이동 경로에서의 충돌 감지가 가능하다.
4.3 다중 객체 관리 문제
문제 코드
void Update()
{
foreach (Transform obj in objects)
{
obj.position += new Vector3(0, 1, 0) * Time.deltaTime; // 모든 객체가 같은 위치로 이동
}
}
● 중복 이동: 모든 객체가 동일한 이동 값을 가지며, 최종적으로 동일한 위치에 놓이는 문제가 발생한다.
개선된 코드
void Update()
{
for (int i = 0; i < objects.Length; i++)
{
objects[i].position += new Vector3(0, 1, 0) * Time.deltaTime; // 개별 객체 이동
}
}
● 각 객체가 독립적으로 이동하며, 위치 중복 문제가 발생하지 않는다.
'Unity 게임 프로그래밍 > Unity 이해하기' 카테고리의 다른 글
Unity Transform 회전 (0) | 2025.03.03 |
---|---|
Unity Transform 이해하기 (2) | 2024.12.29 |