-
UITookit VisualElement 드래그 움직이기Unity/Unity Script 2023. 12. 11. 22:48728x90
Unirx를 사용하여 Unirx 설치가 필요하다.
Unirx를 사용하지 않을 것이라면 Update() 등으로 대체해서 사용하면 된다.
https://github.com/neuecc/UniRx
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