using UnityEngine; using Cinemachine; using AibisDream.Kit; using AibisDream.Utility; using System.Linq; using AibisDream.Framework; using UnityEngine.EventSystems; namespace AibisDream { public class BlockPuzzleSystem : Singleton { [Header("物体索引")] // 物体索引 [SerializeField] public BlockPuzzleGrid grid; [SerializeField] private Transform shapeRoot; [SerializeField] public BlockPuzzlePanel blockPuzzlePanel; [SerializeField] private ShapeRecycleSlot shapeRecycleSlot; [Header("数据")] [SerializeField] private BlockPuzzleData puzzleData; [SerializeField] private bool initializeOnStart = true; private BlockPuzzleValidator validator; private ShapeFactory shapeFactory; // 锁定状态 public bool IsLocked { get; private set; } private void Start() { if (initializeOnStart) { Initialize(); } CameraKit.Instance?.RegisterCamera(CameraEnum.BlockPuzzle, GetComponentInChildren()); } public override void OnSingletonDestroy() { CameraKit.Instance?.UnRegisterCamera(CameraEnum.BlockPuzzle); } public void Initialize(BlockPuzzleData puzzleData) { this.puzzleData = puzzleData; ClearGame(); Initialize(); } public void Initialize() { float startTime = Time.realtimeSinceStartup; // 初始化网格 grid.Initialize(puzzleData.gridWidth, puzzleData.gridHeight, puzzleData.cellSize); // 批量预加载所有需要的BlockShapeData,避免循环中重复读取JSON文件 var shapeKeys = puzzleData.gridShapeDataInfos.Select(s => s.shapeKey).Distinct().ToArray(); var shapeDataDict = BlockPuzzleKit.LoadBlockShapeDataBatch(shapeKeys); // 初始化网格上图形 shapeFactory = new ShapeFactory(shapeRoot); foreach (var shapeData in puzzleData.gridShapeDataInfos) { // 使用预加载的数据创建形状,避免重复读取JSON if (shapeDataDict.TryGetValue(shapeData.shapeKey, out var blockShapeData)) { var shape = shapeFactory.CreateBlockShape(blockShapeData); shape.Rotate(shapeData.rotationAngle); grid.TrySnapToGrid(shape, shapeData.rootCell); shape.ShapeDragger.IsDraggable = shapeData.isDraggable; } } grid.GridVisualizer.UpdateAllCellsVisual(); // 加载验证器 validator = ResourceKit.LoadAssetSync(puzzleData.validatorName); blockPuzzlePanel.Panel.SetProgressMaxValue(validator.CollectThresholds()); // 初始化侧边栏 var deviceDatas = BlockPuzzleKit.LoadBlockShapeDataBatch(puzzleData.shapeInRack); blockPuzzlePanel.Panel.DeviceButtonDatas = deviceDatas.Values.ToArray(); // 组装事件逻辑 AssembleEventLogic(); // 初始化时验证一次 validator.Validate(grid.GetShapes()); // 确保交互状态正确 UpdateInteractionState(); } private void SubmitGameResult() { // 检查系统是否锁定 if (IsLocked) { return; } var validateResult = validator.Validate(grid.GetShapes()); // 如果验证通过, 则设置变量并弹出对话 if (validateResult.isPass) { // StorageSystem.Instance.SetValue("$block_puzzle_pass", true); // DialogController.Instance.StartDialogNode("方块拼图完成"); Debug.Log("方块拼图完成"); } } public void ClearGame() { grid.Clear(); shapeRoot.DestroyAllChildren(); // 重置锁定状态 SetLocked(false); } // --------------------- 锁定状态管理 ------------------- /// /// 设置系统锁定状态 /// /// 是否锁定 public void SetLocked(bool locked) { IsLocked = locked; UpdateInteractionState(); } /// /// 更新所有交互组件的状态 /// private void UpdateInteractionState() { // 更新所有形状的拖拽状态 if (shapeFactory != null) { shapeFactory.SetAllShapesDraggable(!IsLocked); } // 更新按钮的交互状态 if (blockPuzzlePanel != null && blockPuzzlePanel.Panel != null) { var panel = blockPuzzlePanel.Panel; if (panel.LockButton != null) { panel.LockButton.interactable = !IsLocked; } if (panel.PopUpButton != null) { panel.PopUpButton.interactable = !IsLocked; } } } public void PlayShapeAnimation(string triggerName) { // 播放Timeline TimelineCenter.Instance.PlayTimeline("维修面板"); shapeFactory.PlayShapeAnimation(triggerName); } public void LoadShapeRack() { blockPuzzlePanel.Panel.LoadBackupDevices(); } // --------------------- 维修面板同步 ------------------- private string selectedShapeName; /// /// 组装各系统之间相互逻辑 /// private void AssembleEventLogic() { // 由面板触发 blockPuzzlePanel.Panel.OnDeviceSelected += OnPanelShapeSelected; blockPuzzlePanel.Panel.OnSubmit.AddListener(SubmitGameResult); blockPuzzlePanel.Panel.OnPopUp.AddListener(PopUpShape); // 由Shape触发 shapeFactory.OnDragStart += OnShapeDragStart; shapeFactory.OnDragEnd += OnShapeDragEnd; shapeFactory.OnDragUpdate += OnShapeDragUpdate; // 由系统触发 validator.OnValidate.AddListener(blockPuzzlePanel.Panel.SetVaildState); validator.OnValidate.AddListener(blockPuzzlePanel.Panel.OnProgressChanged); } private void OnPanelShapeSelected(BlockShapeInfo shapeData) { // 在屏幕上更新选中的图形 selectedShapeName = shapeData.shapeName; blockPuzzlePanel.ShowShapeInScreen(shapeData); } public void OnShapeDragStart(IBlockShape blockShape) { grid.GridVisualizer.SetGridVisible(true); // 显示Info if (blockShape is BlockShape shape && shape.BlockShapeData.blockShapeInfo.shapeName != null) { blockPuzzlePanel.ShowShapeInScreen(shape.BlockShapeData.blockShapeInfo); EventSystem.current.SetSelectedGameObject(null); selectedShapeName = null; } // 回收抽屉高亮,半开 shapeRecycleSlot.PreRecycle(); shapeRecycleSlot.SetRecycleAvaliable(true); // 每次拿起时也要校验 validator.Validate(grid.GetShapes()); } public void OnShapeDragEnd(IBlockShape blockShape, bool isPlaced) { grid.GridVisualizer.SetGridVisible(false); // 如果放置成功,则预先检查一次 if (isPlaced) { validator.Validate(grid.GetShapes()); } } public void OnShapeDragUpdate(IBlockShape blockShape) { // 更新回收槽状态 shapeRecycleSlot.UpdateSlotState(blockShape); } public void PopUpShape() { // 检查系统是否锁定 if (IsLocked) { return; } if (selectedShapeName == null) { return; } // 弹出形状 var blockShape = shapeFactory.CreateBlockShape(selectedShapeName); shapeRecycleSlot.PopUpShape(blockShape); blockShape.GetComponent().CurrentState = DragState.Idle; // 删除按钮 blockPuzzlePanel.Panel.RemoveDeviceButton(selectedShapeName); 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; } // ---------------- 编辑器状态逻辑 ---------------- /// /// 仅加载配置项,不应用到游戏 /// public void LoadConfig() { if (BlockPuzzleKit.TryLoadBlockPuzzleData(puzzleData.puzzleName, out var blockPuzzleData)) { puzzleData = blockPuzzleData; Debug.Log("加载配置项成功"); } else { Debug.Log("加载配置项失败"); } } /// /// 将配置项应用到编辑器 /// public void ApplyConfig() { ClearGame(); shapeFactory = new ShapeFactory(shapeRoot); grid.InitializeInEditor(puzzleData.gridWidth, puzzleData.gridHeight, puzzleData.cellSize); // shapeRack.InitInEditor(puzzleData.shapeRackDataInfos); foreach (var shapeData in puzzleData.gridShapeDataInfos) { var shape = shapeFactory.CreateBlockShape(shapeData.shapeKey); shape.Rotate(shapeData.rotationAngle); grid.TrySnapToGrid(shape, shapeData.rootCell); } } public void SaveConfig() { var gridShapeDataInfos = grid.ShapeDict?.Values.ToArray(); // var shapeRackDataInfos = shapeRack.blockShapeDataList?.ToArray(); puzzleData.gridShapeDataInfos = gridShapeDataInfos; // puzzleData.shapeRackDataInfos = shapeRackDataInfos; BlockPuzzleKit.SaveBlockPuzzleData(puzzleData, puzzleData.puzzleName); } public void CreateShapeInEditor(string shapeKey) { if (shapeFactory == null) { shapeFactory = new ShapeFactory(shapeRoot); } shapeFactory.CreateBlockShape(shapeKey); } } }