using System; using UnityEngine; using UnityEngine.EventSystems; /// /// Turns a pointer press/drag on a UI graphic into a normalized (x, y) position in /// [0,1] within its RectTransform (origin bottom-left). Added in code to the colour /// picker's saturation/value field and hue bar so they react to both clicking and /// dragging. The graphic on the same object must be a raycast target. /// [RequireComponent(typeof(RectTransform))] public class UiPointerSurface : MonoBehaviour, IPointerDownHandler, IDragHandler { /// Fired on press and while dragging with the normalized (x, y) in [0,1]. public event Action Picked; private RectTransform _rect; private void Awake() => _rect = (RectTransform)transform; public void OnPointerDown(PointerEventData eventData) => Report(eventData); public void OnDrag(PointerEventData eventData) => Report(eventData); private void Report(PointerEventData eventData) { // pressEventCamera is null for a Screen Space - Overlay canvas, which is the // correct camera argument there. if (!RectTransformUtility.ScreenPointToLocalPointInRectangle( _rect, eventData.position, eventData.pressEventCamera, out Vector2 local)) return; Rect r = _rect.rect; if (r.width <= 0f || r.height <= 0f) return; float x = Mathf.Clamp01((local.x - r.xMin) / r.width); float y = Mathf.Clamp01((local.y - r.yMin) / r.height); Picked?.Invoke(new Vector2(x, y)); } }