feat(blockpuzzle): 重构方块交互事件并支持点击拖拽模式切换
Made-with: Cursor
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using Cinemachine;
|
||||
using AibisDream.Kit;
|
||||
using AibisDream.Utility;
|
||||
@@ -27,6 +27,9 @@ namespace AibisDream
|
||||
// 锁定状态
|
||||
public bool IsLocked { get; private set; }
|
||||
|
||||
// 缓存当前的吸附结果(由DragUpdate更新)
|
||||
private SnapResult _currentSnapResult;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (initializeOnStart)
|
||||
@@ -70,7 +73,7 @@ namespace AibisDream
|
||||
var shape = shapeFactory.CreateBlockShape(blockShapeData);
|
||||
shape.Rotate(shapeData.rotationAngle);
|
||||
grid.TrySnapToGrid(shape, shapeData.rootCell);
|
||||
shape.ShapeDragger.IsDraggable = shapeData.isDraggable;
|
||||
shape.ShapeDragger.InteractionMode = InteractionMode.Click;
|
||||
}
|
||||
}
|
||||
grid.GridVisualizer.UpdateAllCellsVisual();
|
||||
@@ -142,7 +145,7 @@ namespace AibisDream
|
||||
// 更新所有形状的拖拽状态
|
||||
if (shapeFactory != null)
|
||||
{
|
||||
shapeFactory.SetAllShapesDraggable(!IsLocked);
|
||||
shapeFactory.SetAllShapesInteractable(!IsLocked);
|
||||
}
|
||||
|
||||
// 更新按钮的交互状态
|
||||
@@ -151,7 +154,7 @@ namespace AibisDream
|
||||
var panel = blockPuzzlePanel.Panel;
|
||||
if (panel.LockButton != null)
|
||||
{
|
||||
panel.LockButton.interactable = !IsLocked;
|
||||
panel.LockButton.GetComponent<BlockSubmitHander>().SetLockedState(IsLocked);
|
||||
}
|
||||
if (panel.PopUpButton != null)
|
||||
{
|
||||
@@ -160,12 +163,15 @@ namespace AibisDream
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableDrag()
|
||||
{
|
||||
shapeFactory.SetAllShapesInteractionMode(InteractionMode.Drag);
|
||||
}
|
||||
|
||||
public void PlayShapeAnimation(string triggerName)
|
||||
{
|
||||
// 播放Timeline
|
||||
TimelineCenter.Instance.PlayTimeline("维修面板");
|
||||
|
||||
shapeFactory.PlayShapeAnimation(triggerName);
|
||||
}
|
||||
|
||||
public void LoadShapeRack()
|
||||
@@ -187,10 +193,11 @@ namespace AibisDream
|
||||
blockPuzzlePanel.Panel.OnSubmit.AddListener(SubmitGameResult);
|
||||
blockPuzzlePanel.Panel.OnPopUp.AddListener(PopUpShape);
|
||||
|
||||
// 由Shape触发
|
||||
shapeFactory.OnDragStart += OnShapeDragStart;
|
||||
shapeFactory.OnDragEnd += OnShapeDragEnd;
|
||||
shapeFactory.OnDragUpdate += OnShapeDragUpdate;
|
||||
// 由Shape触发 - 使用新的事件系统
|
||||
shapeFactory.OnDragStartDetailed += OnShapeDragStartDetailed;
|
||||
shapeFactory.OnDragEndDetailed += OnShapeDragEndDetailed;
|
||||
shapeFactory.OnDragUpdateDetailed += OnShapeDragUpdateDetailed;
|
||||
shapeFactory.OnClick += OnShapeClick;
|
||||
|
||||
// 由系统触发
|
||||
validator.OnValidate.AddListener(blockPuzzlePanel.Panel.SetVaildState);
|
||||
@@ -204,14 +211,34 @@ namespace AibisDream
|
||||
blockPuzzlePanel.ShowShapeInScreen(shapeData);
|
||||
}
|
||||
|
||||
public void OnShapeDragStart(IBlockShape blockShape)
|
||||
// 旧的事件处理方法已迁移到新的详细事件处理器
|
||||
// OnShapeDragStart -> OnShapeDragStartDetailed
|
||||
// OnShapeDragEnd -> OnShapeDragEndDetailed
|
||||
// OnShapeDragUpdate -> OnShapeDragUpdateDetailed
|
||||
|
||||
public void OnShapeClick(BlockShape blockShape)
|
||||
{
|
||||
// 点击形状
|
||||
blockPuzzlePanel.ShowShapeInScreen(blockShape.BlockShapeData.blockShapeInfo);
|
||||
}
|
||||
|
||||
#region 新的事件驱动处理器
|
||||
|
||||
private void OnShapeDragStartDetailed(object sender, DragStartEventArgs args)
|
||||
{
|
||||
var blockShape = args.Shape;
|
||||
|
||||
// 如果原本就在网格中,则先移除
|
||||
grid.TryRemoveShapeFromGrid(blockShape);
|
||||
grid.ResetPreviewGrid();
|
||||
|
||||
// 显示网格
|
||||
grid.GridVisualizer.SetGridVisible(true);
|
||||
|
||||
// 显示Info
|
||||
if (blockShape is BlockShape shape && shape.BlockShapeData.blockShapeInfo.shapeName != null)
|
||||
if (blockShape?.BlockShapeData.blockShapeInfo.shapeName != null)
|
||||
{
|
||||
blockPuzzlePanel.ShowShapeInScreen(shape.BlockShapeData.blockShapeInfo);
|
||||
blockPuzzlePanel.ShowShapeInScreen(blockShape.BlockShapeData.blockShapeInfo);
|
||||
EventSystem.current.SetSelectedGameObject(null);
|
||||
selectedShapeName = null;
|
||||
}
|
||||
@@ -224,22 +251,125 @@ namespace AibisDream
|
||||
validator.Validate(grid.GetShapes());
|
||||
}
|
||||
|
||||
public void OnShapeDragEnd(IBlockShape blockShape, bool isPlaced)
|
||||
private void OnShapeDragUpdateDetailed(object sender, DragUpdateEventArgs args)
|
||||
{
|
||||
grid.GridVisualizer.SetGridVisible(false);
|
||||
var blockShape = args.Shape;
|
||||
|
||||
// 如果放置成功,则预先检查一次
|
||||
if (isPlaced)
|
||||
{
|
||||
validator.Validate(grid.GetShapes());
|
||||
}
|
||||
}
|
||||
// 进行Snap检查并缓存结果
|
||||
_currentSnapResult = grid.CheckSnapToGrid(blockShape);
|
||||
args.CurrentSnapResult = _currentSnapResult;
|
||||
|
||||
// 在网格显示预览
|
||||
grid.ShowSnapPreview(_currentSnapResult);
|
||||
|
||||
public void OnShapeDragUpdate(IBlockShape blockShape)
|
||||
{
|
||||
// 更新回收槽状态
|
||||
shapeRecycleSlot.UpdateSlotState(blockShape);
|
||||
}
|
||||
|
||||
private void OnShapeDragEndDetailed(object sender, DragEndEventArgs args)
|
||||
{
|
||||
var blockShape = args.Shape;
|
||||
|
||||
// 隐藏网格
|
||||
grid.GridVisualizer.SetGridVisible(false);
|
||||
|
||||
// 1. 首先尝试回收
|
||||
if (TryHandleRecycle(args))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 然后尝试吸附到网格
|
||||
if (TryHandleGridSnap(args))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 都未处理,保持未处理状态
|
||||
args.IsHandled = false;
|
||||
args.ResultType = DragEndResultType.Dropped;
|
||||
|
||||
// 重置预览网格
|
||||
grid.ResetPreviewGrid();
|
||||
grid.GridVisualizer.UpdateAllCellsVisual();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理回收逻辑
|
||||
/// </summary>
|
||||
private bool TryHandleRecycle(DragEndEventArgs args)
|
||||
{
|
||||
if (shapeRecycleSlot.CurrentState != PositionState.Open)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 执行回收
|
||||
shapeRecycleSlot.RecycleShape(args.Shape);
|
||||
|
||||
// 清空屏幕并切换回LogScreen
|
||||
blockPuzzlePanel.ClearShapeInScreen();
|
||||
blockPuzzlePanel.SwitchToLogScreen();
|
||||
|
||||
// 向面板添加回收的形状
|
||||
blockPuzzlePanel.Panel.OnDeviceRecycle(args.Shape);
|
||||
|
||||
// 更新事件参数
|
||||
args.IsHandled = true;
|
||||
args.FinalState = DragState.Idle;
|
||||
args.ResultType = DragEndResultType.Recycled;
|
||||
|
||||
// 延时后进行销毁
|
||||
ActionKit.Delay(1.0f, () => {
|
||||
shapeFactory.RecycleBlockShape(args.Shape);
|
||||
}).Start(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理网格吸附逻辑
|
||||
/// </summary>
|
||||
private bool TryHandleGridSnap(DragEndEventArgs args)
|
||||
{
|
||||
// 使用缓存的snap结果或重新检测
|
||||
var snapResult = _currentSnapResult;
|
||||
if (!snapResult.canSnap)
|
||||
{
|
||||
snapResult = grid.CheckSnapToGrid(args.Shape);
|
||||
}
|
||||
|
||||
if (!snapResult.canSnap)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 执行网格吸附
|
||||
grid.ResetPreviewGrid();
|
||||
|
||||
// 设置形状位置和状态
|
||||
args.Shape.transform.position = grid.GridToWorld(snapResult.RootCell.x, snapResult.RootCell.y);
|
||||
args.Shape.transform.localScale = Vector3.one;
|
||||
|
||||
// 更新网格状态
|
||||
grid.TrySnapToGrid(args.Shape, snapResult.RootCell);
|
||||
|
||||
// 更新事件参数
|
||||
args.IsHandled = true;
|
||||
args.FinalState = DragState.Placed;
|
||||
args.ResultType = DragEndResultType.SnappedToGrid;
|
||||
|
||||
// 验证放置
|
||||
validator.Validate(grid.GetShapes());
|
||||
|
||||
// 处理Cursor
|
||||
var eventTrigger = args.Shape.GetComponent<EventTriggerEx>();
|
||||
eventTrigger?.OnPointerUp(null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void PopUpShape()
|
||||
{
|
||||
@@ -264,28 +394,6 @@ namespace AibisDream
|
||||
selectedShapeName = null;
|
||||
}
|
||||
|
||||
// --------------------- 吸附校验 ---------------------
|
||||
|
||||
public bool TrySnapToRecycleSlot(BlockShape blockShape)
|
||||
{
|
||||
// 先判断是否吸附到回收槽
|
||||
if (shapeRecycleSlot.CurrentState == PositionState.Open)
|
||||
{
|
||||
shapeRecycleSlot.RecycleShape(blockShape);
|
||||
// 清空屏幕并切换回LogScreen
|
||||
blockPuzzlePanel.ClearShapeInScreen();
|
||||
blockPuzzlePanel.SwitchToLogScreen();
|
||||
// 向面板添加回收的形状
|
||||
blockPuzzlePanel.Panel.OnDeviceRecycle(blockShape);
|
||||
// 延时后进行销毁
|
||||
ActionKit.Delay(1.0f, () => {
|
||||
shapeFactory.RecycleBlockShape(blockShape);
|
||||
}).Start(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------- 编辑器状态逻辑 ----------------
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user