using AibisDream; using AibisDream.FixSystem; using AibisDream.Kit; using DG.Tweening; using UnityEngine; using UnityEngine.UI; /// /// 记忆流程中的打孔带投放槽:胶片动画、投放逻辑;插入后触发 。 /// namespace AibisDream.FixSystem { public class MemoryPunchTapeSlot : MonoBehaviour { /// 当前场景中的记忆插槽(用于 MemoryProcess 等避免 FindObjectOfType)。 public static MemoryPunchTapeSlot ActiveInstance { get; private set; } public Image filmImage; public Image RoateImage; private Vector3 filmStartLocalPosition; private PunchTapeInteraction interaction; [HideInInspector] public PunchTapeItem currentPunchTapeItem; public Image punchTapeImage; public Image coverClose; public Image coverOpen; [HideInInspector] public bool isOccupied = false; [HideInInspector] public bool isLocked = false; private MemoryProcess memoryManager; [HideInInspector] public PunchTape punchTape; private void Awake() { if (ActiveInstance != null && ActiveInstance != this) { Debug.LogWarning("[MemoryPunchTapeSlot] 场景中存在多个 MemoryPunchTapeSlot,ActiveInstance 将保留最先 Awake 的实例。", this); } else { ActiveInstance = this; } } private void OnDestroy() { if (ActiveInstance == this) ActiveInstance = null; } private void OnEnable() { PunchTapeFavoritesDragEvents.DragStarted += OnFavoriteDragStarted; PunchTapeFavoritesDragEvents.DragEnded += OnFavoriteDragEnded; } private void OnDisable() { PunchTapeFavoritesDragEvents.DragStarted -= OnFavoriteDragStarted; PunchTapeFavoritesDragEvents.DragEnded -= OnFavoriteDragEnded; } private void OnFavoriteDragStarted() { if (isOccupied) return; coverOpen.enabled = true; coverClose.enabled = false; } private void OnFavoriteDragEnded() { if (isOccupied) return; coverOpen.enabled = false; coverClose.enabled = true; } private void Start() { currentPunchTapeItem = null; coverClose.enabled = true; coverOpen.enabled = false; punchTapeImage.enabled = false; filmStartLocalPosition = filmImage.rectTransform.localPosition; memoryManager = FixSystemCenter.SystemDic.Get(); if (memoryManager == null) Debug.LogWarning("[MemoryPunchTapeSlot] 未在 FixSystemCenter.SystemDic 中注册 MemoryProcess。", this); } public void SetSlotCorrect() { SetSlotLockState(true); } public bool TryAcceptDrop(PunchTapeItem item) { if (isOccupied || item == null) return false; PunchTape droppedTape = item.GetPunchTapeData(); if (droppedTape == null) return false; interaction = item.GetComponent(); currentPunchTapeItem = item; isOccupied = true; punchTapeImage.enabled = true; AudioManager.Instance.PlaySfx("event:/ActionFB/mem_insert"); StartFilmAnimation(); PunchTapeManager.Instance.CloseFavoritesPanel(); punchTapeImage.rectTransform.DOAnchorPosY(-473f, 4f) .OnComplete(() => { punchTapeImage.enabled = false; punchTapeImage.rectTransform.DOAnchorPosY(-3f, 0.1f); OnPunchTapeInsertedAfterAnimation(droppedTape); StopFilmAnimation(); }); return true; } public void ReleaseSlot() { Debug.Log("释放记忆插槽"); coverClose.enabled = false; coverOpen.enabled = true; isOccupied = false; currentPunchTapeItem = null; interaction = null; filmImage.rectTransform.localPosition = filmStartLocalPosition; } private void OnPunchTapeInsertedAfterAnimation(PunchTape tape) { punchTape = tape; coverClose.enabled = true; coverOpen.enabled = false; PlayMemory(punchTape); PunchTapeManager.Instance.RemovePunchTape(tape); } private void PlayMemory(PunchTape tape) { if (tape != null && PunchTapeManager.Instance.TryGetDefinition(tape, out var definition)) { Debug.Log("播放记忆:" + definition.MemoryResourceKey); if (memoryManager != null) memoryManager.StartCoroutine(memoryManager.SearchMemory(tape)); } } public void SetSlotLockState(bool lockState) { isLocked = lockState; } private void StartFilmAnimation() { filmImage.rectTransform.DOLocalMoveX(-494f, 1f) .SetLoops(-1, LoopType.Restart) .SetEase(Ease.Linear); RoateImage.rectTransform.DORotate(new Vector3(0, 0, 360), 1f, RotateMode.FastBeyond360) .SetLoops(-1, LoopType.Restart) .SetEase(Ease.Linear); } private void StopFilmAnimation() { filmImage.rectTransform.DOKill(); RoateImage.rectTransform.DOKill(); } } /// /// 收藏夹内打孔带拖拽生命周期事件,供插槽等监听以切换封面表现,避免 UI Item 直接引用插槽。 /// public static class PunchTapeFavoritesDragEvents { public static event System.Action DragStarted; public static event System.Action DragEnded; public static void NotifyDragStarted() => DragStarted?.Invoke(); public static void NotifyDragEnded() => DragEnded?.Invoke(); } }