Til 17

김정환·2025년 2월 23일
post-thumbnail

1️⃣ 개인작업

애니메이션 작업

UI 호출 시에 너무 밋밋해서 이 부분을 좀 개선해보기로 했다.

  • UI들이 전반적으로 공통되게 위의 과정을 거친다.
  • 그 중에서 UI 열기, 닫기 부분의 과정을 좀 손보기로 했다.

UIBase 기능 추가

public class UIBase : MonoBehaviour
{
    [Header("UI Animations")]
    public UIAnimationSO[] OpenAnim;
    public UIAnimationSO[] CloseAnim;
    
    public AnimationSetting AnimSetting;
    public CanvasGroup CanvasGroup;
    
    public virtual void Open()
    {
        for (int i = 0; i < OpenAnim.Length; i++)
            UIManager.AnimFactory.Get(OpenAnim[i].Anim).Open(this, i);
    }

    public virtual void Close()
    {
        for (int i = 0; i < CloseAnim.Length; i++)
            UIManager.AnimFactory.Get(CloseAnim[i].Anim).Close(this, i);
    }
}
  • 기존에 단순히 SetActive(true/false)만 있던 부분을 위처럼 수정했다.
  • 인스펙터에서 할당된 애니메이션 SO를 기반으로 선택된 애니메이션을 실행한다.

애니메이션 팩토리

public enum UIAnimation
{
    Default,
    FadeInOut,
    SizeUpDown,
    MoveUpDown,
}

public class UIAnimationFactory
{
    Dictionary<UIAnimation, IUIOpenClosable> animations = new ();
    
    public UIAnimationFactory()
    {
        animations.Add(UIAnimation.Default, new UIDefaultAnimation());
        animations.Add(UIAnimation.FadeInOut, new UIFadeInOut());
        animations.Add(UIAnimation.SizeUpDown, new UISizeUpDown());
        animations.Add(UIAnimation.MoveUpDown, new UIMoveUpDown());
    }

    public IUIOpenClosable Get(UIAnimation animation)
    {
        return animations[animation];
    }
}
  • 애니메이션 팩토리를 통해서 타입에 따른 애니메이션을 실행하는 객체를 받아온다.

UI 애니메이션 예시 UIMoveUpDown

using DG.Tweening;
using UnityEngine;

public class UIMoveUpDown : IUIOpenClosable
{
    public void Open(UIBase ui, int idx)
    {
        if(idx==0)
            ui.gameObject.SetActive(true);

        Vector3 pos = ui.transform.localPosition + ui.AnimSetting.PositionOffset;
        Vector3 from = pos + ui.AnimSetting.PositionAnim;
        Vector3 to = pos;
        
        ui.transform.localPosition = from;
        
        ui.transform.DOLocalMove(to, ui.AnimSetting.Duration)
            .SetEase(ui.OpenAnim[idx].Curve);
    }

    public void Close(UIBase ui, int idx)
    {
        Vector3 pos = ui.transform.localPosition;
        Vector3 from = pos;
        Vector3 to = pos + ui.AnimSetting.PositionAnim;
        
        ui.transform.localPosition = from;
        
        var tween = 
            ui.transform.DOLocalMove(to, ui.AnimSetting.Duration)
                .SetEase(ui.CloseAnim[idx].Curve);
        
        if(idx==0)
            tween.OnComplete(() => { ui.gameObject.SetActive(false); });
    }
}
  • IUIOpenClosable 인터페이스를 상속해서 Open, Close 메서드를 원하는대로 구현한다.
    • 이번 구현은 DoTween을 활용했다.
  • 이렇게 구현해둔 애니메이션 객체를 팩토리를 통해서 불러온다.

애니메이션 프리셋 SO

[CreateAssetMenu(fileName = "UIAnimationSO", menuName = "UI Anim/UIAnimationSO")]
public class UIAnimationSO : ScriptableObject
{
    public UIAnimation Anim;
    public AnimationCurve Curve;
}
  • 원하는 애니메이션을 원하는 속도 커브에 따라 사용할 수 있도록하는 SO이다.

위처럼 이동하는 애니메이션이지만 속도감은 curve에 따라 달라지도록 만들었다.
이런 식으로 범용적으로 사용할 수 있는 일종의 프리셋을 아래와 같이 만들어두고 사용할 것이다.

애니메이션 제어용 객체

[Serializable]
public class AnimationSetting
{
    [Range(0.1f, 5f)] public float Duration = 0.5f;
    public Vector3 PositionOffset = Vector3.zero;
    public Vector3 PositionAnim = Vector3.zero;
}
  • 위의 프리셋 외에도 UI마다 애니메이션 지속시간이나 움직이는 경우 시작 위치, 움직이는 거리 등등 변수로 만들어서 사용하기 위해 만들었다.

사용


인벤토리 UI의 프리팹을 보면 표시한 구간과 같이 애니메이션 SO를 넣고, 애니메이션 세팅을 통해서 세부적으로 조절할 수 있게 해두었다.

profile
만성피로 개발자

0개의 댓글