191 lines
6.1 KiB
C#
191 lines
6.1 KiB
C#
using AibisDream;
|
||
using AibisDream.FixSystem;
|
||
using AibisDream.Kit;
|
||
using DG.Tweening;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
/// <summary>
|
||
/// 记忆流程中的打孔带投放槽:胶片动画、投放逻辑;插入后触发 <see cref="MemoryProcess.SearchMemory"/>。
|
||
/// </summary>
|
||
namespace AibisDream.FixSystem
|
||
{
|
||
public class MemoryPunchTapeSlot : MonoBehaviour
|
||
{
|
||
/// <summary>当前场景中的记忆插槽(用于 MemoryProcess 等避免 FindObjectOfType)。</summary>
|
||
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<MemoryProcess>();
|
||
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<PunchTapeInteraction>();
|
||
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();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 收藏夹内打孔带拖拽生命周期事件,供插槽等监听以切换封面表现,避免 UI Item 直接引用插槽。
|
||
/// </summary>
|
||
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();
|
||
}
|
||
}
|