유니티(Transform)

2 minute read

유니티 Transform(트랜스폼)

Scale

  • 오브젝트의 크기, 확대/축소
  • 거대한 모델이 필요하다고하면, 모델을 만들 때 처음부터 크게 만드는게 아니라 모델은 작게 만들어주고 유니티에서 Scale을 통해 크기 조절

Position

  • 오브젝트의 위치, 이동과 관련
  • 거리 = 시간 * 속력

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private float _speed = 10.0f;

    void Start()
    {
        
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.W))
            transform.position += new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime * _speed;
        if (Input.GetKey(KeyCode.S))
            transform.position -= new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime * _speed;
        if (Input.GetKey(KeyCode.D))
            transform.position += new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
        if (Input.GetKey(KeyCode.A))
            transform.position -= new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
    }
}
  • Update() : 매 프레임마다 호출되는 함수
    • W,A,S,D 키를 누를 때마다 호출되며 한 프레임동안 Time.deltatime * _speedㅁ 만큼 더 이동한다.
    • 방향(벡터) -> Vector(0.0f,0.0f,1.0f)
      • X,Y,Z 축 방향에 따라 Vector3.back, Vecotor3.left, right등과 방향이 같다.
    • 거리(스칼라) -> 시간 * 속력 = Time.deltaTime * _speed
      • 프레임간의 간격 시간 동안 _speed크기 만큼 이동

위 코드를 아래와 같이 변경 가능


   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.D))
            transform.position += Vector3.right * Time.deltaTime * _speed;
        if (Input.GetKey(KeyCode.A))
            transform.position += Vector3.left * Time.deltaTime * _speed;
    }
  • translate와 position의 차이
    1. Translate
      • transform.Translate는 오브젝트를 현재 위치에서 특정 방향으로 이동시키는 메서드입니다.
      • 상대적인 이동을 적용. 즉, 현재 위치를 기준으로 일정 거리만큼 이동
      • Translate는 상대적인 이동을 하므로, 이동 방향은 월드 좌표나 로컬 좌표계에 따라 달라질 수 있습니다. 예를 들어 transform.Translate(Vector3.forward)는 오브젝트가 바라보는 방향으로 이동하고, transform.Translate(Vector3.forward, Space.World)는 월드 좌표계를 기준으로 이동합니다.
    2. Position
      • transform.position은 오브젝트의 절대적인 위치를 설정하는 프로퍼티입니다.
      • 오브젝트의 위치를 직접적으로 지정합니다. 즉, 이동이 아니라 위치를 바꾸는 방식입니다.

위치 벡터와 방향 벡터

  • A위치 벡터에서 B벡터 만큼 더해서 C위치 벡터가 된다는 의미에 주목해 보면, B 벡터는 A위치 벡터가 C위치 벡터로 향하는 ‘방향 벡터’ 가 된다.
    void Start()
    {
        MyVector to = new MyVector(10.0f, 0.0f, 0.0f);
        MyVector from = new MyVector(5.0f, 0.0f, 0.0f);
        MyVector dir = to - from;  // (5.0f, 0.0f, 0.0f); 👉 방향의 크기(거리)는 5, 실제 방향은 오른쪽
    }
  1. 방향 벡터
    • 방향에 대한 크기(스칼라). 즉, 방향에 대한 거리를 알 수 있다.
    • magnitude
      public float magnitude { get { return Mathf.Sqrt(x * x + y * y + z * z); } }
      
        - 실제 방향을 알 수 있다.
      
    • normalized : 각 요소를 크기(magnitude)로 나눠줌.
      public MyVector normalized { get { return new MyVector(x / magnitude, y / magnitude, z / magnitude); } }
      

Rotation

  1. 회전 값을 절대적으로 설정할때 -> eulerAngles
    • 유니티에선 Transform의 rotation은 Vecotor3가 아닌 Quaternion이다.(x,y,z,w 이렇게 4개의 값이 필요) 따라서 Vecotor3 형태로 X,Y,Z 축 이렇게 3개의 회전 값으로 회전 값을 설정하고 싶다면 eulerAngles를 사용
      transform.eulerAngles = new Vector3(0.0f, _yAngle, 0.0f);  // Y 축으로 _yAngle 각도 만큼 회전한다.
      
  2. 회전 값을 상대적으로 설정할때 -> Rotate
    transform.Rotate(0.0f, Time.deltaTime * _speed, 0.0f);
    

Quaternion

  • 인수로 받은 Vecotor3를 쿼터니언으로 변환하고 이를 리턴, Euler() 함수로 Vecotor3를 쿼터니언으로 변환하면, 쿼터니언 타입은 transform.rotation에 할당 가능
    transform.rotation = Quaternion.Euler(new Vector3(0.0f, _yAngle, 0.0f));
    
  1. Quaternion.LookRotation() : 우리가 원하는 방향을 쳐다 보는 회전 값을 쿼터니언으로 리턴.
     if (Input.GetKey(KeyCode.S))
           {
               transform.rotation = Quaternion.LookRotation(Vector3.back);
           }
    
  2. Quaternion.Slerp(Vecotor3 a, Vecotor3 b, flaot t) : 회전이나 방향을 보간할 때 주로 사용(회전을 부드럽게)
     transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), Time.time * speed);
    

WASD 키로 이동하면서 자연스럽게 회전하는 코드

        if(Input.GetKey(KeyCode.W)){
            transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(Vector3.forward),0.2f);
            transform.position+=Vector3.forward * Time.deltaTime * _speed;
        }
        if(Input.GetKey(KeyCode.S)){
            transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(Vector3.back),0.2f);
            transform.position+=Vector3.back * Time.deltaTime * _speed;
        }
            
            //transform.position += transform.TransformDirection(Vector3.back * Time.deltaTime * _speed); //Vector3로 플레이어 로컬 좌표를 구한 후 월드 좌표로 변환
        if(Input.GetKey(KeyCode.A)){
            transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(Vector3.left),0.2f);
            transform.position+=Vector3.left * Time.deltaTime * _speed;
        }
            
            //transform.position += transform.TransformDirection(Vector3.left * Time.deltaTime * _speed);
        if(Input.GetKey(KeyCode.D)){
            transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(Vector3.right),0.2f);
            transform.position+=Vector3.right * Time.deltaTime * _speed;
        }

Leave a comment