본문 바로가기
개발더미

[개발더미][Unity] 바라보는 방향으로 회전

by 스테디코디스트 2023. 7. 29.
반응형
struct RotData
    {
        // 회전 데이터
        public float angle; // 회전 각도
        public float rotDir; // 회전 방향
    }

    void CalculateAngle(Vector3 forwardDir, Vector3 rightDir, Vector3 lookDir, out RotData data)
    {
        // 각도 계산 함수
        // 자신의 앞 방향 forwardDir과 바라봐야 할 방향 lookDir 사이의 각도를 구하는 함수
        // 1. 각 입력 벡터를 정규화하여 크기를 1로 세팅
        // 2. 두 벡터 사이의 각도를 x라고 하면 cos(x)는 자신의 forwardDir의 크기 1과 forwardDir, lookDir의 내적값의 크기 d로 구할 수 있음
        // 3. cos(x) = d/1 = d
        // 4. 우리가 구해야 할 것은 x이므로 cos의 역함수 acos을 이용해 x = acos(d)로 구할 수 있음
        // 5. 자신의 오른쪽 방향 rightDir과 lookDir를 내적했을 때의 값이 양수인지 음수인지 판단하여 회전방향을 결정

        // 각 벡터를 정규화
        Vector3 NomForwardDir = forwardDir.normalized;
        Vector3 NomLookDir = lookDir.normalized;

        float dot = Vector3.Dot(NomForwardDir, NomLookDir); // 두 벡터의 정규화된 값을 내적하여 내적값의 크기 d를 구함
        float rad = Mathf.Acos(dot); // 내적값 dot를 이용해 두 벡터 사이의 각도 rad을 구함(이 값은 라디안 값임)        

        data.angle = 180 * (rad / Mathf.PI); // 계산한 각도를 degree 값으로 변경하여 회전데이터에 저장
        data.rotDir = 1.0f; // 회전 방향값 -> 오른쪽 회전

        // 두 벡터 사이의 각도가 180도 이상인 경우 -> rightDir과의 내적값이 음수인 경우
        if (Vector3.Dot(rightDir.normalized, NomLookDir) < 0)
        {
            data.rotDir = -1.0f; // 회전 방향을 반대로 해줌 -> 왼쪽 회전
        }
    }
    
    // 코루틴으로 동작
     IEnumerator LookTarget()
    {
    	// 회전 데이터 생성
        RotData rotData;

        // 바라봐야할 방향
        Vector3 lookDir = Target.transform.position - this.transform.position;

        // 회전해야할 각도 설정
        CalculateAngle(this.transform.forward, this.transform.right, lookDir, out rotData);

        while (rotData.angle > 0)
        {
            float Tick = Time.deltaTime * 360; // 얼마나 회전할지를 나타냄

            Tick = rotData.angle > Tick ? Tick : rotData.angle;

            // 회전
            this.transform.eulerAngles += Vector3.up * Tick * rotData.rotDir;

            rotData.angle -= Tick;

            yield return null;
        }

        print("rotate end");
    }