using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; #if META_SDK using Oculus.Interaction; #endif namespace VRUIP { /// /// This is a script that is attached to the buttons that are used to scale a canvas. /// public class ScaleUIButton : A_ColorController, IDragHandler, IPointerDownHandler, IPointerUpHandler { [Header("Components")] [SerializeField] private Image icon; [SerializeField] private RectTransform expander; private RectTransform _buttonTransform; private RectTransform _scalableCanvas; private CanvasCorner _corner; private Vector3 _originalPosition; private Vector2 _originalSize; private LineRenderer _lineRenderer; private bool _isVR; private Vector2 _minSize; private Vector2 _maxSize; private Vector2 _expanderSize = new(1000, 1000); private BoxCollider _canvasBoxCollider; private readonly Dictionary anchors = new() { { CanvasCorner.BottomLeft, new[] { Vector2.zero, Vector2.zero } }, { CanvasCorner.TopLeft, new[] { new Vector2(0,1), new Vector2(0,1) } }, { CanvasCorner.TopRight, new[] { new Vector2(1,1), new Vector2(1,1) } }, { CanvasCorner.BottomRight, new[] { new Vector2(1,0), new Vector2(1,0) } } }; private readonly Dictionary pivots = new() { { CanvasCorner.BottomLeft, new Vector2(1, 1) }, { CanvasCorner.TopLeft, new Vector2(1, 0) }, { CanvasCorner.TopRight, new Vector2(0, 0) }, { CanvasCorner.BottomRight, new Vector2(0, 1) } }; public void Initialize(RectTransform scalableCanvas, CanvasCorner corner, int cornerIndex, Vector2 minSize, Vector2 maxSize) { _isVR = VRUIPManager.instance.IsVR; _scalableCanvas = scalableCanvas; _corner = corner; _buttonTransform = GetComponent(); var rotate = _corner == CanvasCorner.TopLeft || _corner == CanvasCorner.BottomRight; transform.localEulerAngles = rotate ? new Vector3(0, 0, 90) : Vector3.zero; #if !META_SDK _lineRenderer = VRUIPManager.instance.lineRenderer; #else _canvasBoxCollider = _scalableCanvas.GetComponent(); #endif // Set min and max size. _minSize = minSize; _maxSize = maxSize; // Set anchors _buttonTransform.anchorMin = anchors[_corner][0]; _buttonTransform.anchorMax = anchors[_corner][1]; // Set positions to corners var corners = new Vector3[4]; scalableCanvas.GetLocalCorners(corners); transform.localPosition = corners[cornerIndex]; } public void OnPointerDown(PointerEventData eventData) { _originalPosition = transform.position; _originalSize = _scalableCanvas.sizeDelta; // Set pivots Util.SetPivot(_scalableCanvas, pivots[_corner]); #if META_SDK var canvasSize = _scalableCanvas.sizeDelta; if (_canvasBoxCollider != null) { var x = _corner == CanvasCorner.BottomRight || _corner == CanvasCorner.TopRight ? canvasSize.x / 2f : -canvasSize.x / 2f; var y = _corner == CanvasCorner.TopLeft || _corner == CanvasCorner.TopRight ? canvasSize.y / 2f : -canvasSize.y / 2f; _canvasBoxCollider.center = new Vector3(x , y, _canvasBoxCollider.center.z); } #endif expander.sizeDelta = _expanderSize; } public void OnPointerUp(PointerEventData eventData) { var size = GetComponent().sizeDelta; expander.sizeDelta = size; #if META_SDK var canvasSize = _scalableCanvas.sizeDelta; _canvasBoxCollider.size = canvasSize; var x = _corner == CanvasCorner.BottomRight || _corner == CanvasCorner.TopRight ? canvasSize.x / 2f : -canvasSize.x / 2f; var y = _corner == CanvasCorner.TopLeft || _corner == CanvasCorner.TopRight ? canvasSize.y / 2f : -canvasSize.y / 2f; _canvasBoxCollider.center = new Vector3(x , y, _canvasBoxCollider.center.z); #endif } public void OnDrag(PointerEventData eventData) { Vector3 pointerEndPosition; if (_isVR) { #if META_SDK if (!VRUIPManager.instance.GetRayInteractorPosition(out pointerEndPosition)) return; #else pointerEndPosition = _lineRenderer.GetPosition(_lineRenderer.positionCount - 1); #endif } else { RectTransformUtility.ScreenPointToLocalPointInRectangle(_scalableCanvas, eventData.position, VRUIPManager.instance.mainCamera, out var mousePos); pointerEndPosition = _scalableCanvas.TransformPoint(mousePos); } float differenceX = 0; float differenceY = 0; if (_corner == CanvasCorner.TopLeft) { differenceX = _originalPosition.x - pointerEndPosition.x; differenceY = pointerEndPosition.y - _originalPosition.y; } else if (_corner == CanvasCorner.BottomRight) { differenceX = pointerEndPosition.x - _originalPosition.x; differenceY = _originalPosition.y - pointerEndPosition.y; } else if (_corner == CanvasCorner.BottomLeft) { differenceX = _originalPosition.x - pointerEndPosition.x; differenceY = _originalPosition.y - pointerEndPosition.y; } else if (_corner == CanvasCorner.TopRight) { differenceX = pointerEndPosition.x - _originalPosition.x; differenceY = pointerEndPosition.y - _originalPosition.y; } var difference = new Vector2(differenceX, differenceY); var lossyScale = _scalableCanvas.lossyScale; var pixelDifference = new Vector3(difference.x / lossyScale.x, difference.y / lossyScale.y); var newSize = _originalSize + (Vector2)pixelDifference; var adjustedSize = new Vector2(Mathf.Clamp(newSize.x, _minSize.x, _maxSize.x), Mathf.Clamp(newSize.y, _minSize.y, _maxSize.y)); #if META_SDK var expandedColliderSize = adjustedSize + new Vector2(200, 200); _canvasBoxCollider.size = expandedColliderSize; var x = _corner == CanvasCorner.BottomRight || _corner == CanvasCorner.TopRight ? expandedColliderSize.x / 2f : -expandedColliderSize.x / 2f; var y = _corner == CanvasCorner.TopLeft || _corner == CanvasCorner.TopRight ? expandedColliderSize.y / 2f : -expandedColliderSize.y / 2f; _canvasBoxCollider.center = new Vector3(x , y, _canvasBoxCollider.center.z); #endif _scalableCanvas.sizeDelta = adjustedSize; } public enum CanvasCorner { BottomLeft, TopLeft, TopRight, BottomRight } protected override void SetColors(ColorTheme theme) { icon.color = theme.secondaryColor; } } }