회전(rotation)

·2023년 4월 8일
0

Unity

목록 보기
7/22

📌회전


transform.eulerAngles

 float _yAngle = 0.0f;
    void Update()
    {
        _yAngle += Time.deltaTime * _speed;

        transform.eulerAngles = new Vector3(0.0f, _yAngle, 0.0f);
    }
로그 출력해보니까 위의 코드에서 _yAnlgle은 더 올라가지만 Vector3의 y축은 360도 넘어가서 초기화됨

오일러 앵글을 사용할 때, 360도 넘으면 문제가 생기니까 increment를 하지마라!

360도 넘으면 어떤 문제가 생길지 만들어봄

transform.eulerAngles = new Vector3(0.0f, Time.deltaTime * 365.0f, 0.0f);

이상한 값들이 들어감

transform.Rotate

float _yAngle = 0.0f;
    void Update()
    {
        _yAngle += Time.deltaTime * _speed;

        //+- delta
        transform.Rotate(new Vector3(0.0f, Time.deltaTime * 100.0f, 0.0f));
        //transform.rotation
}

회전값을 x, y, z 축마다 넣어줘서 회전한다

여기서 Time.deltaTime * 100.0f 자리에 _yAngle 넣어봤더니 미친듯이 빨라짐
(이건 고정값으로 넣어줘야하는듯??)


📌Quaternion(transform.rotation)


  • x, y, z, w

x, y, z가 아니라 w까지 해서 rotation에 저장하는 이유가 뭘까?

짐벌락문제
잘못 회전하다 보면은 두축이 겹쳐서 회전이 먹통이 되는문제

 float _yAngle = 0.0f;
    void Update()
    {
        _yAngle += Time.deltaTime * _speed;
        transform.rotation = Quaternion.Euler(new Vector3(0.0f, _yAngle, 0.0f));
}

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); //월드기준
        } 
    }

LookRotation만 하면 빠르게 90도 돌기 때문에 Slerp를 사용해서 부드럽게 처리한다.

Slerp

a와 b를 t퍼센트 만큼 구형으로 보간하다? 0이면 완전 a이고 1이면 완전 b이다.(0~1범위)

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); //월드기준

        }
    }

조금은 부드러워진것을 볼수가 있다.


📌움직이기


방향돌리면서 움직이기(로컬좌표)

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로 되어있다
화면을 돌리고 그 기준으로 forward를 정하기 때문에 약간 이상하게 움직이는 경우도 있다

방향돌리면서 움직이기(글로벌좌표)

움직임을 로컬좌표가 아닌 글로벌좌표 기준으로 바꿔주면 이상하게 움직이는걸 보정가능하다.

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;
        }
    }

position은 내가 어디를 바라보고있든지 상관없기에 forward, back, left, right로 되어있다
화면이 돌아가는것과 움직이는게 상관없기 때문에 이상한 움직임이 생기지 않는다.


참고자료


Part3: 유니티 엔진
섹션 2.Transform(트랜스폼)

profile
개인공부저장용(하루의 기록)

0개의 댓글