[Unity] Unity local/world position
카테고리: Unity
유니티에서 게임오브젝트가 움직이는것은 아주 흔한 일입니다. 오랜만에 유니티를 하니 transform.localPosition 과 transform.position을 사용하는것이 헷갈려서 다시 정리를 하였습니다.
World Position
World Position은 말 그대로, 게임 공간상의 위치를 말합니다. 예를들어, 플레이어가 앞으로 움직어야 한다면, 플레이어는 게임 공간 상에서 위치를 변경해줘야 합니다. 그럴때 WorldPosition을 사용합니다.
차가 움직여야 할 때, 플레이어가 움직여야 할 때, 비행기가 움직여야 할 때 등등 월드 좌표 기준으로 움직여야 하는 녀석들은 전부 transform.position 을 조작하면 됩니다.
Local Position
로컬 포지션은 자기 자신의 위치를 뜻합니다. 보통 특정 오브젝트의 자식으로 속해있는 오브젝트에서 많이 사용합니다. 만약, 플레이어의 손이 움직여야 한다고 생각해 봅시다. 그렇다면 그 손은 월드 기준으로 움직이는것이 아니라, 부모 오브젝트인 플레이어 안에서 움직어야 합니다.
부모인 플레이어 오브젝트가 움직일 때, 자식으로 속한 오브젝트의 위치는 그대로가 됩니다. 그 오브젝트의 위치를 수정할때는 transform.localPosition을 사용해야 합니다.
또한, 유니티에서는 localPosition 이 기본값으로 세팅이 되어 있고, position 을 구할때는 오브젝트의 localPosition과 부모의 위치를 더하는 연산을 수행합니다.
따라서 부모가 있는 오브젝트라면 localPosition을 조작하는 것이 성능상 아주 미세하게 효율적이라고 할 수 있습니다.
예제
다음 예제는 플레이어와, 플레이어의 팔이 움직이는 코드 입니다. 플레이어가 월드 상에서 움직일때는, transform.position, 플레이어의 팔이 움직일때는 transform.loaclPosition을 사용하도록 구성하였습니다.
Player.cs
using System;
using UnityEngine;
namespace TransformStudy
{
public class Player : MonoBehaviour
{
private RightHand rightHand = null;
private LeftHand leftHand = null;
private float moveSpeed = 0.01f;
private void Awake()
{
rightHand = GetComponentInChildren<RightHand>();
leftHand = GetComponentInChildren<LeftHand>();
}
private void Update()
{
//손 움직임 제어
HandleHands();
//플레이어 움직임 제어
MovePlayer();
}
private void MovePlayer()
{
if (Input.GetKey(KeyCode.W))
MoveForward();
if (Input.GetKey(KeyCode.A))
MoveLeft();
if (Input.GetKey(KeyCode.S))
MoveBackward();
if (Input.GetKey(KeyCode.D))
MoveRight();
}
private void HandleHands()
{
//오른손 올리는 키
if (Input.GetKey(KeyCode.E))
{
rightHand.RaiseHand();
}
//오른손 내리는 키
if (Input.GetKey(KeyCode.C))
{
rightHand.PutDownHand();
}
//왼손 올리는 키
if (Input.GetKey(KeyCode.Q))
{
leftHand.RaiseHand();
}
//왼손 내리는 키
if (Input.GetKey(KeyCode.Z))
{
leftHand.PutDownHand();
}
}
private void MoveRight()
{
transform.position += new Vector3(moveSpeed, 0, 0);
}
private void MoveBackward()
{
transform.position += new Vector3(0, 0, -moveSpeed);
}
private void MoveLeft()
{
transform.position += new Vector3(-moveSpeed, 0, 0);
}
private void MoveForward()
{
transform.position += new Vector3(0, 0, moveSpeed);
}
}
}
HandBase.cs
using UnityEngine;
namespace TransformStudy
{
public class HandBase : MonoBehaviour
{
[SerializeField] protected float moveSpeed = 0.1f;
public void RaiseHand()
{
transform.localRotation *= Quaternion.Euler(-moveSpeed, 0f, 0f);
}
public void PutDownHand()
{
transform.localRotation *= Quaternion.Euler(moveSpeed, 0f, 0f);
}
}
}
댓글 남기기