pudding81 2024. 3. 4. 23:13

구형 선형 보간/ 시간에 따라 부드럽게 회전하기

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

public class Bear : MonoBehaviour
{
    [SerializeField] private Transform enemyTrans;
    [SerializeField] private float speed = 10f;

    // 목표 회전 각도
    public float targetAngle = 90f;
    // 회전 속도
    public float rotateSpeed = 1f;


    private bool isRot = false;

    void Start()
    {
       //처음 45도 회전
      //  this.transform.rotation = Quaternion.Euler(0, 45, 0);
    }

    
    void Update()
    {
        
        if (Input.GetMouseButtonDown(0))
        {
            //1. 마우스 클릭하면 15도씩 회전하기
            //this.transform.rotation *= Quaternion.Euler(0, 15, 0);

            //화면을 클릭해서 오일러각을 출력
            //  Debug.LogFormat("=> {0}", this.transform.rotation.eulerAngles);


            //2. 회전을 초기화 
            // transform.rotation = Quaternion.identity;



            /////////////////////////////////////////////////////////////////
            // 3.적의 위치로부터 현재 위치를 향하는 회전을 계산하여 적의 방향으로 회전함
            //transform.rotation = Quaternion.LookRotation(enemyTrans.position - transform.position);

            // 타겟과의 각도를 계산 
            //  Quaternion.Angle 메서드는 두 개의 쿼터니언 사이의 각도를 계산 (0~ 180도 사이값이 나옴)
            //  float angle = Quaternion.Angle(transform.rotation, enemyTrans.rotation);
            //  Debug.LogFormat("=> {0}", angle);



            /////////////////////////////////////////////////////////
            // 4. 쿼터니언을 생성하여 x 축을 중심으로 45도 회전하도록 함
            //Quaternion rotation = Quaternion.Euler(new Vector3(0, 45, 0));

            // transform.rotation = rotation;

            // 쿼터니언을 각도-축 표현으로 변환함
            //  float angle;
            //  Vector3 axis;
            //  rotation.ToAngleAxis(out angle, out axis);

            // 변환된 각도와 축을 출력함
            //  Debug.Log("Angle: " + angle);
            //  Debug.Log("Axis: " + axis);


            /////////////////////////////////////////////////////////
            // 5. y축으로 30도씩 회전 
            //transform.rotation *= Quaternion.AngleAxis(30, Vector3.up);


            //////////////////////////////////////////////////////  
            //Quaternion.FromToRotation 메서드는 두 벡터 사이의 회전을 나타내는 쿼터니언을 생성합니다.
            //6. 플레이어가 적을 향해 정렬되도록 회전을 조정
            //Vector3 fromDirection = this.transform.forward;
            //Vector3 toDirection = this.enemyTrans.forward;

            //Quaternion rotation = Quaternion.FromToRotation(fromDirection, toDirection);
            //transform.rotation = rotation;


            ///////////////////////////////////////////////////////
            //7. 회전할 방향을 정의합니다.
            // Vector3 direction = new Vector3(1, 0, 0); // x 축 방향

            // 주어진 방향을 향하는 회전을 나타내는 쿼터니언을 생성합니다.
            //Quaternion rotation = Quaternion.LookRotation(direction);

            // 생성된 쿼터니언을 현재 오브젝트의 회전으로 설정합니다.
            //transform.rotation = rotation;


            /////////////////////////////////////////////////////////
            //8.시간에 따라 보간된 회전을 원한다면?

            isRot = true;

        }

        /* if (isRot) // 선형 보간
         {
             // The step size is equal to speed times frame time.
             var step = speed * Time.deltaTime;
             // Rotate our transform a step closer to the target's.
             transform.rotation = Quaternion.RotateTowards(transform.rotation, enemyTrans.rotation, step);
         }*/


        //구형 선형 보간을 통해 보다 부드럽게 회전하고 싶다면?
        if (isRot) //구형 선형보간 ---
        {
            //Quaternion.Slerp 메서드는 두 개의 쿼터니언 간을 spherical linear interpolation(구면 선형 보간)을 사용하여 부드러운 회전을 수행합니다.
            //이 메서드는 두 쿼터니언 간의 각도를 시간에 따라 선형적으로 보간하여 새로운 쿼터니언을 생성합니다.

            // 현재 오브젝트의 회전 쿼터니언을 가져옵니다.
            Quaternion currentRotation = transform.rotation;

            // 목표 회전 쿼터니언을 구합니다.
            Quaternion targetRotation = Quaternion.Euler(0f, targetAngle, 0f);

            // 현재 회전에서 목표 회전으로 spherical linear interpolation(구면 선형 보간)을 수행하여 부드러운 회전을 구합니다.
            Quaternion newRotation = Quaternion.Slerp(currentRotation, targetRotation, rotateSpeed * Time.deltaTime);

            // 새로운 회전을 적용합니다.
            transform.rotation = newRotation;
        }


    }
}

 

 

 

 

 Unity - Scripting API: Quaternion (unity3d.com)

 

Unity - Scripting API: Quaternion

They are compact, don't suffer from gimbal lock and can easily be interpolated. Unity internally uses Quaternions to represent all rotations. They are based on complex numbers and are not easy to understand intuitively. You almost never access or modify in

docs.unity3d.com