Transform

개발조하·2023년 11월 22일
0

Unity

목록 보기
3/30
post-thumbnail

1. Player 설정 (이동)

public class PlayerController : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKey(KeyCode.W)) //앞
        {
            transform.position += new Vector3(0.0f, 0.0f, 1.0f);
        }
        if(Input.GetKey(KeyCode.S)) //뒤
        {
            transform.position -= new Vector3(0.0f, 0.0f, 1.0f);
        }
        if (Input.GetKey(KeyCode.A)) //좌
        {
            transform.position -= new Vector3(1.0f, 0.0f, 0.0f);
        }
        if (Input.GetKey(KeyCode.D)) //우
        {
            transform.position += new Vector3(1.0f, 0.0f, 0.0f);
        }
    }
}

Player 객체에 PlayerController.cs 붙여준다.

⚠️ 하지만 지금은 너무 빨리 움직인다!!
-> Update()는 한 프레임당 호출되는 함수로 60프레임의 게임이 돈다면 1/60초마다 포지션을 이동하는 함수가 실행되므로 매우 빠를 수밖에 없다.

💡 이전 프레임과 지금 프레임의 시간차를 구해서 동작하도록 해야함 -> Time.deltaTime;을 사용한다.

Time.deltaTime;

: 지난 프레임이 이후 경과된 시간

⚠️ 이러면 또 너무 느려지기 때문에 상수값 speed 변수를 선언하고 각 포지션 이동값에 곱해서 속도를 맞춰준다.

public class PlayerController : MonoBehaviour
{
    [SerializeField] float _speed = 10.0f;
    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.A))
        {
            transform.position -= new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.D))
        {
            transform.position += new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
        }
    }
}

[SerializeField]

: Private으로 선언된 필드를 Unity Inspector 창에서 제어할 수 있도록 해주는 기능
(Public으로 선언해도 Inspector에서 제어할 수 있지만 외부 접근도 가능하기 때문에 보안에 취약하다)

Vector3.방향

Unity에 내재되어 있는 'Vector3.방향'을 넣어서 코드의 가독성을 높이자!

public class PlayerController : MonoBehaviour
{
    [SerializeField] float _speed = 10.0f;
    void Update()
    {
        if (Input.GetKey(KeyCode.W))
        {
            //transform.position += new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime * _speed;
            transform.position += Vector3.forward * Time.deltaTime * _speed;
        }
        if(Input.GetKey(KeyCode.S))
        {
            //transform.position -= new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime * _speed;
            transform.position -= Vector3.back * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.A))
        {
            //transform.position -= new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
            transform.position -= Vector3.left * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.D))
        {
            //transform.position += new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
            transform.position += Vector3.right * Time.deltaTime * _speed;
        }
    }
}

⚠️ 만약 Player의 Transform.Rotate값을 조절해서 Player가 바라보는 방향을 바꾼 다음 현재 코드를 실행시키면, Player가 바라보는 방향이 '앞'이 되는 것이 아니라, World좌표 기준으로 '앞, 뒤, 좌, 우'가 움직여서 매우 부자연스러운 움직임이 발생한다;;

transform.TransformDirection()

: Local 좌표 -> World 좌표로

  • transform.InverseTransformDirection()
    : World 좌표 -> Local 좌표
public class PlayerController : MonoBehaviour
{
    [SerializeField] float _speed = 10.0f;
    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);
        }
    }
}

ㄴ 이렇게 오브젝트의 움직임 좌표계를 변경시켜주면 오브젝트가 바라보고 있는 방향이 '앞'이 된다.

transform.Translate()

: 오브젝트가 바라보는 방향인 Local을 기준으로 연산하기 때문에 Translate(Local좌표 기준의 연산)을 해도 된다.

public class PlayerController : MonoBehaviour
{
    [SerializeField] float _speed = 10.0f;
    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);
        }
    }
}
profile
Unity 개발자 취준생의 개발로그, Slow and steady wins the race !

0개의 댓글