Persist HUD layout on drag-end instead of only on teardown

HUD panel positions and brush values were written only from
OnApplicationQuit/OnDestroy, which is not guaranteed in a build (Alt-F4,
process kill, crash), so layout work was lost. DraggablePanel now exposes
an IEndDragHandler callback that saves the layout the moment a panel is
dropped. Brush-value changes are detected against a disk baseline in
LateUpdate and flushed after a 0.5s debounce so per-frame slider drags
do not write every frame. The teardown save path is removed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-06-28 13:56:02 +02:00
1 parent 2a6fc163b1
commit f22ca4765f
3 files changed
+93 -23

No files matched your search

+12 -1
View File
@@ -14,7 +14,7 @@ using UnityEngine.EventSystems;
/// corners in its parent, not from a fixed top-left assumption).
/// </summary>
[RequireComponent(typeof(RectTransform))]
public class DraggablePanel : MonoBehaviour, IPointerDownHandler, IBeginDragHandler, IDragHandler
public class DraggablePanel : MonoBehaviour, IPointerDownHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
{
[Tooltip("Panel moved by the drag. Empty = this object's RectTransform.")]
public RectTransform target;
@@ -22,6 +22,10 @@ public class DraggablePanel : MonoBehaviour, IPointerDownHandler, IBeginDragHand
[Tooltip("Panel pixels (canvas units) kept on screen on every edge so it can never be lost.")]
public float keepVisible = 48f;
// Raised once when a real panel drag ends (not for gestures that began on a widget). The HUD uses
// this to persist the layout the moment a panel is dropped. Optional - left null by other users.
public System.Action Moved;
private RectTransform _area; // the panel's parent; pointer positions are tracked in its local space
private Vector2 _grabOffset;
private bool _dragging;
@@ -66,6 +70,13 @@ public class DraggablePanel : MonoBehaviour, IPointerDownHandler, IBeginDragHand
target.anchoredPosition = Clamp(local + _grabOffset);
}
public void OnEndDrag(PointerEventData eventData)
{
if (!_dragging) return; // gesture began on a widget -> not our drag, nothing moved
_dragging = false;
Moved?.Invoke();
}
// True when the press started on an interactive widget inside the panel (which then owns the gesture).
private bool StartedOnWidget(PointerEventData eventData)
{