From 07c9a5ff50792532c3a61fb98f338dd51f517b20 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Mon, 8 Dec 2025 19:54:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B9=E5=9D=97=E6=8B=BC=E5=9B=BE=E5=AE=8C?= =?UTF-8?q?=E6=95=B4=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AssetGroups/Art Resources.asset | 5 + .../AssetGroups/Prefabs.asset | 10 + ...lockShaprEditor.cs => BlockShapeEditor.cs} | 0 ...ditor.cs.meta => BlockShapeEditor.cs.meta} | 0 Assets/Editor/MenuItem.meta | 8 + .../MenuItem/BlockPuzzleMenuItemCreator.cs | 27 + .../BlockPuzzleMenuItemCreator.cs.meta} | 2 +- Assets/Prefabs/BlockPuzzle.meta | 8 + .../BlockPuzzle/BlockPuzzleValidator.asset | 21 + .../BlockPuzzleValidator.asset.meta | 8 + Assets/Prefabs/BlockPuzzle/BlockShape.prefab | 228 ++ .../BlockPuzzle/BlockShape.prefab.meta | 7 + .../BlockPuzzle/ShapeCreateButton.prefab | 272 +++ .../BlockPuzzle/ShapeCreateButton.prefab.meta | 7 + Assets/RawResources/Art/网格拼图相关素材.meta | 8 + .../Art/网格拼图相关素材/条状.png | 3 + .../Art/网格拼图相关素材/条状.png.meta | 153 ++ .../Yarn/FP_Shitou2/Stage3_中间对话.yarn | 1 - Assets/Scenes/网格测试.unity | 1972 ++++++++++------- .../Scripts/Dialog System/BaseYarnCommand.cs | 14 - .../FixSystemNew/Clinic/ClinicYarnCommand.cs | 7 - .../EventSystemKit/WorldScrollRect.cs | 499 +++++ .../EventSystemKit/WorldScrollRect.cs.meta} | 2 +- Assets/Scripts/Framework/LogKit/FileLogger.cs | 12 +- Assets/Scripts/Framework/LogKit/LogKit.cs | 3 +- .../Framework/ResourceKit/ResourceKit.cs | 29 +- .../MiniGame/BlockPuzzle/BlockPuzzleSystem.cs | 6 +- .../MiniGame/BlockPuzzle/Class/BlockPuzzle.cs | 291 +++ .../BlockPuzzle.cs.meta} | 2 +- .../BlockPuzzle/Class/BlockPuzzleGrid.cs | 30 +- .../BlockPuzzle/Class/BlockPuzzleGridEx.cs | 96 - .../Class/BlockPuzzleGridExample.cs | 148 -- .../BlockPuzzle/Class/BlockPuzzleValidator.cs | 106 + ...e.cs.meta => BlockPuzzleValidator.cs.meta} | 2 +- .../MiniGame/BlockPuzzle/Class/BlockShape.cs | 373 +++- .../BlockPuzzle/Class/BlockShapeDragger.cs | 406 ---- .../BlockPuzzle/Class/BlockShapeRack.cs | 94 + .../BlockPuzzle/Class/BlockShapeRack.cs.meta | 11 + .../BlockPuzzle/Class/PlacementValidator.cs | 322 +-- .../BlockPuzzle/Class/ShapeCreateButton.cs | 53 + .../Class/ShapeCreateButton.cs.meta | 11 + .../BlockPuzzle/Class/ShapeDragger.cs | 35 +- .../BlockPuzzle/Class/ValidateResultLog.cs | 81 + .../Class/ValidateResultLog.cs.meta | 11 + .../Interface/IBlockPuzzleGameLogic.cs | 139 -- .../BlockPuzzle/Interface/IBlockPuzzleGrid.cs | 14 +- .../BlockPuzzle/Interface/IBlockShape.cs | 17 +- .../Interface/IBlockShapeDragger.cs | 8 +- .../Interface/IBlockShapeFactory.cs | 54 +- .../Interface/IBlockShapeFactory.cs.meta | 2 +- .../BlockPuzzle/Interface/IBlockShapeRack.cs | 22 + .../Interface/IBlockShapeRack.cs.meta | 11 + Assets/Scripts/Utility/ConstRef.cs | 8 +- .../LevelData/BlockPuzzle.meta | 8 + .../LevelData/BlockPuzzle/BlockShapeData.json | 1 + .../BlockPuzzle/BlockShapeData.json.meta | 7 + ProjectSettings/Physics2DSettings.asset | 2 +- ProjectSettings/TagManager.asset | 2 +- 58 files changed, 3598 insertions(+), 2081 deletions(-) rename Assets/Editor/Inspector/{BlockShaprEditor.cs => BlockShapeEditor.cs} (100%) rename Assets/Editor/Inspector/{BlockShaprEditor.cs.meta => BlockShapeEditor.cs.meta} (100%) create mode 100644 Assets/Editor/MenuItem.meta create mode 100644 Assets/Editor/MenuItem/BlockPuzzleMenuItemCreator.cs rename Assets/{Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs.meta => Editor/MenuItem/BlockPuzzleMenuItemCreator.cs.meta} (83%) create mode 100644 Assets/Prefabs/BlockPuzzle.meta create mode 100644 Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset create mode 100644 Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset.meta create mode 100644 Assets/Prefabs/BlockPuzzle/BlockShape.prefab create mode 100644 Assets/Prefabs/BlockPuzzle/BlockShape.prefab.meta create mode 100644 Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab create mode 100644 Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab.meta create mode 100644 Assets/RawResources/Art/网格拼图相关素材.meta create mode 100644 Assets/RawResources/Art/网格拼图相关素材/条状.png create mode 100644 Assets/RawResources/Art/网格拼图相关素材/条状.png.meta create mode 100644 Assets/Scripts/Framework/EventSystemKit/WorldScrollRect.cs rename Assets/Scripts/{MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs.meta => Framework/EventSystemKit/WorldScrollRect.cs.meta} (83%) create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzle.cs rename Assets/Scripts/MiniGame/BlockPuzzle/{Interface/IBlockPuzzleGameLogic.cs.meta => Class/BlockPuzzle.cs.meta} (83%) delete mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs delete mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridExample.cs create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleValidator.cs rename Assets/Scripts/MiniGame/BlockPuzzle/Class/{BlockPuzzleGridExample.cs.meta => BlockPuzzleValidator.cs.meta} (83%) delete mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs.meta create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/ShapeCreateButton.cs create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/ShapeCreateButton.cs.meta create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/ValidateResultLog.cs create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Class/ValidateResultLog.cs.meta delete mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Interface/IBlockPuzzleGameLogic.cs create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Interface/IBlockShapeRack.cs create mode 100644 Assets/Scripts/MiniGame/BlockPuzzle/Interface/IBlockShapeRack.cs.meta create mode 100644 Assets/StreamingAssets/LevelData/BlockPuzzle.meta create mode 100644 Assets/StreamingAssets/LevelData/BlockPuzzle/BlockShapeData.json create mode 100644 Assets/StreamingAssets/LevelData/BlockPuzzle/BlockShapeData.json.meta diff --git a/Assets/AddressableAssetsData/AssetGroups/Art Resources.asset b/Assets/AddressableAssetsData/AssetGroups/Art Resources.asset index a477477f0..43687d602 100644 --- a/Assets/AddressableAssetsData/AssetGroups/Art Resources.asset +++ b/Assets/AddressableAssetsData/AssetGroups/Art Resources.asset @@ -87,6 +87,11 @@ MonoBehaviour: m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: c0724ae6698e0454da14fa5f9e87918a + m_Address: "BlockShape/\u6761\u72B6" + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 m_ReadOnly: 0 m_Settings: {fileID: 11400000, guid: 77169ce22e430f64fb36c771815a4a7b, type: 2} m_SchemaSet: diff --git a/Assets/AddressableAssetsData/AssetGroups/Prefabs.asset b/Assets/AddressableAssetsData/AssetGroups/Prefabs.asset index 5728902ef..920f20836 100644 --- a/Assets/AddressableAssetsData/AssetGroups/Prefabs.asset +++ b/Assets/AddressableAssetsData/AssetGroups/Prefabs.asset @@ -82,6 +82,16 @@ MonoBehaviour: m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: 03e5e9a1437535042ae48b2ba034dd93 + m_Address: BlockShape + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: f0804046fd11f7a4a8f27886f2bd3cb0 + m_Address: ShapeCreateButton + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 m_ReadOnly: 0 m_Settings: {fileID: 11400000, guid: 77169ce22e430f64fb36c771815a4a7b, type: 2} m_SchemaSet: diff --git a/Assets/Editor/Inspector/BlockShaprEditor.cs b/Assets/Editor/Inspector/BlockShapeEditor.cs similarity index 100% rename from Assets/Editor/Inspector/BlockShaprEditor.cs rename to Assets/Editor/Inspector/BlockShapeEditor.cs diff --git a/Assets/Editor/Inspector/BlockShaprEditor.cs.meta b/Assets/Editor/Inspector/BlockShapeEditor.cs.meta similarity index 100% rename from Assets/Editor/Inspector/BlockShaprEditor.cs.meta rename to Assets/Editor/Inspector/BlockShapeEditor.cs.meta diff --git a/Assets/Editor/MenuItem.meta b/Assets/Editor/MenuItem.meta new file mode 100644 index 000000000..109984dae --- /dev/null +++ b/Assets/Editor/MenuItem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d6d1e89d1670e074a9f74578cfc6bc00 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/MenuItem/BlockPuzzleMenuItemCreator.cs b/Assets/Editor/MenuItem/BlockPuzzleMenuItemCreator.cs new file mode 100644 index 000000000..75a8570d0 --- /dev/null +++ b/Assets/Editor/MenuItem/BlockPuzzleMenuItemCreator.cs @@ -0,0 +1,27 @@ +using UnityEditor; +using UnityEngine; + +namespace AibisDream.SystemEditor +{ + public static class BlockPuzzleMenuItemCreator + { + private const string BLOCK_SHAPE_PREFAB_PATH = "Assets/Prefabs/BlockPuzzle/BlockShape.prefab"; + + [MenuItem("GameObject/Block Puzzle/Shape")] + public static BlockShape CreateBlockPuzzleShape() + { + var prefabAsset =AssetDatabase.LoadAssetAtPath(BLOCK_SHAPE_PREFAB_PATH); + if (prefabAsset == null) + { + throw new System.InvalidOperationException( + $"Can't create a new Block Shape: Can't find the prefab to create a Block Shape from." + ); + } + + var instantiatedPrefab = (GameObject)PrefabUtility.InstantiatePrefab(prefabAsset); + PrefabUtility.UnpackPrefabInstance(instantiatedPrefab, PrefabUnpackMode.Completely, InteractionMode.UserAction); + return instantiatedPrefab.GetComponent(); + } + } +} + diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs.meta b/Assets/Editor/MenuItem/BlockPuzzleMenuItemCreator.cs.meta similarity index 83% rename from Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs.meta rename to Assets/Editor/MenuItem/BlockPuzzleMenuItemCreator.cs.meta index 58d046e4f..2f5655a27 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs.meta +++ b/Assets/Editor/MenuItem/BlockPuzzleMenuItemCreator.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6ad01079e32d2314eb3719ead5f50ddb +guid: 71b77fc2d917b61489a45c2a36d5d049 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Prefabs/BlockPuzzle.meta b/Assets/Prefabs/BlockPuzzle.meta new file mode 100644 index 000000000..96acb0aba --- /dev/null +++ b/Assets/Prefabs/BlockPuzzle.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc64d655e8c64514986c3cb226291943 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset b/Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset new file mode 100644 index 000000000..f2b8012d6 --- /dev/null +++ b/Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8eea7264a53eb574eabe4bd65c4fa462, type: 3} + m_Name: BlockPuzzleValidator + m_EditorClassIdentifier: + baseConditions: + - name: "\u6761\u4EF61" + targetNames: + - "\u57FA\u7840\u6D4B\u8BD51" + compareSign: 0 + count: 1 + extraConditions: [] diff --git a/Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset.meta b/Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset.meta new file mode 100644 index 000000000..e7829539f --- /dev/null +++ b/Assets/Prefabs/BlockPuzzle/BlockPuzzleValidator.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5198c209e90354148ae73619dd0b4f03 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/BlockPuzzle/BlockShape.prefab b/Assets/Prefabs/BlockPuzzle/BlockShape.prefab new file mode 100644 index 000000000..d6779efc6 --- /dev/null +++ b/Assets/Prefabs/BlockPuzzle/BlockShape.prefab @@ -0,0 +1,228 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1355800832498282156 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4390508356052025844} + - component: {fileID: 1564096825049927058} + - component: {fileID: 5623161269037470069} + - component: {fileID: 1224845219232276460} + - component: {fileID: 4646419983055809048} + - component: {fileID: 4283988294842430357} + m_Layer: 0 + m_Name: BlockShape + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4390508356052025844 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355800832498282156} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 2.06, y: -0.14, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1564096825049927058 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355800832498282156} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4be33b2e5baf96447a7df0d10cb22064, type: 3} + m_Name: + m_EditorClassIdentifier: + _blockShapeData: + shapeId: 2 + shapeName: "\u57FA\u7840\u6D4B\u8BD52" + width: 2 + height: 3 + cellSize: 1 + originalPatternStr: 0,1,1;1,1,0 + spritePath: "BlockShape/\u6761\u72B6" +--- !u!212 &5623161269037470069 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355800832498282156} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: c0724ae6698e0454da14fa5f9e87918a, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 2, y: 3} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!60 &1224845219232276460 +PolygonCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355800832498282156} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.25, y: 0.16666667} + oldSize: {x: 2, y: 3} + newSize: {x: 2, y: 3} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + m_Points: + m_Paths: + - - {x: -0.5, y: 0.5} + - {x: 0.5, y: 0.5} + - {x: 0.5, y: -0.5} + - {x: 1.5, y: -0.5} + - {x: 1.5, y: 0.5} + - {x: 1.5, y: 1.5} + - {x: 0.5, y: 1.5} + - {x: 0.5, y: 2.5} + - {x: -0.5, y: 2.5} + - {x: -0.5, y: 1.5} + m_UseDelaunayMesh: 0 +--- !u!114 &4646419983055809048 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355800832498282156} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0c4fbab01ad40c2449c849cd2a8c620f, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Delegates: + - eventID: 0 + callback: + m_PersistentCalls: + m_Calls: [] + - eventID: 1 + callback: + m_PersistentCalls: + m_Calls: [] + - eventID: 2 + callback: + m_PersistentCalls: + m_Calls: [] + - eventID: 3 + callback: + m_PersistentCalls: + m_Calls: [] + - eventID: 4 + callback: + m_PersistentCalls: + m_Calls: [] + - eventID: 5 + callback: + m_PersistentCalls: + m_Calls: [] + - eventID: 14 + callback: + m_PersistentCalls: + m_Calls: [] + - eventID: 13 + callback: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &4283988294842430357 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355800832498282156} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 62aeab6b39ab40949ab3e66462c5e295, type: 3} + m_Name: + m_EditorClassIdentifier: + isDraggable: 1 + targetGrid: {fileID: 0} + snapColor: {r: 0, g: 1, b: 0, a: 0.7} + invalidColor: {r: 1, g: 0, b: 0, a: 0.7} + normalColor: {r: 1, g: 1, b: 1, a: 1} + dragScale: 1.1 diff --git a/Assets/Prefabs/BlockPuzzle/BlockShape.prefab.meta b/Assets/Prefabs/BlockPuzzle/BlockShape.prefab.meta new file mode 100644 index 000000000..f11858823 --- /dev/null +++ b/Assets/Prefabs/BlockPuzzle/BlockShape.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 03e5e9a1437535042ae48b2ba034dd93 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab b/Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab new file mode 100644 index 000000000..bbe822cd5 --- /dev/null +++ b/Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab @@ -0,0 +1,272 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1286179676683224218 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1446911278243210279} + - component: {fileID: 7196315963220379848} + - component: {fileID: 1201246540162265395} + m_Layer: 0 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1446911278243210279 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1286179676683224218} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5348072435519200876} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7196315963220379848 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1286179676683224218} + m_CullTransparentMesh: 1 +--- !u!114 &1201246540162265395 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1286179676683224218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Button + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: c7fc4cbba4b38a04c8985d4dbce12a73, type: 2} + m_sharedMaterial: {fileID: -5947736473428621296, guid: c7fc4cbba4b38a04c8985d4dbce12a73, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 24 + m_fontSizeBase: 24 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &2562226395007143204 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5348072435519200876} + - component: {fileID: 3255889528921208874} + - component: {fileID: 2606522308025224621} + - component: {fileID: 8678519470614167094} + - component: {fileID: 827712554909876233} + m_Layer: 0 + m_Name: ShapeCreateButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5348072435519200876 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2562226395007143204} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1446911278243210279} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 241.5, y: -65} + m_SizeDelta: {x: 450, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3255889528921208874 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2562226395007143204} + m_CullTransparentMesh: 1 +--- !u!114 &2606522308025224621 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2562226395007143204} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &8678519470614167094 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2562226395007143204} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2606522308025224621} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &827712554909876233 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2562226395007143204} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0f68581711be4834e9e7d77f7375d3eb, type: 3} + m_Name: + m_EditorClassIdentifier: + button: {fileID: 8678519470614167094} + text: {fileID: 1201246540162265395} diff --git a/Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab.meta b/Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab.meta new file mode 100644 index 000000000..090221888 --- /dev/null +++ b/Assets/Prefabs/BlockPuzzle/ShapeCreateButton.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f0804046fd11f7a4a8f27886f2bd3cb0 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/RawResources/Art/网格拼图相关素材.meta b/Assets/RawResources/Art/网格拼图相关素材.meta new file mode 100644 index 000000000..f577da0d5 --- /dev/null +++ b/Assets/RawResources/Art/网格拼图相关素材.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 38652f0ca09ef3a4caa55f050a1ff322 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/RawResources/Art/网格拼图相关素材/条状.png b/Assets/RawResources/Art/网格拼图相关素材/条状.png new file mode 100644 index 000000000..d4c818ff3 --- /dev/null +++ b/Assets/RawResources/Art/网格拼图相关素材/条状.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca4b0d39a9ac6190f1bbe0bc8b6aedd30692b5f22b086a37082778cb7149b7e6 +size 23037 diff --git a/Assets/RawResources/Art/网格拼图相关素材/条状.png.meta b/Assets/RawResources/Art/网格拼图相关素材/条状.png.meta new file mode 100644 index 000000000..f8823090d --- /dev/null +++ b/Assets/RawResources/Art/网格拼图相关素材/条状.png.meta @@ -0,0 +1,153 @@ +fileFormatVersion: 2 +guid: c0724ae6698e0454da14fa5f9e87918a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 9 + spritePivot: {x: 0.25, y: 0.16666667} + spritePixelsToUnits: 500 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 1537655665 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Yarn/FP_Shitou2/Stage3_中间对话.yarn b/Assets/Resources/Yarn/FP_Shitou2/Stage3_中间对话.yarn index b9b367de6..8f71ec21c 100644 --- a/Assets/Resources/Yarn/FP_Shitou2/Stage3_中间对话.yarn +++ b/Assets/Resources/Yarn/FP_Shitou2/Stage3_中间对话.yarn @@ -14,7 +14,6 @@ position: 210,-129 <> <> <> -<> //<> //<> <> diff --git a/Assets/Scenes/网格测试.unity b/Assets/Scenes/网格测试.unity index 3c7b1e6d2..ad0c14c74 100644 --- a/Assets/Scenes/网格测试.unity +++ b/Assets/Scenes/网格测试.unity @@ -123,7 +123,7 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} ---- !u!1 &281764985 +--- !u!1 &62777893 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -131,461 +131,35 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 281764986} - - component: {fileID: 281764987} + - component: {fileID: 62777894} m_Layer: 0 - m_Name: Cell_1_2 + m_Name: Sliding Area m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!4 &281764986 -Transform: +--- !u!224 &62777894 +RectTransform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 281764985} - serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 1, y: 2, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1147676901} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!212 &281764987 -SpriteRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 281764985} - m_Enabled: 0 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_Sprite: {fileID: 587689673} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_FlipX: 0 - m_FlipY: 0 - m_DrawMode: 0 - m_Size: {x: 1, y: 1} - m_AdaptiveModeThreshold: 0.5 - m_SpriteTileMode: 0 - m_WasSpriteAssigned: 1 - m_MaskInteraction: 0 - m_SpriteSortPoint: 0 ---- !u!1 &301990981 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 301990982} - - component: {fileID: 301990983} - m_Layer: 0 - m_Name: Cell_0_1 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &301990982 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 301990981} - serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1147676901} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!212 &301990983 -SpriteRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 301990981} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_Sprite: {fileID: 587689673} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_FlipX: 0 - m_FlipY: 0 - m_DrawMode: 0 - m_Size: {x: 1, y: 1} - m_AdaptiveModeThreshold: 0.5 - m_SpriteTileMode: 0 - m_WasSpriteAssigned: 1 - m_MaskInteraction: 0 - m_SpriteSortPoint: 0 ---- !u!1 &372942194 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 372942195} - - component: {fileID: 372942196} - m_Layer: 0 - m_Name: Cell_0_0 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &372942195 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 372942194} - serializedVersion: 2 + m_GameObject: {fileID: 62777893} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1147676901} + m_Children: + - {fileID: 1340148881} + m_Father: {fileID: 564105416} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!212 &372942196 -SpriteRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 372942194} - m_Enabled: 0 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_Sprite: {fileID: 587689673} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_FlipX: 0 - m_FlipY: 0 - m_DrawMode: 0 - m_Size: {x: 1, y: 1} - m_AdaptiveModeThreshold: 0.5 - m_SpriteTileMode: 0 - m_WasSpriteAssigned: 1 - m_MaskInteraction: 0 - m_SpriteSortPoint: 0 ---- !u!213 &587689673 -Sprite: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: - m_Rect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - m_Offset: {x: 0, y: 0} - m_Border: {x: 0, y: 0, z: 0, w: 0} - m_PixelsToUnits: 1 + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} m_Pivot: {x: 0.5, y: 0.5} - m_Extrude: 0 - m_IsPolygon: 0 - m_AtlasName: - m_PackingTag: - m_RenderDataKey: - 00000000000000000000000000000000: 0 - m_AtlasTags: [] - m_SpriteAtlas: {fileID: 0} - m_RD: - serializedVersion: 3 - texture: {fileID: 1427590382} - alphaTexture: {fileID: 0} - secondaryTextures: [] - m_SubMeshes: - - serializedVersion: 2 - firstByte: 0 - indexCount: 6 - topology: 0 - baseVertex: 0 - firstVertex: 0 - vertexCount: 4 - localAABB: - m_Center: {x: 0, y: 0, z: 0} - m_Extent: {x: 0, y: 0, z: 0} - m_IndexBuffer: 000001000200020001000300 - m_VertexData: - serializedVersion: 3 - m_VertexCount: 4 - m_Channels: - - stream: 0 - offset: 0 - format: 0 - dimension: 3 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 1 - offset: 0 - format: 0 - dimension: 2 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - m_DataSize: 80 - _typelessdata: 000000bf0000003f000000000000003f0000003f00000000000000bf000000bf000000000000003f000000bf00000000000000000000803f0000803f0000803f00000000000000000000803f00000000 - m_Bindpose: [] - textureRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - textureRectOffset: {x: 0, y: 0} - atlasRectOffset: {x: -1, y: -1} - settingsRaw: 64 - uvTransform: {x: 1, y: 0.5, z: 1, w: 0.5} - downscaleMultiplier: 1 - m_AtlasRD: - serializedVersion: 3 - texture: {fileID: 1427590382} - alphaTexture: {fileID: 0} - secondaryTextures: [] - m_SubMeshes: - - serializedVersion: 2 - firstByte: 0 - indexCount: 6 - topology: 0 - baseVertex: 0 - firstVertex: 0 - vertexCount: 4 - localAABB: - m_Center: {x: 0, y: 0, z: 0} - m_Extent: {x: 0, y: 0, z: 0} - m_IndexBuffer: 000001000200020001000300 - m_VertexData: - serializedVersion: 3 - m_VertexCount: 4 - m_Channels: - - stream: 0 - offset: 0 - format: 0 - dimension: 3 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 1 - offset: 0 - format: 0 - dimension: 2 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - m_DataSize: 80 - _typelessdata: 000000bf0000003f000000000000003f0000003f00000000000000bf000000bf000000000000003f000000bf00000000000000000000803f0000803f0000803f00000000000000000000803f00000000 - m_Bindpose: [] - textureRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - textureRectOffset: {x: 0, y: 0} - atlasRectOffset: {x: -1, y: -1} - settingsRaw: 64 - uvTransform: {x: 1, y: 0.5, z: 1, w: 0.5} - downscaleMultiplier: 1 - m_PhysicsShape: [] - m_Bones: [] - m_SpriteID: ---- !u!1 &785730922 +--- !u!1 &121321803 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -593,82 +167,562 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 785730923} - - component: {fileID: 785730924} + - component: {fileID: 121321804} + - component: {fileID: 121321805} m_Layer: 0 - m_Name: Cell_1_1 + m_Name: "\u7EC4\u4EF6\u6839\u8282\u70B9" m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!4 &785730923 +--- !u!4 &121321804 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 785730922} + m_GameObject: {fileID: 121321803} serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 1, y: 1, z: 0} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 1147676901} + m_Father: {fileID: 1429030511} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!212 &785730924 -SpriteRenderer: +--- !u!114 &121321805 +MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 785730922} + m_GameObject: {fileID: 121321803} m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_Sprite: {fileID: 587689673} + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4b41fe99d78fb92428bd63b641c3944c, type: 3} + m_Name: + m_EditorClassIdentifier: + shapeRoot: {fileID: 0} + scrollRect: {fileID: 0} + blockShapeDataList: [] +--- !u!1 &371269376 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 371269377} + m_Layer: 0 + m_Name: "\u529F\u80FD\u6309\u94AE" + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &371269377 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 371269376} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1199638084} + - {fileID: 1773523316} + m_Father: {fileID: 980860029} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &429452828 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 429452829} + - component: {fileID: 429452832} + - component: {fileID: 429452831} + - component: {fileID: 429452830} + - component: {fileID: 429452833} + m_Layer: 0 + m_Name: "\u6A21\u5757\u8D27\u67B6" + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &429452829 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 429452828} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 682812503} + - {fileID: 564105416} + m_Father: {fileID: 980860029} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 500, y: 0} + m_Pivot: {x: 1, y: 0.5} +--- !u!114 &429452830 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 429452828} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 1316836929} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 682812503} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 564105417} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 1 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &429452831 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 429452828} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &429452832 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 429452828} + m_CullTransparentMesh: 1 +--- !u!114 &429452833 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 429452828} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4b41fe99d78fb92428bd63b641c3944c, type: 3} + m_Name: + m_EditorClassIdentifier: + shapeRoot: {fileID: 121321804} + scrollRect: {fileID: 429452830} + blockShapeDataList: + - key: "\u57FA\u7840\u6D4B\u8BD51" + count: 1 + - key: "\u57FA\u7840\u6D4B\u8BD52" + count: 1 + - key: "\u57FA\u7840\u6D4B\u8BD53" + count: 1 +--- !u!1 &513896080 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 513896081} + - component: {fileID: 513896083} + - component: {fileID: 513896082} + m_Layer: 0 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &513896081 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 513896080} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1199638084} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &513896082 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 513896080} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} - m_FlipX: 0 - m_FlipY: 0 - m_DrawMode: 0 - m_Size: {x: 1, y: 1} - m_AdaptiveModeThreshold: 0.5 - m_SpriteTileMode: 0 - m_WasSpriteAssigned: 1 - m_MaskInteraction: 0 - m_SpriteSortPoint: 0 + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\u63D0\u4EA4" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: c7fc4cbba4b38a04c8985d4dbce12a73, type: 2} + m_sharedMaterial: {fileID: -5947736473428621296, guid: c7fc4cbba4b38a04c8985d4dbce12a73, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 24 + m_fontSizeBase: 24 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &513896083 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 513896080} + m_CullTransparentMesh: 1 +--- !u!1 &564105415 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 564105416} + - component: {fileID: 564105419} + - component: {fileID: 564105418} + - component: {fileID: 564105417} + m_Layer: 0 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &564105416 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 564105415} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 62777894} + m_Father: {fileID: 429452829} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &564105417 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 564105415} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1340148882} + m_HandleRect: {fileID: 1340148881} + m_Direction: 2 + m_Value: 0 + m_Size: 1 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &564105418 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 564105415} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &564105419 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 564105415} + m_CullTransparentMesh: 1 +--- !u!1 &682812502 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 682812503} + - component: {fileID: 682812506} + - component: {fileID: 682812505} + - component: {fileID: 682812504} + m_Layer: 0 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &682812503 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 682812502} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1316836929} + m_Father: {fileID: 429452829} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -17, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &682812504 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 682812502} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &682812505 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 682812502} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &682812506 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 682812502} + m_CullTransparentMesh: 1 --- !u!1 &791020753 GameObject: m_ObjectHideFlags: 0 @@ -823,7 +877,7 @@ MonoBehaviour: serializedVersion: 2 m_Bits: 4294967295 m_MaxRayIntersections: 0 ---- !u!1 &1147676900 +--- !u!1 &980860028 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -831,278 +885,493 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 1147676901} - - component: {fileID: 1147676902} - - component: {fileID: 1147676903} - - component: {fileID: 1147676904} - - component: {fileID: 1147676906} - - component: {fileID: 1147676907} + - component: {fileID: 980860029} + - component: {fileID: 980860032} + - component: {fileID: 980860031} + - component: {fileID: 980860030} m_Layer: 0 - m_Name: Shape + m_Name: "UI\u90E8\u5206" m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!4 &1147676901 -Transform: +--- !u!224 &980860029 +RectTransform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1147676900} - serializedVersion: 2 + m_GameObject: {fileID: 980860028} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 2.06, y: -0.14, z: 0} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 429452829} + - {fileID: 371269377} + m_Father: {fileID: 1429030511} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &980860030 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980860028} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &980860031 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980860028} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &980860032 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980860028} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 1 + m_Camera: {fileID: 791020755} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!1 &1199638083 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1199638084} + - component: {fileID: 1199638087} + - component: {fileID: 1199638086} + - component: {fileID: 1199638085} + m_Layer: 0 + m_Name: "\u63D0\u4EA4" + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1199638084 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1199638083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 372942195} - - {fileID: 301990982} - - {fileID: 2107594533} - - {fileID: 1702235238} - - {fileID: 785730923} - - {fileID: 281764986} - m_Father: {fileID: 0} + - {fileID: 513896081} + m_Father: {fileID: 371269377} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1147676902 + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 331, y: -411} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1199638085 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1147676900} + m_GameObject: {fileID: 1199638083} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 4be33b2e5baf96447a7df0d10cb22064, type: 3} + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} m_Name: m_EditorClassIdentifier: - shapeId: 0 - shapeName: "\u793A\u4F8B\u6A21\u5757" - currentRotation: 0 - width: 2 - height: 3 - cellSize: 1 - originalPatternStr: 0,1,1;1,1,0 ---- !u!212 &1147676903 -SpriteRenderer: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1199638086} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1199638086 +MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1147676900} + m_GameObject: {fileID: 1199638083} m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_Sprite: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_FlipX: 0 - m_FlipY: 0 - m_DrawMode: 0 - m_Size: {x: 1, y: 1} - m_AdaptiveModeThreshold: 0.5 - m_SpriteTileMode: 0 - m_WasSpriteAssigned: 0 - m_MaskInteraction: 0 - m_SpriteSortPoint: 0 ---- !u!60 &1147676904 -PolygonCollider2D: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1147676900} - m_Enabled: 1 - m_Density: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_ForceSendLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ForceReceiveLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ContactCaptureLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_CallbackLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_IsTrigger: 0 - m_UsedByEffector: 0 - m_UsedByComposite: 0 - m_Offset: {x: 0, y: 0} - m_SpriteTilingProperty: - border: {x: 0, y: 0, z: 0, w: 0} - pivot: {x: 0, y: 0} - oldSize: {x: 0, y: 0} - newSize: {x: 0, y: 0} - adaptiveTilingThreshold: 0 - drawMode: 0 - adaptiveTiling: 0 - m_AutoTiling: 0 - m_Points: - m_Paths: - - - {x: -0.5, y: 0.5} - - {x: 0.5, y: 0.5} - - {x: 0.5, y: -0.5} - - {x: 1.5, y: -0.5} - - {x: 1.5, y: 0.5} - - {x: 1.5, y: 1.5} - - {x: 0.5, y: 1.5} - - {x: 0.5, y: 2.5} - - {x: -0.5, y: 2.5} - - {x: -0.5, y: 1.5} - m_UseDelaunayMesh: 0 ---- !u!114 &1147676906 + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1199638087 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1199638083} + m_CullTransparentMesh: 1 +--- !u!1 &1316836928 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1316836929} + - component: {fileID: 1316836930} + m_Layer: 0 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1316836929 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1316836928} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 682812503} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0.0009186144} + m_SizeDelta: {x: 0, y: 300} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1316836930 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1147676900} + m_GameObject: {fileID: 1316836928} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0c4fbab01ad40c2449c849cd2a8c620f, type: 3} + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} m_Name: m_EditorClassIdentifier: - m_Delegates: - - eventID: 0 - callback: - m_PersistentCalls: - m_Calls: [] - - eventID: 1 - callback: - m_PersistentCalls: - m_Calls: [] - - eventID: 2 - callback: - m_PersistentCalls: - m_Calls: [] - - eventID: 3 - callback: - m_PersistentCalls: - m_Calls: [] - - eventID: 4 - callback: - m_PersistentCalls: - m_Calls: [] - - eventID: 5 - callback: - m_PersistentCalls: - m_Calls: [] - - eventID: 14 - callback: - m_PersistentCalls: - m_Calls: [] - - eventID: 13 - callback: - m_PersistentCalls: - m_Calls: [] ---- !u!114 &1147676907 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 15 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 30 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &1325372365 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1325372366} + - component: {fileID: 1325372368} + - component: {fileID: 1325372367} + m_Layer: 0 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1325372366 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1325372365} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1773523316} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1325372367 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1147676900} + m_GameObject: {fileID: 1325372365} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 62aeab6b39ab40949ab3e66462c5e295, type: 3} + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} m_Name: m_EditorClassIdentifier: - isDraggable: 1 - snapDistance: 0.5 - targetGrid: {fileID: 1928610078} - snapColor: {r: 0, g: 1, b: 0, a: 0.7} - invalidColor: {r: 1, g: 0, b: 0, a: 0.7} - normalColor: {r: 1, g: 1, b: 1, a: 1} - dragScale: 1.1 ---- !u!28 &1427590382 -Texture2D: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\u91CD\u7F6E" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: c7fc4cbba4b38a04c8985d4dbce12a73, type: 2} + m_sharedMaterial: {fileID: -5947736473428621296, guid: c7fc4cbba4b38a04c8985d4dbce12a73, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 24 + m_fontSizeBase: 24 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1325372368 +CanvasRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1325372365} + m_CullTransparentMesh: 1 +--- !u!1 &1340148880 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1340148881} + - component: {fileID: 1340148883} + - component: {fileID: 1340148882} + m_Layer: 0 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1340148881 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1340148880} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 62777894} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1340148882 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1340148880} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: - m_ImageContentsHash: - serializedVersion: 2 - Hash: 00000000000000000000000000000000 - m_ForcedFallbackFormat: 4 - m_DownscaleFallback: 0 - m_IsAlphaChannelOptional: 0 - serializedVersion: 2 - m_Width: 1 - m_Height: 1 - m_CompleteImageSize: 4 - m_MipsStripped: 0 - m_TextureFormat: 4 - m_MipCount: 1 - m_IsReadable: 1 - m_IsPreProcessed: 0 - m_IgnoreMipmapLimit: 0 - m_MipmapLimitGroupName: - m_StreamingMipmaps: 0 - m_StreamingMipmapsPriority: 0 - m_VTOnly: 0 - m_AlphaIsTransparency: 0 - m_ImageCount: 1 - m_TextureDimension: 2 - m_TextureSettings: - serializedVersion: 2 - m_FilterMode: 1 - m_Aniso: 1 - m_MipBias: 0 - m_WrapU: 0 - m_WrapV: 0 - m_WrapW: 0 - m_LightmapFormat: 0 - m_ColorSpace: 1 - m_PlatformBlob: - image data: 4 - _typelessdata: ff0000ff - m_StreamData: - serializedVersion: 2 - offset: 0 - size: 0 - path: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1340148883 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1340148880} + m_CullTransparentMesh: 1 --- !u!1 &1429030510 GameObject: m_ObjectHideFlags: 0 @@ -1112,6 +1381,8 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 1429030511} + - component: {fileID: 1429030512} + - component: {fileID: 1429030513} m_Layer: 0 m_Name: Block Puzzle Game m_TagString: Untagged @@ -1133,8 +1404,41 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1928610076} + - {fileID: 121321804} + - {fileID: 980860029} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1429030512 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1429030510} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d4ac8aed859d93147929de492c3bc62b, type: 3} + m_Name: + m_EditorClassIdentifier: + grid: {fileID: 1928610078} + shapeRoot: {fileID: 121321804} + validator: {fileID: 11400000, guid: 5198c209e90354148ae73619dd0b4f03, type: 2} + shapeRack: {fileID: 429452833} + submitButton: {fileID: 1199638085} + clearButton: {fileID: 1773523317} +--- !u!114 &1429030513 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1429030510} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c30929a4e1c9c6047b7bf080676d09be, type: 3} + m_Name: + m_EditorClassIdentifier: + fontSize: 50 --- !u!1 &1467061558 GameObject: m_ObjectHideFlags: 0 @@ -1217,7 +1521,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: isLocked: 0 ---- !u!1 &1702235237 +--- !u!1 &1773523315 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -1225,82 +1529,119 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 1702235238} - - component: {fileID: 1702235239} + - component: {fileID: 1773523316} + - component: {fileID: 1773523319} + - component: {fileID: 1773523318} + - component: {fileID: 1773523317} m_Layer: 0 - m_Name: Cell_1_0 + m_Name: "\u91CD\u7F6E" m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!4 &1702235238 -Transform: +--- !u!224 &1773523316 +RectTransform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1702235237} - serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 1, y: 0, z: 0} + m_GameObject: {fileID: 1773523315} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1147676901} + m_Children: + - {fileID: 1325372366} + m_Father: {fileID: 371269377} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!212 &1702235239 -SpriteRenderer: + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 331, y: -486} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1773523317 +MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1702235237} + m_GameObject: {fileID: 1773523315} m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_Sprite: {fileID: 587689673} + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1773523318} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1773523318 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1773523315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} - m_FlipX: 0 - m_FlipY: 0 - m_DrawMode: 0 - m_Size: {x: 1, y: 1} - m_AdaptiveModeThreshold: 0.5 - m_SpriteTileMode: 0 - m_WasSpriteAssigned: 1 - m_MaskInteraction: 0 - m_SpriteSortPoint: 0 + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1773523319 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1773523315} + m_CullTransparentMesh: 1 --- !u!1 &1928610075 GameObject: m_ObjectHideFlags: 0 @@ -1313,7 +1654,7 @@ GameObject: - component: {fileID: 1928610078} - component: {fileID: 1928610077} m_Layer: 0 - m_Name: Grid + m_Name: "\u7F51\u683C" m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -1379,90 +1720,6 @@ MonoBehaviour: emptyCellColor: {r: 0.9, g: 0.9, b: 0.9, a: 0.2} occupiedCellColor: {r: 0.2, g: 0.6, b: 1, a: 0.5} showCellStates: 1 ---- !u!1 &2107594532 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2107594533} - - component: {fileID: 2107594534} - m_Layer: 0 - m_Name: Cell_0_2 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &2107594533 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2107594532} - serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 2, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1147676901} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!212 &2107594534 -SpriteRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2107594532} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 0 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_Sprite: {fileID: 587689673} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_FlipX: 0 - m_FlipY: 0 - m_DrawMode: 0 - m_Size: {x: 1, y: 1} - m_AdaptiveModeThreshold: 0.5 - m_SpriteTileMode: 0 - m_WasSpriteAssigned: 1 - m_MaskInteraction: 0 - m_SpriteSortPoint: 0 --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 @@ -1470,4 +1727,3 @@ SceneRoots: - {fileID: 1467061559} - {fileID: 791020756} - {fileID: 1429030511} - - {fileID: 1147676901} diff --git a/Assets/Scripts/Dialog System/BaseYarnCommand.cs b/Assets/Scripts/Dialog System/BaseYarnCommand.cs index 1bf5e48b2..5152b1c89 100644 --- a/Assets/Scripts/Dialog System/BaseYarnCommand.cs +++ b/Assets/Scripts/Dialog System/BaseYarnCommand.cs @@ -25,20 +25,6 @@ namespace AibisDream UIManager.Instance.ShowPanel(); } - [Obsolete] - [YarnCommand("switch_tv")] - public static void SwitchTV(string picName) - { - Debug.Log("switch_tv 已废弃"); - } - - [Obsolete] - [YarnCommand("show_tv_scene")] - public static void ShowTVScene(float duration) - { - Debug.Log("show_tv_scene 已废弃"); - } - [YarnCommand("load_scene")] public static IEnumerator LoadScene(string sceneName, float duration = 1) { diff --git a/Assets/Scripts/FixSystemNew/Clinic/ClinicYarnCommand.cs b/Assets/Scripts/FixSystemNew/Clinic/ClinicYarnCommand.cs index ec2fff66c..959d8c8a3 100644 --- a/Assets/Scripts/FixSystemNew/Clinic/ClinicYarnCommand.cs +++ b/Assets/Scripts/FixSystemNew/Clinic/ClinicYarnCommand.cs @@ -10,13 +10,6 @@ namespace AibisDream { private static ClinicSystem ClinicSystem => FixSystemCenter.SystemDic.Get(); - [Obsolete] - [YarnCommand("indoor_new")] - public static void Indoor(float duration) - { - Debug.Log("indoor 已废除"); - } - [YarnCommand("quit_clinic_new")] public static IEnumerator Quit(float duration) { diff --git a/Assets/Scripts/Framework/EventSystemKit/WorldScrollRect.cs b/Assets/Scripts/Framework/EventSystemKit/WorldScrollRect.cs new file mode 100644 index 000000000..363a804ae --- /dev/null +++ b/Assets/Scripts/Framework/EventSystemKit/WorldScrollRect.cs @@ -0,0 +1,499 @@ +using UnityEngine; +using UnityEngine.EventSystems; +using AibisDream.Framework; + +namespace AibisDream.Framework +{ + /// + /// 世界坐标下的滚动组件,类似ScrollRect但兼容SpriteRenderer + /// + [RequireComponent(typeof(Collider2D))] + public class WorldScrollRect : MonoBehaviour, IInteraction + { + [Header("滚动目标")] + [SerializeField] private Transform targetTransform; + + [Header("滚动方向")] + [SerializeField] private bool horizontal = true; + [SerializeField] private bool vertical = true; + + [Header("边界设置")] + [SerializeField] private bool useAutoBounds = true; + [SerializeField] private Bounds contentBounds; + [SerializeField] private Bounds viewportBounds; + + [Header("惯性滚动")] + [SerializeField] private bool inertia = true; + [SerializeField] private float decelerationRate = 0.135f; + [SerializeField] private float velocityThreshold = 0.1f; + + [Header("弹性边界")] + [SerializeField] private bool elasticity = true; + [SerializeField] private float elasticityStrength = 0.1f; + + [Header("鼠标滚轮")] + [SerializeField] private bool scrollWheelEnabled = true; + [SerializeField] private float scrollSensitivity = 1f; + + [Header("交互设置")] + [SerializeField] private bool isActive = true; + [SerializeField] private bool isAvailable = true; + + private EventTriggerEx _eventTrigger; + private Collider2D _collider; + private Vector3 _initialTargetPosition; + private Vector3 _lastMouseWorldPos; + private Vector3 _velocity; + private bool _isDragging; + private Vector3[] _velocityHistory = new Vector3[5]; + private int _velocityHistoryIndex; + private float _lastDragTime; + + // IInteraction接口实现 + public bool IsActive => isActive; + public bool IsAvailable => isAvailable; + public GameObject GetGameObject() => gameObject; + + private void Awake() + { + _eventTrigger = GetComponent(); + _collider = GetComponent(); + + if (targetTransform == null) + { + targetTransform = transform; + } + + _initialTargetPosition = targetTransform.position; + + // 注册拖拽事件 + _eventTrigger.Register(EventTriggerType.BeginDrag, OnBeginDrag); + _eventTrigger.Register(EventTriggerType.Drag, OnDrag); + _eventTrigger.Register(EventTriggerType.EndDrag, OnEndDrag); + } + + private void Start() + { + if (useAutoBounds) + { + CalculateBounds(); + } + } + + private void Update() + { + if (!isActive || !isAvailable) return; + + // 处理鼠标滚轮 + if (scrollWheelEnabled) + { + HandleScrollWheel(); + } + + // 处理惯性滚动 + if (inertia && !_isDragging && _velocity.magnitude > velocityThreshold) + { + ApplyInertia(); + } + + // 处理弹性边界 + if (elasticity) + { + ApplyElasticity(); + } + } + + /// + /// 计算内容边界和视口边界 + /// + private void CalculateBounds() + { + // 计算视口边界(从Collider2D获取) + if (_collider != null) + { + viewportBounds = _collider.bounds; + } + else + { + viewportBounds = new Bounds(transform.position, Vector3.one * 5f); + } + + // 计算内容边界(从targetTransform的子对象获取) + if (targetTransform != null) + { + Bounds bounds = new Bounds(); + bool first = true; + + // 检查targetTransform本身是否有Renderer + Renderer selfRenderer = targetTransform.GetComponent(); + if (selfRenderer != null) + { + bounds = selfRenderer.bounds; + first = false; + } + + // 遍历所有子对象 + foreach (Transform child in targetTransform) + { + Renderer renderer = child.GetComponent(); + if (renderer != null) + { + if (first) + { + bounds = renderer.bounds; + first = false; + } + else + { + bounds.Encapsulate(renderer.bounds); + } + } + else + { + // 如果没有Renderer,使用Transform位置 + if (first) + { + bounds = new Bounds(child.position, Vector3.zero); + first = false; + } + else + { + bounds.Encapsulate(child.position); + } + } + } + + if (!first) + { + contentBounds = bounds; + } + else + { + // 如果没有任何Renderer,使用targetTransform的位置 + contentBounds = new Bounds(targetTransform.position, Vector3.one * 2f); + } + } + else + { + contentBounds = new Bounds(transform.position, Vector3.one * 2f); + } + } + + /// + /// 开始拖拽 + /// + private void OnBeginDrag(BaseEventData data) + { + if (!IsActive || !IsAvailable) return; + if (data is not PointerEventData pointerData) return; + + _isDragging = true; + _velocity = Vector3.zero; + _lastMouseWorldPos = CameraKit.GetMouseWorldPos(pointerData.position); + _lastDragTime = Time.time; + _velocityHistoryIndex = 0; + + // 清除速度历史 + for (int i = 0; i < _velocityHistory.Length; i++) + { + _velocityHistory[i] = Vector3.zero; + } + } + + /// + /// 拖拽中 + /// + private void OnDrag(BaseEventData data) + { + if (!IsActive || !IsAvailable) return; + if (data is not PointerEventData pointerData) return; + + Vector3 currentMouseWorldPos = CameraKit.GetMouseWorldPos(pointerData.position); + Vector3 delta = currentMouseWorldPos - _lastMouseWorldPos; + + // 根据滚动方向限制delta + if (!horizontal) delta.x = 0f; + if (!vertical) delta.y = 0f; + delta.z = 0f; + + // 更新目标位置 + Vector3 newPosition = targetTransform.position + delta; + targetTransform.position = ClampPosition(newPosition); + + // 记录速度历史 + float deltaTime = Time.time - _lastDragTime; + if (deltaTime > 0f) + { + Vector3 velocity = delta / deltaTime; + _velocityHistory[_velocityHistoryIndex] = velocity; + _velocityHistoryIndex = (_velocityHistoryIndex + 1) % _velocityHistory.Length; + } + + _lastMouseWorldPos = currentMouseWorldPos; + _lastDragTime = Time.time; + } + + /// + /// 结束拖拽 + /// + private void OnEndDrag(BaseEventData data) + { + _isDragging = false; + + // 计算平均速度 + Vector3 totalVelocity = Vector3.zero; + int count = 0; + for (int i = 0; i < _velocityHistory.Length; i++) + { + if (_velocityHistory[i].magnitude > 0f) + { + totalVelocity += _velocityHistory[i]; + count++; + } + } + + if (count > 0) + { + _velocity = totalVelocity / count; + } + else + { + _velocity = Vector3.zero; + } + } + + /// + /// 应用惯性滚动 + /// + private void ApplyInertia() + { + // 应用衰减 + _velocity *= Mathf.Pow(decelerationRate, Time.deltaTime); + + // 根据滚动方向限制速度 + if (!horizontal) _velocity.x = 0f; + if (!vertical) _velocity.y = 0f; + _velocity.z = 0f; + + // 更新位置 + Vector3 newPosition = targetTransform.position + _velocity * Time.deltaTime; + targetTransform.position = ClampPosition(newPosition); + + // 如果速度太小,停止惯性 + if (_velocity.magnitude < velocityThreshold) + { + _velocity = Vector3.zero; + } + } + + /// + /// 应用弹性边界 + /// + private void ApplyElasticity() + { + if (_isDragging || _velocity.magnitude > velocityThreshold) return; + + Vector3 currentPos = targetTransform.position; + Vector3 clampedPos = ClampPosition(currentPos); + Vector3 offset = currentPos - clampedPos; + + if (offset.magnitude > 0.01f) + { + // 应用弹性回弹 + Vector3 elasticForce = -offset * elasticityStrength; + Vector3 newPosition = currentPos + elasticForce * Time.deltaTime; + targetTransform.position = ClampPosition(newPosition); + } + } + + /// + /// 处理鼠标滚轮 + /// + private void HandleScrollWheel() + { + Vector2 scrollDelta = Input.mouseScrollDelta; + if (scrollDelta.magnitude == 0f) return; + + // 检查鼠标是否在视口内 + Vector3 mouseWorldPos = CameraKit.GetMouseWorldPos(Input.mousePosition); + if (!viewportBounds.Contains(mouseWorldPos)) return; + + Vector3 scrollDelta3D = new Vector3( + horizontal ? scrollDelta.x * scrollSensitivity : 0f, + vertical ? scrollDelta.y * scrollSensitivity : 0f, + 0f + ); + + Vector3 newPosition = targetTransform.position + scrollDelta3D; + targetTransform.position = ClampPosition(newPosition); + + // 停止惯性滚动 + _velocity = Vector3.zero; + } + + /// + /// 限制位置在边界内 + /// + private Vector3 ClampPosition(Vector3 position) + { + if (!useAutoBounds && contentBounds.size.magnitude < 0.01f) + { + return position; + } + + // 计算targetTransform的偏移量 + Vector3 offset = position - _initialTargetPosition; + + // 计算移动后的内容边界 + Bounds movedContentBounds = contentBounds; + movedContentBounds.center += offset; + + Vector3 contentMin = movedContentBounds.min; + Vector3 contentMax = movedContentBounds.max; + Vector3 viewportMin = viewportBounds.min; + Vector3 viewportMax = viewportBounds.max; + + Vector3 clampedOffset = offset; + + // 水平方向限制 + if (horizontal) + { + float contentWidth = contentMax.x - contentMin.x; + float viewportWidth = viewportMax.x - viewportMin.x; + + if (contentWidth > viewportWidth) + { + // 内容大于视口,限制内容边界在视口内 + // 内容左边界不能超过视口左边界 + if (contentMin.x > viewportMin.x) + { + clampedOffset.x -= (contentMin.x - viewportMin.x); + } + // 内容右边界不能超过视口右边界 + if (contentMax.x < viewportMax.x) + { + clampedOffset.x -= (contentMax.x - viewportMax.x); + } + } + // 如果内容小于视口,允许自由移动(不限制) + } + else + { + clampedOffset.x = 0f; + } + + // 垂直方向限制 + if (vertical) + { + float contentHeight = contentMax.y - contentMin.y; + float viewportHeight = viewportMax.y - viewportMin.y; + + if (contentHeight > viewportHeight) + { + // 内容大于视口,限制内容边界在视口内 + // 内容下边界不能超过视口下边界 + if (contentMin.y > viewportMin.y) + { + clampedOffset.y -= (contentMin.y - viewportMin.y); + } + // 内容上边界不能超过视口上边界 + if (contentMax.y < viewportMax.y) + { + clampedOffset.y -= (contentMax.y - viewportMax.y); + } + } + // 如果内容小于视口,允许自由移动(不限制) + } + else + { + clampedOffset.y = 0f; + } + + clampedOffset.z = 0f; + return _initialTargetPosition + clampedOffset; + } + + /// + /// 设置目标Transform + /// + public void SetTargetTransform(Transform target) + { + targetTransform = target; + if (target != null) + { + _initialTargetPosition = target.position; + } + } + + /// + /// 设置内容边界 + /// + public void SetContentBounds(Bounds bounds) + { + contentBounds = bounds; + useAutoBounds = false; + } + + /// + /// 设置视口边界 + /// + public void SetViewportBounds(Bounds bounds) + { + viewportBounds = bounds; + useAutoBounds = false; + } + + /// + /// 重新计算边界 + /// + public void RecalculateBounds() + { + CalculateBounds(); + } + + /// + /// 停止滚动 + /// + public void StopMovement() + { + _velocity = Vector3.zero; + _isDragging = false; + } + + /// + /// 重置到初始位置 + /// + public void ResetPosition() + { + StopMovement(); + if (targetTransform != null) + { + targetTransform.position = _initialTargetPosition; + } + } + + private void OnDestroy() + { + if (_eventTrigger != null) + { + _eventTrigger.UnRegister(EventTriggerType.BeginDrag, OnBeginDrag); + _eventTrigger.UnRegister(EventTriggerType.Drag, OnDrag); + _eventTrigger.UnRegister(EventTriggerType.EndDrag, OnEndDrag); + } + } + +#if UNITY_EDITOR + private void OnDrawGizmosSelected() + { + // 绘制视口边界 + Gizmos.color = Color.green; + Gizmos.DrawWireCube(viewportBounds.center, viewportBounds.size); + + // 绘制内容边界 + Gizmos.color = Color.yellow; + Gizmos.DrawWireCube(contentBounds.center, contentBounds.size); + } +#endif + } +} + diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs.meta b/Assets/Scripts/Framework/EventSystemKit/WorldScrollRect.cs.meta similarity index 83% rename from Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs.meta rename to Assets/Scripts/Framework/EventSystemKit/WorldScrollRect.cs.meta index 49962fd0d..f9b02029d 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs.meta +++ b/Assets/Scripts/Framework/EventSystemKit/WorldScrollRect.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ab4b77b210903a6428113bbc4e0fac09 +guid: 62f74d13a65af244a814f1f7306a1925 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/Framework/LogKit/FileLogger.cs b/Assets/Scripts/Framework/LogKit/FileLogger.cs index 373d8efc6..0928211e3 100644 --- a/Assets/Scripts/Framework/LogKit/FileLogger.cs +++ b/Assets/Scripts/Framework/LogKit/FileLogger.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace AibisDream.Kit @@ -18,7 +18,7 @@ namespace AibisDream.Kit /// /// 开始打印 /// - public FileLogger(string filename, string filePath, int saveDays) + public FileLogger(string filename, string filePath, int saveDays, string version = null) { _filename = filename; _filePath = filePath.TrimEnd('/') + "/"; @@ -26,6 +26,13 @@ namespace AibisDream.Kit StartNewFile(); DeleteOldFile(); _currentLogDay = CurrentDay; + + // 在日志开头写入版本号信息 + if (!string.IsNullOrEmpty(version)) + { + Write($"Version: {version}\n"); + } + Write("*********************************************************\nSystem Start at " + DateTime.Now.ToString("HH:mm:ss") + "\n*********************************************************\n"); @@ -50,6 +57,7 @@ namespace AibisDream.Kit } _fileWriter = File.AppendText(_filePath + string.Format(_filename, DateTime.Now)); + _fileWriter.AutoFlush = true; // 启用自动刷新,实现流式写入 } public void Write(string content) diff --git a/Assets/Scripts/Framework/LogKit/LogKit.cs b/Assets/Scripts/Framework/LogKit/LogKit.cs index 013ff13e9..9eebda169 100644 --- a/Assets/Scripts/Framework/LogKit/LogKit.cs +++ b/Assets/Scripts/Framework/LogKit/LogKit.cs @@ -34,8 +34,7 @@ namespace AibisDream.Kit { #if !UNITY_EDITOR DontDestroyOnLoad(gameObject); - _fileLogger = new FileLogger(LogFileName, LogPath, SaveDays); - LogMessage($"Ver.{Application.version}", "", LogType.Log); + _fileLogger = new FileLogger(LogFileName, LogPath, SaveDays, Application.version); Application.logMessageReceivedThreaded += LogMessage; #endif } diff --git a/Assets/Scripts/Framework/ResourceKit/ResourceKit.cs b/Assets/Scripts/Framework/ResourceKit/ResourceKit.cs index 00688ba8c..bac70d74a 100644 --- a/Assets/Scripts/Framework/ResourceKit/ResourceKit.cs +++ b/Assets/Scripts/Framework/ResourceKit/ResourceKit.cs @@ -1,10 +1,13 @@ using System; using System.Linq; -using UnityEditor; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; +#if UNITY_EDITOR +using UnityEditor; +#endif + namespace AibisDream.Framework { public static class ResourceKit @@ -72,7 +75,7 @@ namespace AibisDream.Framework return default; } } - + public static void LoadAssetAsync(string key, Action callback) where T : UnityEngine.Object { Addressables.LoadAssetAsync(key).Completed += operation => @@ -87,5 +90,27 @@ namespace AibisDream.Framework } }; } + +#if UNITY_EDITOR + public static bool GetAssetAddressableKey(UnityEngine.Object asset, out string addressableKey) + { + string path = AssetDatabase.GetAssetPath(asset); + // 获取其在Addressables里的路径 + var settings = UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject.Settings; + if (settings != null) + { + var entry = settings.FindAssetEntry(AssetDatabase.AssetPathToGUID(path)); + if (entry != null) + { + Debug.Log($"Addressable Key: {entry.address}"); + addressableKey = entry.address; + return true; + } + } + Debug.Log($"资源{asset.name}不存在于Addressables中"); + addressableKey = path; + return false; + } } +#endif } \ No newline at end of file diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/BlockPuzzleSystem.cs b/Assets/Scripts/MiniGame/BlockPuzzle/BlockPuzzleSystem.cs index b77d7b446..9ec14dcb2 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/BlockPuzzleSystem.cs +++ b/Assets/Scripts/MiniGame/BlockPuzzle/BlockPuzzleSystem.cs @@ -1,6 +1,4 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; +using AibisDream.Kit; namespace AibisDream { @@ -8,7 +6,7 @@ namespace AibisDream /// BlockPuzzle游戏系统 /// 整合所有子系统的核心控制器 /// - public class BlockPuzzleSystem : MonoBehaviour + public class BlockPuzzleSystem : Singleton { // 接口引用将在实现类中注入 // 这里先定义基础框架接口结构 diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzle.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzle.cs new file mode 100644 index 000000000..08c987746 --- /dev/null +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzle.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using UnityEngine.UI; +using AibisDream.Kit; +using AibisDream.Utility; + + +namespace AibisDream +{ + public class BlockPuzzle : Singleton + { + // 物体索引 + [SerializeField] public BlockPuzzleGrid grid; + [SerializeField] private Transform shapeRoot; + [SerializeField] private BlockPuzzleValidator validator; + [SerializeField] public BlockShapeRack shapeRack; + + // 临时按钮 + [SerializeField] private Button submitButton; + [SerializeField] private Button clearButton; + + // 事件 + public event Action OnSubmit; + public event Action OnPreview; + + private void Start() + { + Initialize(); + + submitButton.onClick.AddListener(SubmitGameResult); + clearButton.onClick.AddListener(ResetGame); + } + + public void Initialize() + { + // 初始化网格 + grid.Initialize(); + grid.OnShapePlaced += PreCheckGameState; + // 初始化网格上的Shape预设 + + // 初始化图形货架 + // shapeRack.Initialize(); + } + + private void PreCheckGameState() + { + var shapes = grid.GetShapes(); + var validateResult = validator.Validate(shapes); + OnPreview?.Invoke(validateResult); + } + + private void SubmitGameResult() + { + var shapes = grid.GetShapes(); + var validateResult = validator.Validate(shapes); + OnSubmit?.Invoke(validateResult); + } + + private void ResetGame() + { + + } + } + + public static class BlockPuzzleKit + { + /// + /// 保存单个 BlockShapeData 到文件,确保 Key 唯一(如果 Key 已存在则更新,不存在则添加) + /// + /// 要保存的数据 + /// 数据的键(用于字典存储) + /// 保存路径,如果为空则使用默认路径 + public static void SaveBlockShapeData(BlockShapeData data, string key, string path = null) + { + if (string.IsNullOrEmpty(path)) + { + path = ConstRef.BlockShapeDataPath; + } + + // 确保目录存在 + string directory = Path.GetDirectoryName(path); + if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + // 读取现有字典(如果文件存在) + Dictionary dataDict; + if (File.Exists(path)) + { + try + { + dataDict = JsonUtil.ReadBeanDict(path) ?? new Dictionary(); + } + catch (Exception e) + { + Debug.LogWarning($"读取现有 BlockShapeData 文件失败,将创建新文件: {e.Message}"); + dataDict = new Dictionary(); + } + } + else + { + dataDict = new Dictionary(); + } + + // 更新或添加数据(确保 Key 唯一) + dataDict[key] = data; + + // 保存整个字典 + JsonUtil.SaveBean(dataDict, path); + } + + /// + /// 保存 BlockShapeData 数组到文件 + /// + /// 要保存的数据数组 + /// 保存路径,如果为空则使用默认路径 + public static void SaveBlockShapeDataArray(BlockShapeData[] dataArray, string path = null) + { + if (string.IsNullOrEmpty(path)) + { + path = ConstRef.BlockShapeDataPath; + } + + // 确保目录存在 + string directory = Path.GetDirectoryName(path); + if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + JsonUtil.SaveArray(dataArray, path); + } + + /// + /// 保存 BlockShapeData 字典到文件 + /// + /// 要保存的数据字典 + /// 保存路径,如果为空则使用默认路径 + public static void SaveBlockShapeDataDict(Dictionary dataDict, string path = null) + { + if (string.IsNullOrEmpty(path)) + { + path = ConstRef.BlockShapeDataPath; + } + + // 确保目录存在 + string directory = Path.GetDirectoryName(path); + if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + JsonUtil.SaveBean(dataDict, path); + } + + /// + /// 从文件加载单个 BlockShapeData + /// + /// 数据的键 + /// 文件路径,如果为空则使用默认路径 + /// 加载的数据 + /// 是否加载成功 + public static bool TryLoadBlockShapeData(string key, out BlockShapeData data, string path = null) + { + if (string.IsNullOrEmpty(path)) + { + path = ConstRef.BlockShapeDataPath; + } + + try + { + if (!File.Exists(path)) + { + data = default; + return false; + } + + var dict = JsonUtil.ReadBeanDict(path); + if (dict != null && dict.ContainsKey(key)) + { + data = dict[key]; + return true; + } + + data = default; + return false; + } + catch (Exception e) + { + Debug.LogError($"加载 BlockShapeData 失败: {e.Message}"); + data = default; + return false; + } + } + + /// + /// 从文件加载 BlockShapeData 数组 + /// + /// 文件路径,如果为空则使用默认路径 + /// 加载的数据数组 + /// 是否加载成功 + public static bool TryLoadBlockShapeDataArray(out BlockShapeData[] dataArray, string path = null) + { + if (string.IsNullOrEmpty(path)) + { + path = ConstRef.BlockShapeDataPath; + } + + try + { + if (!File.Exists(path)) + { + dataArray = null; + return false; + } + + dataArray = JsonUtil.ReadBeanArray(path); + return dataArray != null; + } + catch (Exception e) + { + Debug.LogError($"加载 BlockShapeData 数组失败: {e.Message}"); + dataArray = null; + return false; + } + } + + /// + /// 从文件加载 BlockShapeData 字典 + /// + /// 文件路径,如果为空则使用默认路径 + /// 加载的数据字典 + /// 是否加载成功 + public static bool TryLoadBlockShapeDataDict(out Dictionary dataDict, string path = null) + { + if (string.IsNullOrEmpty(path)) + { + path = ConstRef.BlockShapeDataPath; + } + + try + { + if (!File.Exists(path)) + { + dataDict = null; + return false; + } + + dataDict = JsonUtil.ReadBeanDict(path); + return dataDict != null; + } + catch (Exception e) + { + Debug.LogError($"加载 BlockShapeData 字典失败: {e.Message}"); + dataDict = null; + return false; + } + } + + /// + /// 获取所有已保存的 BlockShapeData 的键列表 + /// + /// 文件路径,如果为空则使用默认路径 + /// 键列表,如果文件不存在则返回空数组 + public static string[] GetAllBlockShapeDataKeys(string path = null) + { + if (string.IsNullOrEmpty(path)) + { + path = ConstRef.BlockShapeDataPath; + } + + try + { + if (!File.Exists(path)) + { + return new string[0]; + } + + return JsonUtil.ReadKeys(path); + } + catch (Exception e) + { + Debug.LogError($"获取 BlockShapeData 键列表失败: {e.Message}"); + return new string[0]; + } + } + } +} diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Interface/IBlockPuzzleGameLogic.cs.meta b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzle.cs.meta similarity index 83% rename from Assets/Scripts/MiniGame/BlockPuzzle/Interface/IBlockPuzzleGameLogic.cs.meta rename to Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzle.cs.meta index fa33a1d4a..c290a38fd 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Interface/IBlockPuzzleGameLogic.cs.meta +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzle.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4603b37a885792d4b85d6d5d392d4862 +guid: d4ac8aed859d93147929de492c3bc62b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGrid.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGrid.cs index 526dea379..1c80fd931 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGrid.cs +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGrid.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace AibisDream @@ -29,6 +32,9 @@ namespace AibisDream public int Height { get; private set; } public float CellSize { get; private set; } public Vector3 Origin { get; private set; } + public Dictionary ShapeDict { get; private set; } + + public event Action OnShapePlaced; private void Start() { @@ -66,6 +72,8 @@ namespace AibisDream _grid = new GridCellState[width, height]; _isInitialized = true; + ShapeDict = new Dictionary(); + Clear(); } @@ -160,12 +168,6 @@ namespace AibisDream gridX = Mathf.FloorToInt(localPos.x / CellSize); gridY = Mathf.FloorToInt(localPos.y / CellSize); - // TODO: 不检查是否在有效范围内,留给后续检查 - // if (!IsValidPosition(gridX, gridY)) - // { - // return false; - // } - return true; } @@ -253,6 +255,20 @@ namespace AibisDream cellSize = Mathf.Max(0.1f, cellSize); } + public List GetShapes() + { + return ShapeDict.Keys.ToList(); + } + + private void OnDestroy() + { + OnShapePlaced = null; + } + + + // ============================================ 绘制预览 ============================================ + + /// /// 在编辑器中绘制网格预览 /// @@ -298,7 +314,7 @@ namespace AibisDream { Vector3 cellCenter = GridToWorld(x, y); GridCellState state = GetCellState(x, y); - + Gizmos.color = state == GridCellState.Occupied ? occupiedCellColor : emptyCellColor; Gizmos.DrawCube(cellCenter, cellSizeVec); } diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs deleted file mode 100644 index 9e5ba0c24..000000000 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridEx.cs +++ /dev/null @@ -1,96 +0,0 @@ -using UnityEngine; - -namespace AibisDream -{ - public static class BlockPuzzleGridEx - { - public static SnapResult CheckSnapToGrid(this IBlockPuzzleGrid grid, BlockShape shape) - { - // 预制错误结果作为返回值 - SnapResult result = new SnapResult - { - canSnap = false, - snapPosition = shape.transform.position, - gridX = 0, - gridY = 0, - distance = float.MaxValue, - gridPositions = new Vector2Int[0] - }; - - // 将Shape的世界坐标转换为网格坐标(可以是虚拟坐标) - bool inGrid = grid.WorldToGrid(shape.transform.position, out int gridX, out int gridY); - if (!inGrid) return result; - - // 将形状的所有格子转换为网格坐标 - // gridX, gridY 是形状的 (0, 0) 点在网格中的位置 - Vector2Int[] gridCells = ConvertShapeToGridCells(shape, gridX, gridY); - result.gridX = gridX; - result.gridY = gridY; - result.snapPosition = grid.GridToWorld(gridX, gridY); - result.gridPositions = gridCells; - - // 逐个坐标验证是否可以放置 - var canPlace = grid.CanPlace(gridCells); - if (!canPlace) return result; - result.canSnap = true; - result.distance = Vector3.Distance(shape.transform.position, result.snapPosition); - - return result; - } - - /// - /// 将形状的相对坐标转换为网格坐标 - /// 已知形状的 (0, 0) 点在网格中的位置为 (gridX, gridY),将形状的其他格子坐标转换为网格坐标 - /// - /// 形状 - /// 网格X坐标(形状左下角位置,即形状的 (0, 0) 点对应的网格坐标) - /// 网格Y坐标(形状左下角位置,即形状的 (0, 0) 点对应的网格坐标) - /// 形状所有格子在网格中的坐标数组 - public static Vector2Int[] ConvertShapeToGridCells(IBlockShape shape, int gridX, int gridY) - { - if (shape == null) - { - return new Vector2Int[0]; - } - - Vector2Int[] blockPositions = shape.GetBlockPositions(); - if (blockPositions == null || blockPositions.Length == 0) - { - return new Vector2Int[0]; - } - - Vector2Int[] gridCells = new Vector2Int[blockPositions.Length]; - - for (int i = 0; i < blockPositions.Length; i++) - { - // 将形状的相对坐标转换为网格坐标 - // 形状的 (0, 0) 对应网格的 (gridX, gridY) - // 形状的 (blockPos.x, blockPos.y) 对应网格的 (gridX + blockPos.x, gridY + blockPos.y) - gridCells[i] = new Vector2Int( - gridX + blockPositions[i].x, - gridY + blockPositions[i].y - ); - } - - return gridCells; - } - - /// - /// 为吸附制作预览 - /// - /// 转换后的网格坐标组 - public static void ShowSnapPreview(this IBlockPuzzleGrid grid, Vector2Int[] shapeCells) - { - - } - - public static void TrySnapToGrid(this IBlockPuzzleGrid grid, BlockShape shape, Vector2Int rootCell) - { - // 判断RootCell的位置 - var rootWorldPos = grid.GridToWorld(rootCell.x, rootCell.y); - // 已经判断是否可吸附,直接吸就好了 - shape.transform.position = rootWorldPos; - // TODO: 设置网格状态 - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridExample.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridExample.cs deleted file mode 100644 index bf298d12a..000000000 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridExample.cs +++ /dev/null @@ -1,148 +0,0 @@ -using UnityEngine; - -namespace AibisDream -{ - /// - /// BlockPuzzle网格系统使用示例 - /// 演示如何使用网格系统和可视化组件 - /// - public class BlockPuzzleGridExample : MonoBehaviour - { - [Header("组件引用")] - [SerializeField] private BlockPuzzleGrid gridComponent; - [SerializeField] private GridVisualizer gridVisualizer; - - [Header("测试设置")] - [SerializeField] private KeyCode testPlaceKey = KeyCode.Space; - [SerializeField] private KeyCode testClearKey = KeyCode.C; - - private IBlockPuzzleGrid _grid; - - private void Start() - { - // 初始化网格组件 - if (gridComponent != null) - { - gridComponent.Initialize(); - _grid = gridComponent; // 组件直接实现IBlockPuzzleGrid接口 - } - - // 设置可视化器 - if (gridVisualizer != null && _grid != null) - { - gridVisualizer.SetGrid(_grid); - } - } - - private void Update() - { - if (_grid == null) return; - - // 测试:按空格键随机放置一个格子 - if (Input.GetKeyDown(testPlaceKey)) - { - TestPlaceRandomCell(); - } - - // 测试:按C键清空网格 - if (Input.GetKeyDown(testClearKey)) - { - TestClearGrid(); - } - - // 测试:鼠标点击放置格子 - if (Input.GetMouseButtonDown(0)) - { - TestPlaceCellAtMouse(); - } - } - - /// - /// 测试:在随机位置放置一个格子 - /// - private void TestPlaceRandomCell() - { - if (_grid == null) return; - - int x = Random.Range(0, _grid.Width); - int y = Random.Range(0, _grid.Height); - - if (_grid.IsCellEmpty(x, y)) - { - _grid.SetCellState(x, y, GridCellState.Occupied); - Debug.Log($"放置格子到位置 ({x}, {y})"); - - // 更新可视化 - if (gridVisualizer != null) - { - gridVisualizer.UpdateCellVisual(x, y); - } - } - } - - /// - /// 测试:在鼠标位置放置格子 - /// - private void TestPlaceCellAtMouse() - { - if (_grid == null) return; - - // 获取鼠标世界坐标(需要根据你的相机设置调整) - Camera cam = Camera.main; - if (cam == null) return; - - Vector3 mousePos = Input.mousePosition; - mousePos.z = cam.nearClipPlane + 1f; // 设置合适的Z距离 - Vector3 worldPos = cam.ScreenToWorldPoint(mousePos); - - // 转换为网格坐标 - if (_grid.WorldToGrid(worldPos, out int gridX, out int gridY)) - { - if (_grid.IsCellEmpty(gridX, gridY)) - { - _grid.SetCellState(gridX, gridY, GridCellState.Occupied); - Debug.Log($"鼠标点击放置格子到位置 ({gridX}, {gridY})"); - - // 更新可视化 - if (gridVisualizer != null) - { - gridVisualizer.UpdateCellVisual(gridX, gridY); - } - } - } - } - - /// - /// 测试:清空网格 - /// - private void TestClearGrid() - { - if (_grid == null) return; - - _grid.Clear(); - Debug.Log("清空网格"); - - // 更新可视化 - if (gridVisualizer != null) - { - gridVisualizer.UpdateAllCellsVisual(); - } - } - - private void OnGUI() - { - if (_grid == null) return; - - GUILayout.BeginArea(new Rect(10, 10, 300, 200)); - GUILayout.Label($"网格尺寸: {_grid.Width} x {_grid.Height}"); - GUILayout.Label($"单元格大小: {_grid.CellSize}"); - GUILayout.Label($"已占用: {_grid.GetOccupiedCount()} / {_grid.GetTotalCellCount()}"); - GUILayout.Space(10); - GUILayout.Label($"按 {testPlaceKey} 键:随机放置格子"); - GUILayout.Label($"按 {testClearKey} 键:清空网格"); - GUILayout.Label("鼠标左键:在鼠标位置放置格子"); - GUILayout.EndArea(); - } - } -} - diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleValidator.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleValidator.cs new file mode 100644 index 000000000..ca344699f --- /dev/null +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleValidator.cs @@ -0,0 +1,106 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace AibisDream +{ + [CreateAssetMenu(fileName = "BlockPuzzleValidator", menuName = "Block Puzzle/BlockPuzzleValidator")] + public class BlockPuzzleValidator : ScriptableObject + { + [Tooltip("基础条件, 不满足无法提交")] + public ValidateItem[] baseConditions; + [Tooltip("额外条件, 不满足也可以提交")] + public ValidateItem[] extraConditions; + + /// + /// 验证是否可以完成拼图 + /// + /// + /// + public ValidateResult Validate(List shapeInGrid) + { + var result = new ValidateResult(); + + string[] shapeNames = shapeInGrid.Select(s => s.ShapeName).ToArray(); + // 先校验基础条件 + foreach (var condition in baseConditions) + { + var itemResult = condition.Validate(shapeNames); + + result.baseConditionResults.Add((condition.name, itemResult)); + result.isPass = result.isPass && itemResult; + } + + // 再校验额外条件 + foreach (var condition in extraConditions) + { + var itemResult = condition.Validate(shapeNames); + + result.extraConditionResults.Add((condition.name, itemResult)); + result.isExtraConditionPass = result.isExtraConditionPass && itemResult; + } + + return result; + } + + [System.Serializable] + public struct ValidateItem + { + [Tooltip("名称, 仅用于显示")] + public string name; + + [Tooltip("规则要求的组件,多种组件则合并后判断")] + public string[] targetNames; + public CompareSign compareSign; + public int count; + + public bool Validate(string[] shapeNames) + { + var targetNames = this.targetNames; + + if (targetNames.Length == 0) return true; + + var totalCount = shapeNames.Where(name => targetNames.Contains(name)).Count(); + return compareSign switch + { + CompareSign.Equal => totalCount == count, + CompareSign.NotEqual => totalCount != count, + CompareSign.GreaterThan => totalCount > count, + CompareSign.LessThan => totalCount < count, + CompareSign.GreaterThanOrEqual => totalCount >= count, + CompareSign.LessThanOrEqual => totalCount <= count, + _ => false, + }; + } + } + + // 比较符 + public enum CompareSign + { + Equal, + NotEqual, + GreaterThan, + LessThan, + GreaterThanOrEqual, + LessThanOrEqual, + } + } + + public class ValidateResult + { + public bool isPass; + public bool isExtraConditionPass; + + public List<(string name, bool isPass)> baseConditionResults; + public List<(string name, bool isPass)> extraConditionResults; + + public ValidateResult() + { + isPass = true; + isExtraConditionPass = true; + + baseConditionResults = new List<(string name, bool isPass)>(); + extraConditionResults = new List<(string name, bool isPass)>(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridExample.cs.meta b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleValidator.cs.meta similarity index 83% rename from Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridExample.cs.meta rename to Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleValidator.cs.meta index 0fdf9130c..05c3f28ed 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleGridExample.cs.meta +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockPuzzleValidator.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cfe4f41ce15355345b390aa2701f3f46 +guid: 8eea7264a53eb574eabe4bd65c4fa462 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShape.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShape.cs index 792658e6b..5b3e7a359 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShape.cs +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShape.cs @@ -1,6 +1,8 @@ +using System; using System.Collections.Generic; using AibisDream.Utility; using UnityEngine; +using AibisDream.Framework; namespace AibisDream { @@ -10,20 +12,16 @@ namespace AibisDream // 模块数据 [Header("模块数据")] - [SerializeField] private int shapeId; - [SerializeField] private string shapeName; - [SerializeField] private RotationAngle currentRotation; - [SerializeField] private int width; - [SerializeField] private int height; - [SerializeField] private float cellSize; - [SerializeField] private string originalPatternStr; + [SerializeField] private BlockShapeData _blockShapeData; + private RotationAngle currentRotation; // 接口实现 - public int ShapeId => shapeId; - public string ShapeName => shapeName; + public ShapeDragger ShapeDragger { get; private set; } + public int ShapeId => _blockShapeData.shapeId; + public string ShapeName => _blockShapeData.shapeName; public RotationAngle CurrentRotation => currentRotation; - public int Width => width; - public int Height => height; + public int Width => GetCurrentWidth(); + public int Height => GetCurrentHeight(); public int BlockCount { get @@ -32,9 +30,9 @@ namespace AibisDream if (pattern == null) return 0; int count = 0; - for (int i = 0; i < width; i++) + for (int i = 0; i < _blockShapeData.width; i++) { - for (int j = 0; j < height; j++) + for (int j = 0; j < _blockShapeData.height; j++) { if (pattern[i, j] != 0) { @@ -46,16 +44,29 @@ namespace AibisDream } } + public void Init(BlockShapeData blockShapeData) + { + ShapeDragger = GetComponent(); + _blockShapeData = blockShapeData; + // 加载Sprite + LoadSprite(); + // 更新碰撞体 + UpdatePolygonCollider(); + } + public Vector2Int[] GetBlockPositions() { - var pattern = GetOriginalPattern(); + var pattern = GetCurrentPattern(); if (pattern == null) return new Vector2Int[0]; + int currentWidth = GetCurrentWidth(); + int currentHeight = GetCurrentHeight(); + List positions = new List(); - - for (int i = 0; i < width; i++) + + for (int i = 0; i < currentWidth; i++) { - for (int j = 0; j < height; j++) + for (int j = 0; j < currentHeight; j++) { if (pattern[i, j] != 0) { @@ -67,47 +78,233 @@ namespace AibisDream return positions.ToArray(); } - /// - /// 获取单元格渲染器数组(供拖拽组件使用) - /// - public SpriteRenderer[,] GetCellRenderers() - { - return _cellRenderers; - } - public int[,] GetCurrentPattern() { - throw new System.NotImplementedException(); + var originalPattern = GetOriginalPattern(); + if (originalPattern == null) return null; + + if (currentRotation == RotationAngle.Rotate0) + { + return originalPattern; + } + + return RotatePattern(originalPattern, currentRotation); } public int[,] GetOriginalPattern() { - return CommonUtil.DeserializeIntArray(originalPatternStr); + return CommonUtil.DeserializeIntArray(_blockShapeData.originalPatternStr); } public bool HasBlockAt(int x, int y) { - throw new System.NotImplementedException(); + var pattern = GetCurrentPattern(); + if (pattern == null) return false; + + int currentWidth = GetCurrentWidth(); + int currentHeight = GetCurrentHeight(); + + if (x < 0 || x >= currentWidth || y < 0 || y >= currentHeight) + return false; + + return pattern[x, y] != 0; + } + + /// + /// 根据网格情况计算出形状的物理中心位置 + /// + /// 形状的物理中心位置,z为0 + public Vector3 GetCenterPosition() + { + var pattern = GetCurrentPattern(); + if (pattern == null) return Vector3.zero; + + int currentWidth = GetCurrentWidth(); + int currentHeight = GetCurrentHeight(); + + Vector3 centerSum = Vector3.zero; + int blockCount = 0; + + // 遍历所有格子,计算填充格子的中心位置 + for (int i = 0; i < currentWidth; i++) + { + for (int j = 0; j < currentHeight; j++) + { + if (pattern[i, j] != 0) + { + // 计算格子(i,j)的物理中心位置 + // 格子左下角在 (i * cellSize, j * cellSize) + // 格子中心在 (i * cellSize + cellSize/2, j * cellSize + cellSize/2) + float cellCenterX = i * _blockShapeData.cellSize * GetAxis().x; + float cellCenterY = j * _blockShapeData.cellSize * GetAxis().y; + + centerSum += new Vector3(cellCenterX, cellCenterY, 0); + blockCount++; + } + } + } + + // 如果没有填充的格子,返回零向量 + if (blockCount == 0) + return Vector3.zero; + + // 返回所有填充格子的平均位置(物理中心) + return centerSum / blockCount; } public void ResetRotation() { - throw new System.NotImplementedException(); + currentRotation = RotationAngle.Rotate0; + UpdateVisualRotation(); } public void Rotate(RotationAngle angle) { - throw new System.NotImplementedException(); + currentRotation = angle; + UpdateVisualRotation(); } public void RotateClockwise() { - throw new System.NotImplementedException(); + // 顺时针旋转90度 + switch (currentRotation) + { + case RotationAngle.Rotate0: + currentRotation = RotationAngle.Rotate90; + break; + case RotationAngle.Rotate90: + currentRotation = RotationAngle.Rotate180; + break; + case RotationAngle.Rotate180: + currentRotation = RotationAngle.Rotate270; + break; + case RotationAngle.Rotate270: + currentRotation = RotationAngle.Rotate0; + break; + } + UpdateVisualRotation(); + } + + public Vector2Int GetAxis() + { + // 顺时针旋转90度 + return currentRotation switch + { + RotationAngle.Rotate0 => new Vector2Int(1, 1), + RotationAngle.Rotate90 => new Vector2Int(-1, 1), + RotationAngle.Rotate180 => new Vector2Int(-1, -1), + RotationAngle.Rotate270 => new Vector2Int(1, -1), + _ => new Vector2Int(1, 1), + }; } public void RotateCounterClockwise() { - throw new System.NotImplementedException(); + // 逆时针旋转90度 + switch (currentRotation) + { + case RotationAngle.Rotate0: + currentRotation = RotationAngle.Rotate270; + break; + case RotationAngle.Rotate90: + currentRotation = RotationAngle.Rotate0; + break; + case RotationAngle.Rotate180: + currentRotation = RotationAngle.Rotate90; + break; + case RotationAngle.Rotate270: + currentRotation = RotationAngle.Rotate180; + break; + } + UpdateVisualRotation(); + } + + /// + /// 获取当前旋转后的宽度 + /// + private int GetCurrentWidth() + { + // 90度和270度时,宽度和高度交换 + return (currentRotation == RotationAngle.Rotate90 || currentRotation == RotationAngle.Rotate270) + ? _blockShapeData.height + : _blockShapeData.width; + } + + /// + /// 获取当前旋转后的高度 + /// + private int GetCurrentHeight() + { + // 90度和270度时,宽度和高度交换 + return (currentRotation == RotationAngle.Rotate90 || currentRotation == RotationAngle.Rotate270) + ? _blockShapeData.width + : _blockShapeData.height; + } + + /// + /// 旋转pattern数组 + /// + private int[,] RotatePattern(int[,] pattern, RotationAngle angle) + { + if (pattern == null) return null; + + int originalWidth = pattern.GetLength(0); + int originalHeight = pattern.GetLength(1); + int[,] rotatedPattern; + + switch (angle) + { + case RotationAngle.Rotate90: + // 顺时针90度:new[i][j] = old[width-1-j][i] + rotatedPattern = new int[originalHeight, originalWidth]; + for (int i = 0; i < originalHeight; i++) + { + for (int j = 0; j < originalWidth; j++) + { + rotatedPattern[i, j] = pattern[originalWidth - 1 - j, i]; + } + } + break; + + case RotationAngle.Rotate180: + // 180度:new[i][j] = old[width-1-i][height-1-j] + rotatedPattern = new int[originalWidth, originalHeight]; + for (int i = 0; i < originalWidth; i++) + { + for (int j = 0; j < originalHeight; j++) + { + rotatedPattern[i, j] = pattern[originalWidth - 1 - i, originalHeight - 1 - j]; + } + } + break; + + case RotationAngle.Rotate270: + // 逆时针90度(顺时针270度):new[i][j] = old[j][height-1-i] + rotatedPattern = new int[originalHeight, originalWidth]; + for (int i = 0; i < originalHeight; i++) + { + for (int j = 0; j < originalWidth; j++) + { + rotatedPattern[i, j] = pattern[j, originalHeight - 1 - i]; + } + } + break; + + default: // Rotate0 + rotatedPattern = (int[,])pattern.Clone(); + break; + } + + return rotatedPattern; + } + + /// + /// 更新视觉旋转(更新transform的rotation) + /// + private void UpdateVisualRotation() + { + float rotationZ = (float)currentRotation; + transform.rotation = Quaternion.Euler(0, 0, rotationZ); } private Sprite CreateDefaultSprite() @@ -125,11 +322,11 @@ namespace AibisDream _cellRenderers = null; // 根据Width和Height,绘制Cells,Cell为SpriteRenderer - _cellRenderers = new SpriteRenderer[width, height]; + _cellRenderers = new SpriteRenderer[_blockShapeData.width, _blockShapeData.height]; var defaultSprite = CreateDefaultSprite(); - for (int i = 0; i < width; i++) + for (int i = 0; i < _blockShapeData.width; i++) { - for (int j = 0; j < height; j++) + for (int j = 0; j < _blockShapeData.height; j++) { var cell = new GameObject($"Cell_{i}_{j}"); var cellRenderer = cell.AddComponent(); @@ -138,53 +335,75 @@ namespace AibisDream cell.transform.parent = transform; // 计算Cell应处的位置 - var cellPosX = i * cellSize; - var cellPosY = j * cellSize; + var cellPosX = i * _blockShapeData.cellSize; + var cellPosY = j * _blockShapeData.cellSize; cell.transform.localPosition = new Vector3(cellPosX, cellPosY, 0); } } // 反序列化并处理 - var pattern = CommonUtil.DeserializeIntArray(originalPatternStr); + var pattern = CommonUtil.DeserializeIntArray(_blockShapeData.originalPatternStr); // 先判断pattern的维度是否与width和height一致 - if (pattern.GetLength(0) != width || pattern.GetLength(1) != height) + if (pattern.GetLength(0) != _blockShapeData.width || pattern.GetLength(1) != _blockShapeData.height) { // 如果不一致,就不处理 - Debug.LogWarning($"Pattern dimension mismatch: {pattern.GetLength(0)}x{pattern.GetLength(1)} != {width}x{height}"); + Debug.LogWarning($"Pattern dimension mismatch: {pattern.GetLength(0)}x{pattern.GetLength(1)} != {_blockShapeData.width}x{_blockShapeData.height}"); return; } // 如果一致,就读取pattern,并设置对应的cell的SpriteRenderer是否激活 - for (int i = 0; i < width; i++) + for (int i = 0; i < _blockShapeData.width; i++) { - for (int j = 0; j < height; j++) + for (int j = 0; j < _blockShapeData.height; j++) { _cellRenderers[i, j].enabled = pattern[i, j] != 0; } } + LoadSprite(); // 更新碰撞体形状 UpdatePolygonCollider(); } + private void LoadSprite() + { + if (!string.IsNullOrEmpty(_blockShapeData.spritePath)) + { + var sprite = ResourceKit.LoadAssetSync(_blockShapeData.spritePath); + var renderer = GetComponent(); + renderer.sprite = sprite; + } + } + public void SaveShape() { // 如果_cellRenderers不为空,则序列化并保存 if (_cellRenderers != null) { - var pattern = new int[width, height]; - for (int i = 0; i < width; i++) + var pattern = new int[_blockShapeData.width, _blockShapeData.height]; + for (int i = 0; i < _blockShapeData.width; i++) { - for (int j = 0; j < height; j++) + for (int j = 0; j < _blockShapeData.height; j++) { pattern[i, j] = _cellRenderers[i, j].enabled ? 1 : 0; } } Debug.Log($"SaveShape: {CommonUtil.SerializeIntArray(pattern)}"); - originalPatternStr = CommonUtil.SerializeIntArray(pattern); - - // 保存后更新碰撞体 - UpdatePolygonCollider(); + _blockShapeData.originalPatternStr = CommonUtil.SerializeIntArray(pattern); + + var renderer = GetComponent(); + if (renderer != null && renderer.sprite != null) + { + Debug.Log($"SaveShape: {renderer.sprite.name}"); + if (ResourceKit.GetAssetAddressableKey(renderer.sprite, out string spritePath)) + { + _blockShapeData.spritePath = spritePath; + } + } } + + BlockPuzzleKit.SaveBlockShapeData(_blockShapeData, _blockShapeData.shapeName); + // 保存后更新碰撞体 + UpdatePolygonCollider(); } /// @@ -204,7 +423,7 @@ namespace AibisDream // 生成多边形顶点 List vertices = GeneratePolygonVertices(pattern); - + if (vertices.Count > 0) { // 设置多边形路径 @@ -225,7 +444,7 @@ namespace AibisDream { List vertices = new List(); - if (pattern == null || width <= 0 || height <= 0 || cellSize <= 0) + if (pattern == null || _blockShapeData.width <= 0 || _blockShapeData.height <= 0 || _blockShapeData.cellSize <= 0) return vertices; // 生成精确的外轮廓(只包含边界点) @@ -244,22 +463,22 @@ namespace AibisDream HashSet visitedPoints = new HashSet(); // 遍历所有格子,找到边界点 - for (int i = 0; i <= width; i++) + for (int i = 0; i <= _blockShapeData.width; i++) { - for (int j = 0; j <= height; j++) + for (int j = 0; j <= _blockShapeData.height; j++) { // 检查这个角点是否在边界上 bool isBoundaryCorner = IsBoundaryCorner(pattern, i, j); - + if (isBoundaryCorner) { // 计算角点的本地坐标 // cornerX 和 cornerY 是角点索引(0到width/height) // 需要转换为格子的角点坐标 // 角点 (i, j) 对应格子 (i-0.5, j-0.5) 的角点位置 - float x = (i - 0.5f) * cellSize; - float y = (j - 0.5f) * cellSize; - + float x = (i - 0.5f) * _blockShapeData.cellSize; + float y = (j - 0.5f) * _blockShapeData.cellSize; + Vector2Int key = new Vector2Int(Mathf.RoundToInt(x * 100), Mathf.RoundToInt(y * 100)); if (!visitedPoints.Contains(key)) { @@ -288,12 +507,12 @@ namespace AibisDream // 角点位于四个格子的交汇处 // 检查周围四个格子的状态 bool topLeft = (cornerX > 0 && cornerY > 0) ? pattern[cornerX - 1, cornerY - 1] != 0 : false; - bool topRight = (cornerX < width && cornerY > 0) ? pattern[cornerX, cornerY - 1] != 0 : false; - bool bottomLeft = (cornerX > 0 && cornerY < height) ? pattern[cornerX - 1, cornerY] != 0 : false; - bool bottomRight = (cornerX < width && cornerY < height) ? pattern[cornerX, cornerY] != 0 : false; + bool topRight = (cornerX < _blockShapeData.width && cornerY > 0) ? pattern[cornerX, cornerY - 1] != 0 : false; + bool bottomLeft = (cornerX > 0 && cornerY < _blockShapeData.height) ? pattern[cornerX - 1, cornerY] != 0 : false; + bool bottomRight = (cornerX < _blockShapeData.width && cornerY < _blockShapeData.height) ? pattern[cornerX, cornerY] != 0 : false; // 如果四个格子状态不一致,说明这个角点在边界上 - int filledCount = (topLeft ? 1 : 0) + (topRight ? 1 : 0) + + int filledCount = (topLeft ? 1 : 0) + (topRight ? 1 : 0) + (bottomLeft ? 1 : 0) + (bottomRight ? 1 : 0); // 边界角点:不是全部填充也不是全部空 @@ -309,12 +528,12 @@ namespace AibisDream List vertices = new List(); // 找到有效格子的边界 - int minX = width, maxX = -1, minY = height, maxY = -1; + int minX = _blockShapeData.width, maxX = -1, minY = _blockShapeData.height, maxY = -1; bool hasValidCell = false; - for (int i = 0; i < width; i++) + for (int i = 0; i < _blockShapeData.width; i++) { - for (int j = 0; j < height; j++) + for (int j = 0; j < _blockShapeData.height; j++) { if (pattern[i, j] != 0) { @@ -331,11 +550,11 @@ namespace AibisDream return vertices; // 计算包围盒的四个角点(本地坐标) - float halfSize = cellSize / 2f; - float minXWorld = minX * cellSize - width * cellSize / 2f - halfSize; - float maxXWorld = (maxX + 1) * cellSize - width * cellSize / 2f + halfSize; - float minYWorld = minY * cellSize - height * cellSize / 2f - halfSize; - float maxYWorld = (maxY + 1) * cellSize - height * cellSize / 2f + halfSize; + float halfSize = _blockShapeData.cellSize / 2f; + float minXWorld = minX * _blockShapeData.cellSize - _blockShapeData.width * _blockShapeData.cellSize / 2f - halfSize; + float maxXWorld = (maxX + 1) * _blockShapeData.cellSize - _blockShapeData.width * _blockShapeData.cellSize / 2f + halfSize; + float minYWorld = minY * _blockShapeData.cellSize - _blockShapeData.height * _blockShapeData.cellSize / 2f - halfSize; + float maxYWorld = (maxY + 1) * _blockShapeData.cellSize - _blockShapeData.height * _blockShapeData.cellSize / 2f + halfSize; // 按逆时针顺序添加顶点(Unity的PolygonCollider2D要求) vertices.Add(new Vector2(minXWorld, minYWorld)); // 左下 @@ -371,11 +590,25 @@ namespace AibisDream { return angleA.CompareTo(angleB); } - + return (a - center).sqrMagnitude.CompareTo((b - center).sqrMagnitude); }); return vertices; } + + + } + + [Serializable] + public struct BlockShapeData + { + public int shapeId; + public string shapeName; + public int width; + public int height; + public float cellSize; + public string originalPatternStr; + public string spritePath; } } \ No newline at end of file diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs deleted file mode 100644 index b352882d9..000000000 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeDragger.cs +++ /dev/null @@ -1,406 +0,0 @@ -using System; -using AibisDream.Framework; -using UnityEngine; -using UnityEngine.EventSystems; - -namespace AibisDream -{ - /// - /// 形状拖拽组件 - /// 实现IBlockShapeDragger接口,处理形状的拖拽、吸附和放置逻辑 - /// - [RequireComponent(typeof(BlockShape))] - [RequireComponent(typeof(EventTriggerEx))] - public class BlockShapeDragger : MonoBehaviour, IBlockShapeDragger - { - [Header("拖拽设置")] - [SerializeField] private bool isDraggable = true; - [SerializeField] private float snapDistance = 0.5f; - [SerializeField] private BlockPuzzleGrid targetGridComponent; // Unity组件引用 - - [Header("视觉反馈")] - [SerializeField] private Color snapColor = new Color(0f, 1f, 0f, 0.7f); - [SerializeField] private Color invalidColor = new Color(1f, 0f, 0f, 0.7f); - [SerializeField] private Color normalColor = Color.white; - [SerializeField] private float dragScale = 1.1f; - - // 拖拽状态 - private DragState _currentState = DragState.Idle; - private bool _isDragging = false; - private Vector3 _dragOffset; - private Vector3 _originalPosition; - private Vector3 _originalScale; - private int _originalSortingOrder; - private bool _isSnapping = false; - private int _snapGridX; - private int _snapGridY; - - // 组件引用 - private BlockShape _blockShape; - private SpriteRenderer _spriteRenderer; - private EventTriggerEx _eventTrigger; - - // 事件 - public event Action OnDragStart; - public event Action OnDragUpdate; - public event Action OnDragEnd; - public event Action OnSnap; - public event Action OnUnsnap; - - // 接口实现 - public DragState CurrentState => _currentState; - public bool IsDraggable { get => isDraggable; set => isDraggable = value; } - public IBlockPuzzleGrid TargetGrid - { - get => targetGridComponent; - set => targetGridComponent = value as BlockPuzzleGrid; - } - public float SnapDistance { get => snapDistance; set => snapDistance = value; } - - // 内部使用的网格引用 - private IBlockPuzzleGrid targetGrid => targetGridComponent; - - private void Awake() - { - _blockShape = GetComponent(); - _spriteRenderer = GetComponent(); - _eventTrigger = GetComponent(); - - RegisterEvent(); - } - - private void RegisterEvent() - { - _eventTrigger.Register(EventTriggerType.PointerClick, OnPointerClick); - } - - private void OnPointerClick(BaseEventData eventData) - { - if (eventData is not PointerEventData { button: PointerEventData.InputButton.Left }) - { - return; - } - - PointerEventData pointerEventData = eventData as PointerEventData; - - Vector3 mouseWorldPos = GetMouseWorldPosition(pointerEventData.position); - // 如果当前物体不在拖拽中则进入拖拽逻辑 - if (!_isDragging) - { - StartDrag(mouseWorldPos); - } - // 如果当前物体在拖拽中则取消拖拽 - else - { - CancelDrag(); - } - } - - public void StartDrag(Vector3 mouseWorldPos) - { - if (!isDraggable || _isDragging) return; - - _isDragging = true; - _currentState = DragState.Dragging; - _originalPosition = transform.position; - _originalScale = transform.localScale; - - // 计算拖拽偏移量 - _dragOffset = transform.position - mouseWorldPos; - - // 提升层级和缩放 - if (_spriteRenderer != null) - { - _originalSortingOrder = _spriteRenderer.sortingOrder; - _spriteRenderer.sortingOrder = 100; - } - - transform.localScale = _originalScale * dragScale; - - OnDragStart?.Invoke(_blockShape); - } - - public void UpdateDrag() - { - if (!_isDragging) return; - - Vector3 mouseWorldPos = GetMouseWorldPosition(Input.mousePosition); - Vector3 targetPosition = mouseWorldPos + _dragOffset; - - if (targetGrid != null) - { - // 检查吸附可能 - var snapResult = targetGrid.CheckSnapToGrid(_blockShape); - if (snapResult.canSnap) - { - // 可以吸附,保存吸附内容 - } - else - { - // 没有吸附,自由拖拽 - transform.position = targetPosition; - _currentState = DragState.Dragging; - } - } - else - { - // 没有网格,自由拖拽 - transform.position = targetPosition; - _currentState = DragState.Dragging; - } - - OnDragUpdate?.Invoke(_blockShape, transform.position); - } - - public void EndDrag() - { - if (!_isDragging) return; - - bool placed = false; - - if (_isSnapping && targetGrid != null) - { - // 尝试放置到网格 - if (CanPlaceAt(_snapGridX, _snapGridY)) - { - if (TryPlaceOnGrid(_snapGridX, _snapGridY)) - { - placed = true; - _currentState = DragState.Placed; - OnShapePlaced(); - } - } - } - - if (!placed) - { - // 返回原位置 - transform.position = _originalPosition; - _currentState = DragState.Idle; - } - - // 恢复原始状态 - transform.localScale = _originalScale; - if (_spriteRenderer != null) - { - _spriteRenderer.sortingOrder = _originalSortingOrder; - } - - ShowSnapPreview(false, false); - - _isDragging = false; - _isSnapping = false; - - OnDragEnd?.Invoke(_blockShape, placed); - } - - public void CancelDrag() - { - if (!_isDragging) return; - - transform.position = _originalPosition; - transform.localScale = _originalScale; - if (_spriteRenderer != null) - { - _spriteRenderer.sortingOrder = _originalSortingOrder; - } - - ShowSnapPreview(false, false); - - _isDragging = false; - _isSnapping = false; - _currentState = DragState.Idle; - - OnDragEnd?.Invoke(_blockShape, false); - } - - public bool CanPlaceAt(int gridX, int gridY) - { - if (targetGrid == null || _blockShape == null) return false; - - Vector2Int[] blockPositions = _blockShape.GetBlockPositions(); - if (blockPositions == null || blockPositions.Length == 0) return false; - - // 形状的坐标系统: - // - GetBlockPositions() 返回的坐标中,(0, 0) 是形状的左下角 - // - gridX, gridY 是形状左下角在网格中的位置 - // - 需要将形状的相对坐标转换为网格坐标 - foreach (var blockPos in blockPositions) - { - // 将形状的相对坐标转换为网格坐标(左下角为基准) - // 形状的 (0, 0) 对应网格的 (gridX, gridY) - // 形状的 (i, j) 对应网格的 (gridX + i, gridY + j) - int checkX = gridX + blockPos.x; - int checkY = gridY + blockPos.y; - - if (!targetGrid.IsValidPosition(checkX, checkY) || - !targetGrid.IsCellEmpty(checkX, checkY)) - { - return false; - } - } - - return true; - } - - public bool GetSnapGridPosition(out int gridX, out int gridY) - { - if (_isSnapping) - { - gridX = _snapGridX; - gridY = _snapGridY; - return true; - } - - gridX = 0; - gridY = 0; - return false; - } - - /// - /// 检查是否可以吸附到网格 - /// - private bool CheckSnapToGrid(Vector3 worldPos, out Vector3 snapPos, out int gridX, out int gridY) - { - snapPos = worldPos; - gridX = 0; - gridY = 0; - - if (targetGrid == null) return false; - - // 将世界坐标转换为网格坐标 - // 注意:WorldToGrid 需要世界坐标在网格范围内才能返回true - // 但我们需要检查所有附近的网格单元格,不仅仅是当前所在的单元格 - // 所以先尝试直接转换,如果失败则查找最近的网格单元格 - - int tempGridX, tempGridY; - bool inGrid = targetGrid.WorldToGrid(worldPos, out tempGridX, out tempGridY); - - if (!inGrid) - { - // 如果不在网格内,尝试查找最近的网格单元格 - // 计算最近的网格坐标 - Vector3 localPos = worldPos - targetGrid.Origin; - tempGridX = Mathf.FloorToInt(localPos.x / targetGrid.CellSize); - tempGridY = Mathf.FloorToInt(localPos.y / targetGrid.CellSize); - - // 检查是否在有效范围内 - if (!targetGrid.IsValidPosition(tempGridX, tempGridY)) - { - return false; - } - } - - // 获取网格单元格中心的世界坐标 - Vector3 gridCenter = targetGrid.GridToWorld(tempGridX, tempGridY); - - // 计算距离 - float distance = Vector3.Distance(worldPos, gridCenter); - - if (distance <= snapDistance) - { - // 计算形状应该放置的网格位置 - // 形状左下角对齐到网格单元格左下角 - gridX = tempGridX; - gridY = tempGridY; - - // 计算形状左下角的世界坐标 - // 网格单元格左下角的世界坐标 = Origin + (gridX * CellSize, gridY * CellSize) - Vector3 gridBottomLeft = targetGrid.Origin + new Vector3( - gridX * targetGrid.CellSize, - gridY * targetGrid.CellSize, - 0 - ); - - // 计算形状中心相对于形状左下角的偏移 - // 形状的 pattern 中,(0, 0) 是左下角 - // 在形状的本地坐标系中(假设形状中心在 (0, 0)),形状左下角的位置是: - // localX = -width * cellSize / 2 - // localY = -height * cellSize / 2 - // 形状中心相对于形状左下角的偏移 = (0, 0) - (localX, localY) = (width * cellSize / 2, height * cellSize / 2) - - // 形状左下角对齐到网格单元格左下角 - // 形状中心的世界坐标 = 网格单元格左下角的世界坐标 + 形状中心相对于形状左下角的偏移 - // 使用网格的 CellSize,因为形状的 cellSize 应该与网格的 CellSize 相同 - float shapeCenterOffsetX = _blockShape.Width * targetGrid.CellSize / 2f; - float shapeCenterOffsetY = _blockShape.Height * targetGrid.CellSize / 2f; - snapPos = gridBottomLeft + new Vector3(shapeCenterOffsetX, shapeCenterOffsetY, 0); - - return true; - } - - return false; - } - - /// - /// 尝试放置到网格 - /// - /// 网格X坐标(形状左下角位置) - /// 网格Y坐标(形状左下角位置) - private bool TryPlaceOnGrid(int gridX, int gridY) - { - if (!CanPlaceAt(gridX, gridY)) return false; - - Vector2Int[] blockPositions = _blockShape.GetBlockPositions(); - if (blockPositions == null) return false; - - // 形状的坐标系统: - // - GetBlockPositions() 返回的坐标中,(0, 0) 是形状的左下角 - // - gridX, gridY 是形状左下角在网格中的位置 - // - 需要将形状的相对坐标转换为网格坐标 - foreach (var blockPos in blockPositions) - { - // 将形状的相对坐标转换为网格坐标(左下角为基准) - // 形状的 (0, 0) 对应网格的 (gridX, gridY) - // 形状的 (i, j) 对应网格的 (gridX + i, gridY + j) - int x = gridX + blockPos.x; - int y = gridY + blockPos.y; - targetGrid.SetCellState(x, y, GridCellState.Occupied); - } - - return true; - } - - /// - /// 显示吸附预览效果 - /// - private void ShowSnapPreview(bool show, bool isValid) - { - Color previewColor = show ? (isValid ? snapColor : invalidColor) : normalColor; - - // 更新主SpriteRenderer - if (_spriteRenderer != null) - { - _spriteRenderer.color = previewColor; - } - } - - /// - /// 形状放置完成 - /// - private void OnShapePlaced() - { - // 可以在这里添加放置后的逻辑 - // 例如:禁用拖拽、播放动画等 - isDraggable = false; - } - - /// - /// 获取鼠标世界坐标 - /// - private Vector3 GetMouseWorldPosition(Vector3 mousePos) - { - var pos = Camera.main.ScreenToWorldPoint(mousePos); - return new Vector3(pos.x, pos.y, 0); - } - - private void OnDisable() - { - if (_isDragging) - { - CancelDrag(); - } - } - } -} - diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs new file mode 100644 index 000000000..41b396f1e --- /dev/null +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using AibisDream.Framework; +using AibisDream.Utility; +using UnityEngine; +using UnityEngine.UI; + +namespace AibisDream +{ + public class BlockShapeRack : MonoBehaviour, IBlockShapeFactory + { + [SerializeField] private Transform shapeRoot; + [SerializeField] private ScrollRect scrollRect; + [SerializeField] private RackDataInfo[] blockShapeDataList; + private Dictionary buttonDict; + private GameObject _shapeCreateButtonPrefab; + + private void Awake() + { + InitPrefab(); + InitShapeButtons(); + } + + private void InitPrefab() + { + _shapeCreateButtonPrefab = ResourceKit.LoadAssetSync(ConstRef.ShapeCreateButtonPrefab); + _blockShapePrefab = ResourceKit.LoadAssetSync(ConstRef.BlockShapePrefab); + } + + private void InitShapeButtons() + { + buttonDict = new Dictionary(); + foreach (var blockShapeData in blockShapeDataList) + { + var button = Instantiate(_shapeCreateButtonPrefab, scrollRect.content).GetComponent(); + button.SetButtonInfo(blockShapeData.key, blockShapeData.count); + button.OnClick += CreateShapeByButton; + buttonDict.Add(blockShapeData.key, button); + } + } + + private void CreateShapeByButton(string key) + { + // 获取配置信息 + if (!BlockPuzzleKit.TryLoadBlockShapeData(key, out var blockShapeData)) + { + Debug.LogError($"获取配置信息失败: {key}"); + return; + } + + // 创建形状并开始拖拽 + var blockShape = CreateBlockShape(blockShapeData); + blockShape.ShapeDragger.StartDrag(); + } + + public void RecycleBlockShape(BlockShape blockShape) + { + // 将数据加回对象池 + if (buttonDict.TryGetValue(blockShape.ShapeName, out var oldButton)) + { + oldButton.AddCount(); + } + else + { + // 创建新的按钮 + var button = Instantiate(_shapeCreateButtonPrefab, scrollRect.content).GetComponent(); + button.SetButtonInfo(blockShape.ShapeName, 1); + button.OnClick += CreateShapeByButton; + buttonDict.Add(blockShape.ShapeName, button); + } + // 销毁物体 + Destroy(blockShape.gameObject); + } + + + // ------------------------------ 图形工厂类实现 ------------------------------ + + private GameObject _blockShapePrefab; + + public BlockShape CreateBlockShape(BlockShapeData blockShapeData) + { + var blockShape = Instantiate(_blockShapePrefab, shapeRoot).GetComponent(); + blockShape.Init(blockShapeData); + return blockShape; + } + + [Serializable] + public struct RackDataInfo + { + public string key; + public int count; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs.meta b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs.meta new file mode 100644 index 000000000..6fe354b0f --- /dev/null +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/BlockShapeRack.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b41fe99d78fb92428bd63b641c3944c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/PlacementValidator.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/PlacementValidator.cs index 9e5fdc984..01ef8daab 100644 --- a/Assets/Scripts/MiniGame/BlockPuzzle/Class/PlacementValidator.cs +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/PlacementValidator.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using UnityEngine; namespace AibisDream @@ -9,283 +8,120 @@ namespace AibisDream /// public static class PlacementValidator { - /// - /// 检查形状是否可以放置在指定位置 - /// - /// 网格系统 - /// 要放置的形状 - /// 网格X坐标(形状左下角位置) - /// 网格Y坐标(形状左下角位置) - /// 放置验证结果 - public static PlacementResult CanPlace(IBlockPuzzleGrid grid, IBlockShape shape, int gridX, int gridY) - { - if (grid == null || shape == null) - { - return PlacementResult.InvalidPosition; - } - - // 获取形状的所有格子位置(相对坐标,基于形状的本地坐标系) - Vector2Int[] blockPositions = shape.GetBlockPositions(); - if (blockPositions == null || blockPositions.Length == 0) - { - return PlacementResult.InvalidPosition; - } - - // 形状的坐标系统: - // - GetBlockPositions() 返回的坐标中,(0, 0) 是形状的左下角 - // - pattern[i, j] 中,i 是 x(从左到右),j 是 y(从下到上,j=0 是底部) - // - gridX, gridY 是形状左下角在网格中的位置 - // - 需要将形状的相对坐标转换为网格坐标 - foreach (var blockPos in blockPositions) - { - // 将形状的相对坐标转换为网格坐标 - // 形状的 (0, 0) 对应网格的 (gridX, gridY) - // 形状的 (i, j) 对应网格的 (gridX + i, gridY + j) - int gridCellX = gridX + blockPos.x; - int gridCellY = gridY + blockPos.y; - - // 检查是否超出边界 - if (!grid.IsValidPosition(gridCellX, gridCellY)) - { - return PlacementResult.OutOfBounds; - } - - // 检查是否与已有块重叠 - if (!grid.IsCellEmpty(gridCellX, gridCellY)) - { - return PlacementResult.Overlap; - } - } - - return PlacementResult.Success; - } - - /// - /// 检查形状是否可以放置在指定位置(详细版本) - /// - /// 网格系统 - /// 要放置的形状 - /// 网格X坐标(形状左下角位置) - /// 网格Y坐标(形状左下角位置) - /// 失败原因(如果返回false) - /// 是否可以放置 - public static bool CanPlaceDetailed(IBlockPuzzleGrid grid, IBlockShape shape, int gridX, int gridY, out PlacementResult failureReason) - { - failureReason = CanPlace(grid, shape, gridX, gridY); - return failureReason == PlacementResult.Success; - } - - /// - /// 获取形状在指定位置的所有占用格子坐标 - /// - /// 形状 - /// 网格X坐标(形状左下角位置) - /// 网格Y坐标(形状左下角位置) - /// 占用格子的网格坐标数组 - public static (int x, int y)[] GetOccupiedCells(IBlockShape shape, int gridX, int gridY) - { - if (shape == null) - { - return new (int x, int y)[0]; - } - - Vector2Int[] blockPositions = shape.GetBlockPositions(); - if (blockPositions == null || blockPositions.Length == 0) - { - return new (int x, int y)[0]; - } - - List<(int x, int y)> occupiedCells = new List<(int x, int y)>(); - - foreach (var blockPos in blockPositions) - { - // 将形状的相对坐标转换为网格坐标(左下角为基准) - // 形状的 (0, 0) 对应网格的 (gridX, gridY) - // 形状的 (i, j) 对应网格的 (gridX + i, gridY + j) - int gridCellX = gridX + blockPos.x; - int gridCellY = gridY + blockPos.y; - occupiedCells.Add((gridCellX, gridCellY)); - } - - return occupiedCells.ToArray(); - } - - - /// - /// 将形状的单个相对坐标转换为网格坐标 - /// - /// 形状内的X坐标(相对坐标,相对于形状左下角) - /// 形状内的Y坐标(相对坐标,相对于形状左下角) - /// 网格X坐标(形状左下角位置) - /// 网格Y坐标(形状左下角位置) - /// 对应的网格坐标 - public static Vector2Int ConvertShapeLocalToGrid(int shapeLocalX, int shapeLocalY, int gridX, int gridY) - { - return new Vector2Int(gridX + shapeLocalX, gridY + shapeLocalY); - } - - /// - /// 检查世界坐标是否可以吸附到网格 - /// - /// 网格系统 - /// 世界坐标位置 - /// 吸附距离阈值 - /// 吸附检测结果 - public static SnapResult CheckSnapToGrid(IBlockPuzzleGrid grid, Vector3 worldPos, float snapDistance) + public static SnapResult CheckSnapToGrid(this IBlockPuzzleGrid grid, BlockShape shape) { + // 预制错误结果作为返回值 SnapResult result = new SnapResult { canSnap = false, - snapPosition = worldPos, + snapPosition = shape.transform.position, gridX = 0, gridY = 0, - distance = float.MaxValue + distance = float.MaxValue, + gridPositions = new Vector2Int[0] }; - if (grid == null) - { - return result; - } + // 将Shape的世界坐标转换为网格坐标(可以是虚拟坐标) + bool inGrid = grid.WorldToGrid(shape.transform.position, out int gridX, out int gridY); + if (!inGrid) return result; - // 将世界坐标转换为网格坐标 - // 注意:WorldToGrid 需要世界坐标在网格范围内才能返回true - // 但我们需要检查所有附近的网格单元格,不仅仅是当前所在的单元格 - // 所以先尝试直接转换,如果失败则查找最近的网格单元格 + // 将形状的所有格子转换为网格坐标 + // gridX, gridY 是形状的 (0, 0) 点在网格中的位置 + Vector2Int[] gridCells = ConvertShapeToGridCells(shape, gridX, gridY); + result.gridX = gridX; + result.gridY = gridY; + result.snapPosition = grid.GridToWorld(gridX, gridY); + result.gridPositions = gridCells; - int tempGridX, tempGridY; - bool inGrid = grid.WorldToGrid(worldPos, out tempGridX, out tempGridY); - - if (!inGrid) - { - // 如果不在网格内,尝试查找最近的网格单元格 - // 计算最近的网格坐标 - Vector3 localPos = worldPos - grid.Origin; - tempGridX = Mathf.FloorToInt(localPos.x / grid.CellSize); - tempGridY = Mathf.FloorToInt(localPos.y / grid.CellSize); - - // 检查是否在有效范围内 - if (!grid.IsValidPosition(tempGridX, tempGridY)) - { - return result; - } - } - - // 获取网格单元格中心的世界坐标 - Vector3 gridCenter = grid.GridToWorld(tempGridX, tempGridY); - - // 计算距离 - float distance = Vector3.Distance(worldPos, gridCenter); - - if (distance <= snapDistance) - { - // 计算形状应该放置的网格位置 - // 形状左下角对齐到网格单元格左下角 - result.gridX = tempGridX; - result.gridY = tempGridY; - - // 计算形状左下角的世界坐标 - // 网格单元格左下角的世界坐标 = Origin + (gridX * CellSize, gridY * CellSize) - Vector3 gridBottomLeft = grid.Origin + new Vector3( - tempGridX * grid.CellSize, - tempGridY * grid.CellSize, - 0 - ); - - result.snapPosition = gridBottomLeft; - result.distance = distance; - result.canSnap = true; - } + // 逐个坐标验证是否可以放置 + var canPlace = grid.CanPlace(gridCells); + if (!canPlace) return result; + result.canSnap = true; + result.distance = Vector3.Distance(shape.transform.position, result.snapPosition); return result; } /// - /// 检查世界坐标是否可以吸附到网格(简化版本,只返回是否可以吸附和网格坐标) + /// 将形状的相对坐标转换为网格坐标 + /// 已知形状的 (0, 0) 点在网格中的位置为 (gridX, gridY),将形状的其他格子坐标转换为网格坐标 /// - /// 网格系统 - /// 世界坐标位置 - /// 吸附距离阈值 - /// 吸附到的网格X坐标(形状左下角位置) - /// 吸附到的网格Y坐标(形状左下角位置) - /// 是否可以吸附 - public static bool CheckSnapToGrid(IBlockPuzzleGrid grid, Vector3 worldPos, float snapDistance, out int gridX, out int gridY) + /// 形状 + /// 网格X坐标(形状左下角位置,即形状的 (0, 0) 点对应的网格坐标) + /// 网格Y坐标(形状左下角位置,即形状的 (0, 0) 点对应的网格坐标) + /// 形状所有格子在网格中的坐标数组 + public static Vector2Int[] ConvertShapeToGridCells(IBlockShape shape, int gridX, int gridY) { - gridX = 0; - gridY = 0; - - SnapResult result = CheckSnapToGrid(grid, worldPos, snapDistance); - if (result.canSnap) + if (shape == null) { - gridX = result.gridX; - gridY = result.gridY; - return true; + return new Vector2Int[0]; } - return false; + Vector2Int[] blockPositions = shape.GetBlockPositions(); + if (blockPositions == null || blockPositions.Length == 0) + { + return new Vector2Int[0]; + } + + Vector2Int[] gridCells = new Vector2Int[blockPositions.Length]; + Vector2Int axis = shape.GetAxis(); + + for (int i = 0; i < blockPositions.Length; i++) + { + // 将形状的相对坐标转换为网格坐标 + // 形状的 (0, 0) 对应网格的 (gridX, gridY) + // 形状的 (blockPos.x, blockPos.y) 对应网格的 (gridX + blockPos.x, gridY + blockPos.y) + gridCells[i] = new Vector2Int( + gridX + blockPositions[i].x * axis.x, + gridY + blockPositions[i].y * axis.y + ); + } + + return gridCells; } /// - /// 检查世界坐标是否可以吸附到网格(完整版本,返回吸附位置和网格坐标) + /// 为吸附制作预览 /// - /// 网格系统 - /// 世界坐标位置 - /// 吸附距离阈值 - /// 吸附后的世界坐标位置 - /// 吸附到的网格X坐标(形状左下角位置) - /// 吸附到的网格Y坐标(形状左下角位置) - /// 是否可以吸附 - public static bool CheckSnapToGrid(IBlockPuzzleGrid grid, Vector3 worldPos, float snapDistance, out Vector3 snapPos, out int gridX, out int gridY) + /// 转换后的网格坐标组 + public static void ShowSnapPreview(this IBlockPuzzleGrid grid, Vector2Int[] shapeCells) { - snapPos = worldPos; - gridX = 0; - gridY = 0; - SnapResult result = CheckSnapToGrid(grid, worldPos, snapDistance); - if (result.canSnap) + } + + public static void TrySnapToGrid(this IBlockPuzzleGrid grid, BlockShape shape, Vector2Int rootCell) + { + // 判断RootCell的位置 + var rootWorldPos = grid.GridToWorld(rootCell.x, rootCell.y); + // 已经判断是否可吸附,直接吸就好了 + shape.transform.position = rootWorldPos; + // 设置网格状态 + var shapeCells = ConvertShapeToGridCells(shape, rootCell.x, rootCell.y); + foreach (var cell in shapeCells) { - snapPos = result.snapPosition; - gridX = result.gridX; - gridY = result.gridY; - return true; + grid.SetCellState(cell.x, cell.y, GridCellState.Occupied); } - - return false; + // 加入网格 + grid.ShapeDict.Add(shape, rootCell); } /// - /// 查找最近的网格单元格(即使不在吸附距离内) + /// 尝试从网格中移除形状 /// - /// 网格系统 - /// 世界坐标位置 - /// 最近的网格X坐标 - /// 最近的网格Y坐标 - /// 是否找到有效的网格单元格 - public static bool FindNearestGridCell(IBlockPuzzleGrid grid, Vector3 worldPos, out int gridX, out int gridY) + /// 网格 + /// 形状 + public static void TryRemoveShapeFromGrid(this IBlockPuzzleGrid grid, BlockShape shape) { - gridX = 0; - gridY = 0; - - if (grid == null) + if (grid.ShapeDict.TryGetValue(shape, out var rootCell)) { - return false; + // 设置网格状态 + var shapeCells = ConvertShapeToGridCells(shape, rootCell.x, rootCell.y); + foreach (var cell in shapeCells) + { + grid.SetCellState(cell.x, cell.y, GridCellState.Empty); + } + grid.ShapeDict.Remove(shape); } - - // 先尝试直接转换 - if (grid.WorldToGrid(worldPos, out gridX, out gridY)) - { - return true; - } - - // 如果不在网格内,计算最近的网格坐标 - Vector3 localPos = worldPos - grid.Origin; - gridX = Mathf.FloorToInt(localPos.x / grid.CellSize); - gridY = Mathf.FloorToInt(localPos.y / grid.CellSize); - - // 限制在有效范围内 - gridX = Mathf.Clamp(gridX, 0, grid.Width - 1); - gridY = Mathf.Clamp(gridY, 0, grid.Height - 1); - - return grid.IsValidPosition(gridX, gridY); } } diff --git a/Assets/Scripts/MiniGame/BlockPuzzle/Class/ShapeCreateButton.cs b/Assets/Scripts/MiniGame/BlockPuzzle/Class/ShapeCreateButton.cs new file mode 100644 index 000000000..dee37cca4 --- /dev/null +++ b/Assets/Scripts/MiniGame/BlockPuzzle/Class/ShapeCreateButton.cs @@ -0,0 +1,53 @@ +using System; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +namespace AibisDream +{ + [RequireComponent(typeof(Button))] + public class ShapeCreateButton : MonoBehaviour + { + [SerializeField] private Button button; + [SerializeField] private TMP_Text text; + + private string blockShapeKey; + private int count; + + public event Action OnClick; + + private void Awake() + { + GetComponent