Version: 2023.1
언어: 한국어
이벤트 처리
이벤트 합성 및 전송

매니퓰레이터

이벤트 로직을 UI 코드에서 분리하려면 매니퓰레이터를 사용하여 이벤트를 처리합니다. 매니퓰레이터는 UI 요소와의 사용자 상호작용을 처리하는 상태 머신입니다. 매니퓰레이터는 이벤트 콜백을 저장, 등록 및 등록 취소합니다. 매니퓰레이터는 사용자 상호작용 설정을 간소화하므로 각 콜백을 일일이 처리하지 않아도 됩니다. 이벤트를 처리하려면 UI 툴킷이 지원하는 매니퓰레이터 중 하나를 사용하거나 상속합니다.

매니퓰레이터를 생성 및 사용하려면 다음을 수행하십시오.

  1. UI 툴킷이 지원하는 매니퓰레이터 클래스에서 상속하는 전용 클래스를 정의합니다. 이 클래스는 관리하려는 특정 사용자 상호작용에 맞춘 이벤트 처리 로직을 캡슐화합니다.
  2. 클래스 내에서 마우스 클릭이나 드래그와 같은 관련 상호작용에 응답하는 메서드를 구현합니다. 이러한 메서드는 원하는 동작을 실행하는 데 필요한 정보를 캡처하고 처리합니다.
  3. 매니퓰레이터 클래스 디자인을 완료했으면 이를 인스턴스화하여 타겟 UI 요소에 연결합니다. 이렇게 하면 매니퓰레이터가 인터셉트하고 지정된 이벤트를 관리하여 UI 코드와의 명확한 분리 관계를 유지하면서 사용자 상호작용을 오케스트레이션할 수 있습니다.

지원되는 매니퓰레이터

다음 표에는 지원되는 매니퓰레이터 클래스가 나열되어 있습니다.

매니퓰레이터 다음에서 상속 설명
Manipulator 제공된 모든 매니퓰레이터의 기본 클래스입니다.
KeyboardNavigationManipulator Manipulator 기기별 입력 이벤트를 키보드를 사용하여 상위 레벨의 탐색 작업으로 변환합니다.
MouseManipulator Manipulator 마우스 입력을 처리합니다.활성화 필터 리스트가 있습니다.
ContextualMenuManipulator MouseManipulator 사용자가 오른쪽 클릭하거나 키보드의 메뉴 키를 누르면 컨텍스트 메뉴가 표시됩니다.
PointerManipulator MouseManipulator 포인터 입력을 처리합니다.활성화 필터 리스트가 있습니다.
Clickable PointerManipulator 요소에서 마우스 이벤트를 추적하고, 동일한 요소에서 포인터를 누르고 놓는 등의 클릭이 발생하는 시점을 식별합니다.

예제

다음 예는 매니퓰레이터를 사용하여 이벤트를 처리하는 방법을 보여 줍니다. 다음 작업을 수행합니다.

  • 마우스 입력을 처리하는 PointerManipulators 클래스에서 매니퓰레이터를 상속합니다.
  • activators 목록을 사용하여 매니퓰레이터를 활성화하는 조건을 지정합니다. 예를 들어 사용자가 마우스 버튼을 클릭할 때 매니퓰레이터를 활성화하려면 button 필드가 MouseButton.LeftMouse로 설정된 상태에서 ManipulatorActivationFilteractivators 목록에 추가합니다.
  • target 프로퍼티를 사용하여 매니퓰레이터가 연결된 요소에 액세스합니다.
  • RegisterCallbacksOnTargetUnregisterCallbacksFromTarget 메서드를 오버라이드하여 이벤트 콜백을 등록 및 등록 해제합니다.

ExampleDragger 매니퓰레이터 생성

다음 예시에서는 클릭 및 드래그 시 요소를 옮기는 매니퓰레이터를 생성합니다.

using UnityEngine;
using UnityEngine.UIElements;

public class ExampleDragger : PointerManipulator
{
    private Vector3 m_Start;
    protected bool m_Active;
    private int m_PointerId;
    private Vector2 m_StartSize;

