ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UITookit VisualElement 드래그 움직이기
    Unity/Unity Script 2023. 12. 11. 22:48
    728x90

    Unirx를 사용하여 Unirx 설치가 필요하다.

    Unirx를 사용하지 않을 것이라면 Update() 등으로 대체해서 사용하면 된다.

     

    https://github.com/neuecc/UniRx

     

    GitHub - neuecc/UniRx: Reactive Extensions for Unity

    Reactive Extensions for Unity. Contribute to neuecc/UniRx development by creating an account on GitHub.

    github.com

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using UnityEngine;
    using UnityEngine.UIElements;
    using UniRx;
    using UniRx.Triggers;
    
    public class DragHandler
    {
        private VisualElement panel;
        private VisualElement head;
        private Button buttonHead;
    
        private bool isDragging;
        private Vector2 startPosition;
        private Vector2 gap;
        private Vector2 originPosition;
    
        private Vector2 screenSize;
    
        private Vector2 margin;
        private Vector2 absoluteMargin = new Vector2(5, 5);
        private Vector2 panelSize;
    
        public void Initialize(MonoBehaviour actor, VisualElement head, VisualElement panel, Vector2 marginByPercent, Vector2 panelSize)
        {
            this.panel = panel;
            this.head = head;
    
            originPosition = panel.transform.position;
            SetMarginByPercent(marginByPercent);
            this.panelSize = panelSize;
    
            head.RegisterCallback<PointerDownEvent>((x) =>
            {
                isDragging = true;
                startPosition = new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y);
                gap = startPosition - (Vector2)panel.transform.position;
            });
    
            SetUpdateActions(ref actor);
        }
    
        public void SetUpdateActions(ref MonoBehaviour actor)
        {
            actor.UpdateAsObservable().Where(x => screenSize.x != Screen.width || screenSize.y != Screen.height).Subscribe(y =>
            {
                ResetWindowPosition();
                SetMarginByPercent(absoluteMargin);
                screenSize = new Vector2(Screen.width, Screen.height);
            });
            actor.UpdateAsObservable().Where(ev1 => isDragging).Subscribe(ev2 =>
            {
                float x = Mathf.Clamp(Input.mousePosition.x - gap.x, 0 - margin.x, Screen.width - panelSize.x - margin.x);
                float y = Mathf.Clamp(Screen.height - Input.mousePosition.y - gap.y, 0 - margin.y, Screen.height - panelSize.y - margin.y);
                panel.transform.position = new Vector3(x, y);
            });
            actor.UpdateAsObservable().Where(x => Input.GetMouseButtonUp(0)).Subscribe(y =>
            {
                isDragging = false;
            });
        }
    
        void ResetWindowPosition()
        {
            isDragging = false;
            panel.transform.position = originPosition;
        }
    
        private void SetMarginByPercent(Vector2 marginPercent)
        {
            this.margin = new Vector2(Screen.width / 100f * marginPercent.x, Screen.height / 100f * marginPercent.y);
        }
    }

     

     

    급하게 만드느라 정리가 좀 덜 되긴 했는데, 기능은 이상 없는 듯.

    사용은 아래처럼 Start에서 Initialize()를 실행시키면 되고, marginByPercent에는 UXML상 설정되어 있는 margin값(%)과, panelSize에는 설정된 VisualElement의 사이즈 픽셀 값을 넣어주면 된다.

    panel에는 움직일 VisualElement, head에는 드래그할 수 있는 머리 부분 bar VisualElement를 넣어주면 된다.

    원래는 받아와서 사용하려고 했으나, style이나 resolvedStyle에서 제대로 값을 뱉어내지 못하는 것 같다..

     

    using UnityEngine;
    using UnityEngine.UIElements;
    
    public class UIToolkitDragTest2 : MonoBehaviour
    {
        public UIDocument doc;
    
        private VisualElement panel;
        private VisualElement head;
    
        private DragHandler dragHandler;
    
        // Start is called before the first frame update
        void Start()
        {
            dragHandler = new DragHandler();
    
            VisualElement root = doc.rootVisualElement;
            panel = root.Q<VisualElement>("Panel");
            head = panel.Q<VisualElement>("Head");
    
            dragHandler.Initialize(this, head, panel, new Vector2(5, 5), new Vector2(300, 250));
        }  
    }

     

     

    728x90

    'Unity > Unity Script' 카테고리의 다른 글

    유니티 XML 읽기/쓰기  (0) 2022.01.10

    댓글

Designed by Tistory.