강의, 책/[Unity] C#과 유니티로 만드는 MMORPG 게임 개발 시리즈

Section 2. Transform - Rotate

hye3193 2024. 1. 16. 18:46

GameObject의 절대적인 rotate 값을 변경해주기 위해서는

transform.eulerAngles = new Vector3(0.0f, 0.0f, 0.0f);

위와 같이 오일러앵글을 사용해줘야 한다

 

그런데 이 eulerAngles는 360도가 넘어갈 경우 오작동할 가능성이 있기 때문에, 값을 입력할 때 absolute value로만 입력해주고, 덧셈 뺄셈 같은 연산을 할 수는 없다

 

따라서 절대 회전값 말고 delta 값을 +- 해서 사용하려면 transform.Rotate() 함수를 사용해야 한다

transform.Rotate(new Vector3(0.0f, Time.deltaTime * 100.0f, 0.0f));

이렇게 인자로 회전시킬 값을 넣어주면 y축 기준으로 Time.deltaTime * 100.0f 만큼 회전하게 된다

 

 

그리고 transform.rotation은 Vector3가 아니라 Quaternion이라는 타입을 갖고 있는데

이는 x, y, z 뿐만 아니라 w 값까지 가지고 있는 타입이다 (짐벌 락 현상을 방지하기 위함)

 

_yAngles += Time.deltaTime * 100.0f;
transform.rotation = Quaternion.Euler(new Vector3(0.0f, _yAngle, 0.0f);

따라서 rotation 값을 직접 변경하려면 위와 같이 Quaternion.Euler 함수를 사용하면 된다

 

 

+ 플레이어가 바라보는 방향으로 회전시키기

Quaternion.LookRotation 함수를 사용하면 된다

void Update()
{
    if (Input.GetKey(KeyCode.W))
    {
        transform.rotation = Quaternion.LookRotation(Vector3.forward);
    }
    if (Input.GetKey(KeyCode.S))
    {
        transform.rotation = Quaternion.LookRotation(Vector3.back);
    }
    if (Input.GetKey(KeyCode.A))
    {
        transform.rotation = Quaternion.LookRotation(Vector3.left);
    }
    if (Input.GetKey(KeyCode.D))
    {
        transform.rotation = Quaternion.LookRotation(Vector3.right);
    }
}

위와 같이 플레이어 이동 스크립트를 작성하면, 키보드를 입력하는 방향을 바라보게 회전하게 된다

 

단, 이렇게 작성할 경우 경직된 상태로 회전하게 된다

좀 더 부드럽게 회전하는 방법은 아래와 같다

void Update()
{
    if (Input.GetKey(KeyCode.W))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), 0.2f);
    }
    if (Input.GetKey(KeyCode.S))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);
    }
    if (Input.GetKey(KeyCode.A))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);
    }
    if (Input.GetKey(KeyCode.D))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
    }
}

Quaternion.Slerp 함수를 사용하면 시작점과 끝점의 rotation을 블렌딩(세 번째 인자값으로)해준다

* 세번재 인자값은 0.2f 이런 식으로 상수를 넣기 보단 delta 값 등을 따로 지정해서 코딩할 것

 

최종적으로 키보드를 입력하는 방향을 바라보면서 해당 방향으로 나아가는 스크립트는 아래와 같이 작성하면 된다

void Update()
{
    if (Input.GetKey(KeyCode.W))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), 0.2f);
        transform.Translate(Vector3.forward * Time.deltaTime * _speed);
    }
    if (Input.GetKey(KeyCode.S))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);
        transform.Translate(Vector3.forward * Time.deltaTime * _speed);
    }
    if (Input.GetKey(KeyCode.A))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);
        transform.Translate(Vector3.forward * Time.deltaTime * _speed);
    }
    if (Input.GetKey(KeyCode.D))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
        transform.Translate(Vector3.forward * Time.deltaTime * _speed);
    }
}

바라보는 방향이 바뀌었기 때문에 Translate 함수에는 방향 벡터를 전부 forward로 넣어주면 된다

단, Slerp 함수를 사용하기 때문에 바라보는 방향이 바로 정확한 방향 벡터를 가르키지 않기 때문에

Translate 함수 대신 월드 좌표계 기준으로 이동시키는 transform.position을 사용하면 좀 더 자연스럽게 이동시킬 수 있다

 

void Update()
{
    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;
    }
    if (Input.GetKey(KeyCode.A))
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);
        transform.position += 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;
    }
}

방향도 자연스럽게 틀면서, 월드 좌표계 기준으로 WASD에 맞게 이동할 수 있게 된다