    public ExampleDragger()
    {
        m_PointerId = -1;
        activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse });
        m_Active = false;
    }

    protected override void RegisterCallbacksOnTarget()
    {
        target.RegisterCallback<PointerDownEvent>(OnPointerDown);
        target.RegisterCallback<PointerMoveEvent>(OnPointerMove);
        target.RegisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected override void UnregisterCallbacksFromTarget()
    {
        target.UnregisterCallback<PointerDownEvent>(OnPointerDown);
        target.UnregisterCallback<PointerMoveEvent>(OnPointerMove);
        target.UnregisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected void OnPointerDown(PointerDownEvent e)
    {
        if (m_Active)
        {
            e.StopImmediatePropagation();
            return;
        }

        if (CanStartManipulation(e))
        {
            m_Start = e.localPosition;
            m_PointerId = e.pointerId;

            m_Active = true;
            target.CapturePointer(m_PointerId);
            e.StopPropagation();
        }
    }

    protected void OnPointerMove(PointerMoveEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId))
            return;

        Vector2 diff = e.localPosition - m_Start;

        target.style.top = target.layout.y + diff.y;
        target.style.left = target.layout.x + diff.x;

        e.StopPropagation();
    }

    protected void OnPointerUp(PointerUpEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId) || !CanStopManipulation(e))
            return;

        m_Active = false;
        target.ReleaseMouse();
        e.StopPropagation();
    }
}

ExampleResizer 매니퓰레이터 생성

다음 예시에서는 드래그 시 요소 크기를 조정하는 매니퓰레이터를 생성합니다.

using UnityEngine;
using UnityEngine.UIElements;

public class ExampleResizer : PointerManipulator
{
    private Vector3 m_Start;
    protected bool m_Active;
    private int m_PointerId;
    private Vector2 m_StartSize;
    public ExampleResizer()
    {
        m_PointerId = -1;
        activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse });
        m_Active = false;
    }

    protected override void RegisterCallbacksOnTarget()
    {
        target.RegisterCallback<PointerDownEvent>(OnPointerDown);
        target.RegisterCallback<PointerMoveEvent>(OnPointerMove);
        target.RegisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected override void UnregisterCallbacksFromTarget()
    {
        target.UnregisterCallback<PointerDownEvent>(OnPointerDown);
        target.UnregisterCallback<PointerMoveEvent>(OnPointerMove);
        target.UnregisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected void OnPointerDown(PointerDownEvent e)
    {
        if (m_Active)
        {
            e.StopImmediatePropagation();
            return;
        }

        if (CanStartManipulation(e))
        {
            m_Start = e.localPosition;
            m_StartSize = target.layout.size;
            m_PointerId = e.pointerId;
            m_Active = true;
            target.CapturePointer(m_PointerId);
            e.StopPropagation();
        }
    }

    protected void OnPointerMove(PointerMoveEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId))
            return;

        Vector2 diff = e.localPosition - m_Start;

        target.style.height = m_StartSize.y + diff.y;
        target.style.width = m_StartSize.x + diff.x;

        e.StopPropagation();
    }

    protected void OnPointerUp(PointerUpEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId) || !CanStopManipulation(e))
            return;

        m_Active = false;
        target.ReleasePointer(m_PointerId);
        m_PointerId = -1;
        e.StopPropagation();
    }
}

매니퓰레이터 추가 또는 제거

매니퓰레이터를 요소에 추가하려면 AddManipulator 메서드를 사용합니다. 요소에서 매니퓰레이터를 제거하려면 RemoveManipulator 메서드를 사용합니다.

다음 예시에서는 ExampleDraggerVisualElement에 추가 및 제거합니다.

// Create a VisualElement.
var myElement = new VisualElement();

// Add manipulators to the VisualElement.
myElement.AddManipulator(new ExampleDragger());

// Remove manipulators from the VisualElement.
myElement.RemoveManipulator<ExampleDragger>();

다음 예시에서는 ExampleResizerVisualElement에 추가합니다.

var box = new VisualElement()
{
    style =
    {
        left = 100,
        top = 100,
        width = 100,
        height = 100,
        backgroundColor = Color.red
    },
    pickingMode = PickingMode.Position,
};

box.AddManipulator(new ExampleResizer());

추가 리소스

이벤트 처리
이벤트 합성 및 전송