Unity inspector에서 인터페이스 받고 싶어요.

10426 단어 UnityC#

하고 싶은 일.


이벤트를 느낌이 좋은observable의handler로 변환하기
b. observer
c.subscribe에서 처리하는 것들
나는 이 b와 c가 함께 쓴 반을 비교하고 싶다. 헤어지고 싶다!
b의 inspector에서 c를 바꿀 수 있도록!!

예컨대

  • dragevent를 n개의 손가락으로 드래그하여 끼워넣기식observable의handler
  • 로 만든다
  • observer는 두 개만 쓰면 돼요
  • 드래그, 끼우기 등 여러 가지 행동을 준비하고자 합니다.
  • 한 손가락 회전, 두 손가락 이동
  • 이동모형 또는 이동카메라
  • 행동을 늘릴 때마다 observer 부분을 쓰고 싶지 않아요!
  • uml



    (잘 썼는지 자신이 없다)

    이상 01 명


    Observer


    DragObserver.cs
    public class DragObserver : MonoBehaviour
    {
        [SerializeField] private IDragHandler handler;
        [SerializeField] private int pointerCount;
    
        [Inject] private UIDragHandler dragHandler;
    
        void Start()
        {
            dragHandler.OnDragDeltaAsObservable(pointerCount)
                .Subscribe(handler.OnDrag);
        }
    }
    

    interface


    IDragHandler.cs
    interface IDragHandler
    {
        void OnDrag(Vector2 delta);
    }
    

    이루어지다


    TransformRotator.cs
    public class TransformRotator : MonoBehaviour, IDragHandler
    {
        public void OnDrag(Vector2 delta)
        {
            Rotate();
        }
    }
    

    리얼리티



    물론 인터페이스는 inspector에 표시되지 않습니다.

    어떻게든 인터페이스 사용하고 싶어요!시나리오


    [Serialize Field]를 소유한 쪽에서 거래하는 경우


    base class


    InterfaceSerializeFieldMonoBehaviour.cs
    public class InterfaceSerializeFieldMonoBehaviour<T> : MonoBehaviour
        where T : class
    {
        [SerializeField] private MonoBehaviour implementsMonoBehaviour;
        private T _interface;
        protected T Interface
        {
            get
            {
                if (_interface == default(T))
                {
                    _interface = implementsMonoBehaviour as T;
                }
                return _interface;
            }
        }
    
        protected void OnValidate()
        {
            var t = implementsMonoBehaviour as T;
            if (t == default(T))
            {
                implementsMonoBehaviour = null;
            }
        }
    }
    
    참조: https://forum.unity3d.com/threads/c-interface-wont-show-in-inspector.383886/#post-2498475

    Observer


    DragObserver.cs
    public class DragObserver : InterfaceSerializeFieldMonoBehaviour<IDragHandler>
    {
        [SerializeField] private int pointerCount;
    
        [Inject] private UIDragHandler dragHandler;
    
        void Start()
        {
            dragHandler.OnDragDeltaAsObservable(pointerCount)
                .Subscribe(Interface.OnDrag);
        }
    }
    

    응,응



    기본적으로 설치IDragHandlerMonoBehaviour가 없으면 찔러 상처를 입을 수 없다.

    abstract로 얼버무리는 방안


    abstract class


    DragObserverBase.cs
    public abstract class DragObserverBase : MonoBehaviour
    {
        [SerializeField] private int pointerCount;
    
        [Inject] private UIDragHandler dragHandler;
    
        void Start()
        {
            dragHandler.OnDragDeltaAsObservable(pointerCount)
                .Subscribe(OnDrag);
        }
    
        protected abstract void OnDrag(Vector2 delta);
    }
    

    이루어지다


    TransformRotator.cs
    public sealed class TransformRotator : DragObserverBase
    {
        protected override void OnDrag(Vector2 delta)
        {
            Rotate(delta);
        }
    }
    

    그야말로



    둘 다 안 예뻐요.

  • 이번엔 abstract도 괜찮은데 인터페이스 때문에 못 써서 힘들어
  • 혹시 유니티 똥인가요?
  • 아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아
  • 좋은 웹페이지 즐겨찾기