#nullable enable using System.Collections.Generic; using UnityEngine; namespace io.github.hatayama.uLoopMCP { public static class SimulateMouseUiOverlayState { public static bool IsActive { get; private set; } public static MouseAction Action { get; private set; } public static Vector2 CurrentPosition { get; private set; } public static Vector2? DragStartPosition { get; private set; } public static string? HitGameObjectName { get; private set; } // Screen.width/height at the time positions were recorded (Editor context may differ from Game context) public static Vector2 SourceScreenSize { get; private set; } public static float LongPressElapsed { get; private set; } // Animation request flags survive Clear() — they are consumed by the overlay in LateUpdate private static bool _pendingExpandAnimation; private static bool _pendingDissipateAnimation; private const int MAX_DRAG_WAYPOINTS = 4; private static readonly List _dragWaypoints = new List(); // Intermediate positions where DragMove stopped, forming a polyline path public static IReadOnlyList DragWaypoints => _dragWaypoints; public static void Update( MouseAction action, Vector2 currentPosition, Vector2? dragStartPosition, string? hitGameObjectName, Vector2 sourceScreenSize) { // PlayDissipateAnimation calls Clear() on normal completion, but a cancelled or stuck drag // may leave stale waypoints — defensive clear ensures a fresh start if (action == MouseAction.DragStart || action == MouseAction.Drag) { _dragWaypoints.Clear(); } IsActive = true; Action = action; CurrentPosition = currentPosition; DragStartPosition = dragStartPosition; HitGameObjectName = hitGameObjectName; SourceScreenSize = sourceScreenSize; } public static void UpdateLongPressElapsed(float elapsed) { LongPressElapsed = elapsed; } public static void UpdatePosition(Vector2 position) { CurrentPosition = position; } public static void AddWaypoint(Vector2 position) { // Keep only the most recent waypoints to bound overlay draw cost during long drags if (_dragWaypoints.Count >= MAX_DRAG_WAYPOINTS) { _dragWaypoints.RemoveAt(0); } _dragWaypoints.Add(position); } public static void RequestExpandAnimation() { _pendingExpandAnimation = true; } public static void RequestDissipateAnimation() { _pendingDissipateAnimation = true; } public static bool ConsumePendingExpandAnimation() { if (!_pendingExpandAnimation) { return false; } _pendingExpandAnimation = false; return true; } public static bool ConsumePendingDissipateAnimation() { if (!_pendingDissipateAnimation) { return false; } _pendingDissipateAnimation = false; return true; } public static void Clear() { IsActive = false; Action = default; CurrentPosition = Vector2.zero; DragStartPosition = null; HitGameObjectName = null; SourceScreenSize = Vector2.zero; LongPressElapsed = 0f; _dragWaypoints.Clear(); } } }