Unity 입문 TopDown Shooting - 조준 시스템

Amberjack·2024년 1월 18일
0

Unity

목록 보기
10/44
post-custom-banner

먼저 핵심 내용에 대해 알아보자!

😭 쿼터니언(Quaternion)

  • 4차원 복소수를 이용한 회전 표현 방법이다. (X, Y, Z, W) 형태로 표현되며, Unity에서 주로 사용된다.
  • 오일러 각도(Eular angles)를 사용하여 회전을 표현할 경우 발생하는 짐벌 락(Gimbal Lock) 문제를 피할 수 있다.
  • 직접 값을 변경하거나 계산하는 대신, Unity의 내장 함수를 사용하는 것이 좋다. → 누가 4차원의 복소수를 굳이 굳이 계산할까? 🤔
    ex) Quaternion.Eular, Quaternion.LookRotation, Quaternion.Slerp 등...
  • 쿼터니언은 일반적으로 "정규화(normalized)" 되어야 하는데, Unity에서는 이를 자동으로 처리한다.

😣 아크탄젠트(ArcTangent)

  • 아크탄젠트는 삼각함수의 역함수이다. 특정 비율에 대한 각도를 계산하는 데 사용된다
  • 2차원 공간에서 점 또는 벡터에 대한 각도를 찾는 데 사용된다.
    ex) Vector (x, y)의 경우, Math.Atan2(y, x) 함수를 사용하여 벡터가 x축과 이루는 각도를 라디안으로 얻을 수 있다.
  • 아크탄젠트 함수는 사인과 코사인 함수를 이용하여 직각 삼각형에서 빗변의 각도를 계산하는 데 사용될 수 있다.
  • 이 기능은 객체가 특정 방향을 향하도록 만들거나 두 점 사이의 각도를 계산할 때 유용하다.

🏹 마우스를 따라 회전하는 무기 만들기!

Player → MainSprite 밑에 Create Empty, 이름을 WeaponPivot이라 하자.

이후 무기 스프라이트를 WeaponPivot의 하위에 넣어준다.

이후, 좌표값을 적절하게 조절하고, 크기를 캐릭터에게 맞춰준 뒤에 Order in Layer는 6으로 설정한다(Player가 5이기 때문에)

그런 다음에 WeaponPivot 하위에 Create Empty, 이름을 BulletSpawnPoint라 한다.
BulletSpawnPoint 의 X 값은 무기보다 살짝 더 앞으로 나오도록 설정한다(활에서 화살이 발사될 것이기 때문!)

이후 Entities 파일 밑에 TopDownAimRotation.cs를 생성한다.

public class TopDownAimRotation : MonoBehaviour
{
	// 무기 스프라이트
    [SerializeField] private SpriteRenderer armRenderer;
    // Weapon Pivot : 무기의 기준점. Pivot을 중심으로 무기가 회전되게 된다.
    [SerializeField] private Transform armPivot;

	// 캐릭터 스프라이트
    [SerializeField] private SpriteRenderer characterRenderer;

	// TopDownCharacterController → PlayerInputController에서 이벤트를 가져오기 위한 controller
    private TopDownCharacterController _controller;

    private void Awake()
    {
        _controller = GetComponent<TopDownCharacterController>();
    }

    // Start is called before the first frame update
    void Start()
    {
        // OnLook 구독하기
        _controller.OnLookEvent += OnAim;
    }

    // OnLook이 호출될 때마다(마우스의 방향이 바뀔 때마다)
    private void OnAim(Vector2 newAimDirection)
    {
        // 캐릭터의 몸과 화살을 회전시킨다(마우스 방향으로)
        RotateArm(newAimDirection);
    }

    private void RotateArm(Vector2 direction)
    {
        // Mathf.Atan2(direction.y, direction.x)을 수행하면, 라디안 값이 나오게 된다(Pie 값. 0 ~ 3.14...)
        // 이후, Mathf.Rad2Deg를 곱하면 앞에서 나온 라디안 값을 0 ~ 180도(각도) 사이의 값으로 바꿔준다.
        // 이를 통해 라디안 값을 각도로 변경하여 rotZ를 오일러 각도로 사용할 수 있게 된다.
        float rotZ = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;


        // rotZ의 각도의 절대값이 90도가 넘어가게 되면
        armRenderer.flipY = Mathf.Abs(rotZ) > 90f;
        // 플레이어 스프라이트를 좌우 반전 시킨다.
        characterRenderer.flipX = armRenderer.flipY;
        // 무기 또한 회전 시킨다.
        armPivot.rotation = Quaternion.Euler(0, 0, rotZ);
    }
}


이후 Player에게 TopDownAimRotation 스크립트를 추가하고, 다음과 같이 게임 오브젝트들을 스크립트에 연결시켜준다.

😎 완성!!! ▼

post-custom-banner

0개의 댓글