[Unity] Unity local/world position

Date:     Updated:

카테고리:

태그:

유니티에서 게임오브젝트가 움직이는것은 아주 흔한 일입니다. 오랜만에 유니티를 하니 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);
        }
    }
}

Unity 카테고리 내 다른 글 보러가기

댓글 남기기