본문 바로가기

Unity/로직 설계

[Unity] DOTween - 회전하지 않고 물체 주위 맴돌기

오늘 만들어 볼 내용

※본 글에서는 유니티 에셋 스토어의 DOTween (HOTween v2) 무료 버전을 사용합니다.

※본 글에선 DOTween 에셋의 설치 및 사용법에 대해선 다루지 않습니다.

 

 

 

 

 

 

 

 

 

 

버튼과 중심을 보여줄 스프라이트. 어딘가 익숙하다.

먼저, 스프라이트와 버튼 하나를 생성하겠습니다. 결과를 잘 보여주기 위해 버튼으로 했지만, 스프라이트나 다른 오브젝트로 만들어도 상관 없습니다.

 

 

빈 오브젝트에 버튼을 넣어준 모습

하이어라키 창에서 우클릭 - Create Empty로 빈 오브젝트를 생성한 후, 이름을 Button Object로 바꿔줬습니다. 미리 생성해둔 버튼을 Button Object 아래에 넣어 자식 오브젝트로 만들어줍니다.

 

※자식 오브젝트로 넣기 전, 인스펙터 창에서 Button Object의 Transform 컴포넌트 조정해, 반드시 위치를 0, 0, 0으로 만들어줍니다.

 

 

버튼의 위치를 살짝 띄워준 모습

Button Object의 자식인 Button의 위치를 조정해줍니다. 저는 적당히 Y축 방향으로 400정도 띄워주었습니다.

 

 

FixRotate와 RotateButton 스크립트 생성

프로젝트 창에서 우클릭 - Create - C# Script로 스크립트를 두 개 생성해줍니다. 이름은 FixRotate와 RotateButton으로 지어주었습니다.

FixRotate는 자식 오브젝트인 Button에 붙어 회전하지 않게, RotateButton은 부모 오브젝트인 Button Object에 붙여 버튼이 회전하게 만들 겁니다.

 

 

스크립트를 넣어준 모습

Button Object엔 RotateButton을, Button엔 FixRotate를 넣어줍니다.

 

 

 

각 코드의 내용은 다음과 같습니다.

 

FixRatate.cs

using UnityEngine;
using DG.Tweening;

public class FixRotate : MonoBehaviour
{
    private void Start()
    {
        //초기값을 (0, 0, 0으로 설정)
        transform.rotation = Quaternion.Euler(Vector3.zero);

        //(0, 0, 0)에서 (0, 0, 0)으로 회전 -> 움직이지 않는다.
        transform.DORotate(Vector3.zero, 0f)
            //반복(-1은 무한 반복)
            .SetLoops(-1);
    }
}

Button 오브젝트의 회전을 막아주는 함수입니다. 0초간 Transform의 Rotation 값을 (0, 0, 0) -> (0, 0, 0)으로 바꿔주는 함수를, 무한 반복하는 방법입니다. 이때 Rotation은 World 좌표계 기준이기 때문에 우리의 눈에 회전하지 않는 것으로 보이게 됩니다.

 

 

RotateButton.cs

using DG.Tweening;
using UnityEngine;

public class RotateButton : MonoBehaviour
{
    void Start()
    {
        //오브젝트를 회전시키는 DOTween, z값이 -인 이유는 시계 방향으로 회전하기 위해서며, +면 반시계 방향으로 회전한다.
        transform.DORotate(new Vector3(0, 0, -359), 2f, RotateMode.FastBeyond360)
            //일정한 속도로 변화
            .SetEase(Ease.Linear)
            //반복(-1은 무한 반복)
            .SetLoops(-1);
    }
}

아까 생성한 빈 오브젝트를 회전시키는 함수입니다. 빈 오브젝트(원 스프라이트와 위치가 같습니다)의 위치를 기준으로, 자식 오브젝트인 Button이 주위를 맴돌게 끔 만들어줍니다. 마찬가지로 무한 반복을 걸었습니다.

 

 

결과물

버튼이 동그라미를 중심으로 잘 회전합니다. 원하는 대로 잘 움직이네요!

 

 

 

 

 

 

 

 

 

if) 버튼을 단 한 번만 움직이고 싶다면?

버튼이 꼭 계속 움직이는 게 아니라, 딱 한 번만 움직일 필요도 있을 겁니다. 예를 들면, 이런 효과를 UI를 띄우는 데 사용할 수도 있겠죠.

 

 

그럴 땐 코드를 다음과 같이 바꿔주면 됩니다.

 

FixRotate.cs

using UnityEngine;
using DG.Tweening;

public class FixRotate : MonoBehaviour
{
    private void Start()
    {
        //초기값을 (0, 0, 0으로 설정)
        transform.rotation = Quaternion.Euler(Vector3.zero);

        //(0, 0, 0)에서 (0, 0, 0)으로 회전 -> 움직이지 않는다.
        transform.DORotate(Vector3.zero, 2f);
    }
}

 

RotateButton.cs

using DG.Tweening;
using UnityEngine;

public class RotateButton : MonoBehaviour
{
    void Start()
    {
        //오브젝트를 회전시키는 DOTween, z값이 -인 이유는 시계 방향으로 회전하기 위해서며, +면 반시계 방향으로 회전한다.
        transform.DORotate(new Vector3(0, 0, -359), 2f, RotateMode.FastBeyond360)
            //일정한 속도로 변화
            .SetEase(Ease.Linear);
    }
}

RotateButton에선 반복을 시켜주는 SetLoops를 제거하면 됩니다.

FixRotate의 경우, SetLoops를 제거해준 후, RotateButton과 똑같은 시간으로 설정해주면 됩니다.

 

 

결과물

그럼 이렇게 한 번만 회전하고, 이후론 멈추는 결과를 얻을 수 있습니다.

 

 

Q. FixRotate는 바꿀 필요가 없지 않나요? 오히려 효과가 덜해진 것 같은데요?

SetLoops(-1)을 설정해두면, 버튼이 회전하다가 멈춘 이후에도 Button 오브젝트의 트윈은 멈추지 않고 계속 실행됩니다. 그래서 회전 효과가 끝난 후, 불필요한 트윈이 남지 않게끔 같은 시간동안, 한 번만 움직이게끔 코드를 수정한 것입니다.

 

이 외에도 무한루프를 유지하다가 Button Object의 트윈이 끝나는 시점에 FixRotate의 트윈을 Kill하는 방법으로 같은 효과 및 성능적 이점을 얻을 수 있습니다.