개발일지/기능구현

[Unity] 투사체의 방향 전환 구현 CalculateAngle

OfficialCaox 2023. 10. 26. 02:42

테스트 코드와 전체 코드는 아래의 Git에서

 

CalculateAngle(투사체의 방향 전환) 란에서 찾아볼 수 있다.

 

https://github.com/OfficialCaox/UnityAlgorithmCollection

 

GitHub - OfficialCaox/UnityAlgorithmCollection: 손수 제작한 유니티 알고리즘 모음 리포지토리(Handcrafted Unity

손수 제작한 유니티 알고리즘 모음 리포지토리(Handcrafted Unity Toolkit)UnityAlgorithmCollection) - GitHub - OfficialCaox/UnityAlgorithmCollection: 손수 제작한 유니티 알고리즘 모음 리포지토리(Handcrafted Unity Toolkit)Un

github.com

 

본문===============================================================================

 

 

 

유니티에서 투사체(화살 총알)등을 구현하다 보니, 이 오브젝트들의 방향을 변경해줄 필요가 있다고 느꼈다.

 

 

이러한 화살 오브젝트를 1시 방향의 적에게 발사한다고 하면,

 

이런식으로 오브젝트가 날아간다...

다른 방법이 있는지는 모르겠지만 

 

유니티에서 오브젝트의 Rotation의 Z 값을 변경시켜주면 오브젝트의 기울기 ? 가 변한다.

 

따라서, 화살과 같은 투사체 오브젝트의 방향이 12시를 바라보고 있다고 가정시,

 

삼각함수중에서 아크탄젠트를 이용하면 해당 값을 알아낼 수 있다.

 

아크 탄젠트는 탄젠트의 역함수라고 보면 편하다. 일반적인 탄젠트는(삼각함수) 두 변의 크기를 기반으로각도를 찾아내는 함수이다.

 

 사용하는 예를 들어보자.

 

현재 나의 궁수 프리팹의 위치는 (0,0)

적 오브젝트 프리팹의 위치는 (1,1) => 이러한 위치 값들은 transform.position을 활용하여 알아낼 수 있다.

 

 

근데 우리가 알아내야할 값은 이 값이다.

이해하기 쉽게 기준위치를 궁수로 잡았는데, 나의 경우는 유도체의 위치를 기준으로 삼았다.

이 사진을 보면, 우리가 알아내고 싶은 값은 저기 보라색의 각도 값이다. 해당 각도가 만약 45도라고 가정하면,

Rotation의 z값을 -45로 변경해주면 된다. (해당 각을 음수값으로 변경만 해주면 됨)

Z값을 -45로 변경시.

 

그런데 일반적인 삼각함수로는 저 값을 알아낼 수가 없다.

https://ko.khanacademy.org/math/geometry/hs-geo-trig/hs-geo-solve-for-an-angle/a/inverse-trig-functions-intro

 

역삼각함수란? (개념 이해하기) | 직각삼각형과 삼각법 | Khan Academy

수학, 예술, 컴퓨터 프로그래밍, 경제, 물리학, 화학, 생물학, 의학, 금융, 역사 등을 무료로 학습해 보세요. 칸아카데미는 어디에서나 누구에게나 세계 최고의 무료 교육을 제공하는 미션을 가진

ko.khanacademy.org

를 참고하자.

 

기존의 탄젠트로는, 각과 한 변의 길이를 기반으로 나머지 변의 길이를 알아내는 것은 가능했지만, 각도는 알지 못한다.

 

따라서 역 탄젠트 값을 활용해서 코딩을 하면 다음과 같은 코드를 얻을 수 있다.

 

  public static float CalculateAngle(Vector2 currentObjectPosition, Vector2 targetObjectPosition)
    {
        // 두 점 간의 차이를 계산
        Vector2 direction = targetObjectPosition - currentObjectPosition;

        // Atan2 함수를 사용하여 아크탄젠트 값을 계산
        float radians = Mathf.Atan2(direction.x, direction.y);

        // 라디안 값을 각도로 변환
        float degrees = radians * Mathf.Rad2Deg;

        // 결과 각도가 음수인 경우 360을 더하여 양수로 변환
        if (degrees < 0)
        {
            degrees += 360;
        }
        return degrees;
    }

이 코드를 활용해서

 

transform.rotation = Quaternion.Euler(0f, 0f, -(Util.CalculateAngle(transform.position, targetObject.transform.position)));

이런식으로 변경시켜주고 싶은 오브젝트에서 호출시켜주면 된다.