mirror of
https://github.com/BobbyRafael31/Unity-MazeRunner-Pathfinding-Visualizer.git
synced 2025-08-13 08:52:21 +00:00
Feat\Fix: Adding some test for pathfinding and limit input access during pathfinnding
This commit is contained in:
@ -974,6 +974,173 @@ MonoBehaviour:
|
|||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
m_ShowMaskGraphic: 0
|
m_ShowMaskGraphic: 0
|
||||||
|
--- !u!1 &111507929
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 111507930}
|
||||||
|
- component: {fileID: 111507932}
|
||||||
|
- component: {fileID: 111507931}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Fill
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &111507930
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 111507929}
|
||||||
|
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: 1980971369}
|
||||||
|
m_RootOrder: -1
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 0, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 10, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &111507931
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 111507929}
|
||||||
|
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!222 &111507932
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 111507929}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &115484931
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 115484932}
|
||||||
|
- component: {fileID: 115484933}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Slider
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &115484932
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 115484931}
|
||||||
|
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: 915989142}
|
||||||
|
- {fileID: 1980971369}
|
||||||
|
- {fileID: 351573955}
|
||||||
|
m_Father: {fileID: 873489265}
|
||||||
|
m_RootOrder: -1
|
||||||
|
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: 661, y: -494}
|
||||||
|
m_SizeDelta: {x: 160, y: 20}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &115484933
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 115484931}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, 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: 813565619}
|
||||||
|
m_FillRect: {fileID: 111507930}
|
||||||
|
m_HandleRect: {fileID: 813565618}
|
||||||
|
m_Direction: 0
|
||||||
|
m_MinValue: 0
|
||||||
|
m_MaxValue: 1
|
||||||
|
m_WholeNumbers: 0
|
||||||
|
m_Value: 0
|
||||||
|
m_OnValueChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
--- !u!1 &115565369
|
--- !u!1 &115565369
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -2212,6 +2379,96 @@ CanvasRenderer:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 332997443}
|
m_GameObject: {fileID: 332997443}
|
||||||
m_CullTransparentMesh: 1
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &351573954
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 351573955}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Handle Slide Area
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &351573955
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 351573954}
|
||||||
|
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: 813565618}
|
||||||
|
m_Father: {fileID: 115484932}
|
||||||
|
m_RootOrder: -1
|
||||||
|
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: -20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &371969815
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 371969817}
|
||||||
|
- component: {fileID: 371969816}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Test
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 0
|
||||||
|
--- !u!114 &371969816
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 371969815}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: ed03b279fa9f3194f8caed356ea838dc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
gridMap: {fileID: 1193653632}
|
||||||
|
npc: {fileID: 497641072}
|
||||||
|
startTestButton: {fileID: 1287641230}
|
||||||
|
statusText: {fileID: 1778780372}
|
||||||
|
progressBar: {fileID: 115484933}
|
||||||
|
testsPerCombination: 3
|
||||||
|
delayBetweenTests: 0.5
|
||||||
|
saveResultsToFile: 1
|
||||||
|
resultsFileName: pathfinding_tests.csv
|
||||||
|
--- !u!4 &371969817
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 371969815}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 1324.0585, y: 547.7678, z: -5.158931}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_RootOrder: 9
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1 &375331086
|
--- !u!1 &375331086
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -4605,6 +4862,82 @@ CanvasRenderer:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 809150985}
|
m_GameObject: {fileID: 809150985}
|
||||||
m_CullTransparentMesh: 1
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &813565617
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 813565618}
|
||||||
|
- component: {fileID: 813565620}
|
||||||
|
- component: {fileID: 813565619}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Handle
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &813565618
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 813565617}
|
||||||
|
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: 351573955}
|
||||||
|
m_RootOrder: -1
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 0, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &813565619
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 813565617}
|
||||||
|
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: 10913, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 0
|
||||||
|
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 &813565620
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 813565617}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
--- !u!1 &814740740
|
--- !u!1 &814740740
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -4829,9 +5162,11 @@ MonoBehaviour:
|
|||||||
loadButton: {fileID: 332997445}
|
loadButton: {fileID: 332997445}
|
||||||
exitButton: {fileID: 1403363528}
|
exitButton: {fileID: 1403363528}
|
||||||
performWarmup: 1
|
performWarmup: 1
|
||||||
showWarmupMessage: 0
|
showWarmupMessage: 1
|
||||||
mazeSizeDropdown: {fileID: 770082012}
|
mazeSizeDropdown: {fileID: 770082012}
|
||||||
mazeDensityDropdown: {fileID: 1448650261}
|
mazeDensityDropdown: {fileID: 1448650261}
|
||||||
|
testerPanelPrefab: {fileID: 0}
|
||||||
|
testerPanelParent: {fileID: 0}
|
||||||
--- !u!4 &840407876
|
--- !u!4 &840407876
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -5023,6 +5358,45 @@ MonoBehaviour:
|
|||||||
m_isRichTextEditingAllowed: 0
|
m_isRichTextEditingAllowed: 0
|
||||||
m_LineLimit: 0
|
m_LineLimit: 0
|
||||||
m_InputValidator: {fileID: 0}
|
m_InputValidator: {fileID: 0}
|
||||||
|
--- !u!1 &873489264
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 873489265}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Test
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 0
|
||||||
|
--- !u!224 &873489265
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 873489264}
|
||||||
|
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: 1287641229}
|
||||||
|
- {fileID: 1778780371}
|
||||||
|
- {fileID: 115484932}
|
||||||
|
m_Father: {fileID: 1261321007}
|
||||||
|
m_RootOrder: -1
|
||||||
|
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: -150, y: 155}
|
||||||
|
m_SizeDelta: {x: 100, y: 100}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!1 &877190939
|
--- !u!1 &877190939
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -5158,6 +5532,82 @@ CanvasRenderer:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 877190939}
|
m_GameObject: {fileID: 877190939}
|
||||||
m_CullTransparentMesh: 1
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &915989141
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 915989142}
|
||||||
|
- component: {fileID: 915989144}
|
||||||
|
- component: {fileID: 915989143}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Background
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &915989142
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 915989141}
|
||||||
|
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: 115484932}
|
||||||
|
m_RootOrder: -1
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0.25}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.75}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &915989143
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 915989141}
|
||||||
|
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 &915989144
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 915989141}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
--- !u!1 &924975606
|
--- !u!1 &924975606
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -7627,6 +8077,7 @@ RectTransform:
|
|||||||
- {fileID: 442352525}
|
- {fileID: 442352525}
|
||||||
- {fileID: 1963564225}
|
- {fileID: 1963564225}
|
||||||
- {fileID: 1649005401}
|
- {fileID: 1649005401}
|
||||||
|
- {fileID: 873489265}
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 5
|
m_RootOrder: 5
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
@ -7711,6 +8162,128 @@ CanvasRenderer:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1269161862}
|
m_GameObject: {fileID: 1269161862}
|
||||||
m_CullTransparentMesh: 1
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &1287641228
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1287641229}
|
||||||
|
- component: {fileID: 1287641232}
|
||||||
|
- component: {fileID: 1287641231}
|
||||||
|
- component: {fileID: 1287641230}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Button
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1287641229
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1287641228}
|
||||||
|
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: 1956300463}
|
||||||
|
m_Father: {fileID: 873489265}
|
||||||
|
m_RootOrder: -1
|
||||||
|
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: 166, y: -494}
|
||||||
|
m_SizeDelta: {x: 160, y: 30}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &1287641230
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1287641228}
|
||||||
|
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: 1287641231}
|
||||||
|
m_OnClick:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
--- !u!114 &1287641231
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1287641228}
|
||||||
|
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!222 &1287641232
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1287641228}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
--- !u!1 &1383327469
|
--- !u!1 &1383327469
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -11124,6 +11697,141 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
m_Padding: {x: -8, y: -5, z: -8, w: -5}
|
m_Padding: {x: -8, y: -5, z: -8, w: -5}
|
||||||
m_Softness: {x: 0, y: 0}
|
m_Softness: {x: 0, y: 0}
|
||||||
|
--- !u!1 &1778780370
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1778780371}
|
||||||
|
- component: {fileID: 1778780373}
|
||||||
|
- component: {fileID: 1778780372}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Status
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1778780371
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778780370}
|
||||||
|
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: 873489265}
|
||||||
|
m_RootOrder: -1
|
||||||
|
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: 665.35645, y: -406.85294}
|
||||||
|
m_SizeDelta: {x: 196.7319, y: 125.3129}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &1778780372
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778780370}
|
||||||
|
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: New Text
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||||
|
m_fontSharedMaterials: []
|
||||||
|
m_fontMaterial: {fileID: 0}
|
||||||
|
m_fontMaterials: []
|
||||||
|
m_fontColor32:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontColor: {r: 1, g: 1, b: 1, 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: 25
|
||||||
|
m_fontSizeBase: 36
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 1
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 25
|
||||||
|
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 &1778780373
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778780370}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
--- !u!1 &1799536494
|
--- !u!1 &1799536494
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -12326,6 +13034,141 @@ CanvasRenderer:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1939810452}
|
m_GameObject: {fileID: 1939810452}
|
||||||
m_CullTransparentMesh: 1
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &1956300462
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1956300463}
|
||||||
|
- component: {fileID: 1956300465}
|
||||||
|
- component: {fileID: 1956300464}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Text (TMP)
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1956300463
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1956300462}
|
||||||
|
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: 1287641229}
|
||||||
|
m_RootOrder: -1
|
||||||
|
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 &1956300464
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1956300462}
|
||||||
|
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: Start
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, 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 &1956300465
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1956300462}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
--- !u!1 &1960286546
|
--- !u!1 &1960286546
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -12447,6 +13290,43 @@ CanvasRenderer:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1963564224}
|
m_GameObject: {fileID: 1963564224}
|
||||||
m_CullTransparentMesh: 1
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!1 &1980971368
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1980971369}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Fill Area
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1980971369
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1980971368}
|
||||||
|
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: 111507930}
|
||||||
|
m_Father: {fileID: 115484932}
|
||||||
|
m_RootOrder: -1
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0.25}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.75}
|
||||||
|
m_AnchoredPosition: {x: -5, y: 0}
|
||||||
|
m_SizeDelta: {x: -20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!1 &1982768388
|
--- !u!1 &1982768388
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -239,6 +239,15 @@ public class GridMap : MonoBehaviour
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void RayCastAndSetDestination()
|
public void RayCastAndSetDestination()
|
||||||
{
|
{
|
||||||
|
// Don't allow changing destination during pathfinding, visualization, or movement
|
||||||
|
if (npc != null && (npc.pathFinder?.Status == PathFinding.PathFinderStatus.RUNNING ||
|
||||||
|
npc.IsVisualizingPath ||
|
||||||
|
npc.IsMoving))
|
||||||
|
{
|
||||||
|
// Pathfinding, visualization or movement is in progress - ignore position change
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Konversi posisi mouse ke koordinat dunia
|
// Konversi posisi mouse ke koordinat dunia
|
||||||
Vector2 rayPos = new Vector2(
|
Vector2 rayPos = new Vector2(
|
||||||
Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
|
Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
|
||||||
@ -291,6 +300,15 @@ public class GridMap : MonoBehaviour
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void RayCastAndSetNPCPosition()
|
public void RayCastAndSetNPCPosition()
|
||||||
{
|
{
|
||||||
|
// Don't allow changing NPC position during pathfinding, visualization, or movement
|
||||||
|
if (npc != null && (npc.pathFinder?.Status == PathFinding.PathFinderStatus.RUNNING ||
|
||||||
|
npc.IsVisualizingPath ||
|
||||||
|
npc.IsMoving))
|
||||||
|
{
|
||||||
|
// Pathfinding, visualization or movement is in progress - ignore position change
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Konversi posisi mouse ke koordinat dunia
|
// Konversi posisi mouse ke koordinat dunia
|
||||||
Vector2 rayPos = new Vector2(
|
Vector2 rayPos = new Vector2(
|
||||||
Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
|
Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
|
||||||
@ -318,6 +336,11 @@ public class GridMap : MonoBehaviour
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
|
// Check if pathfinding, visualization, or movement is active
|
||||||
|
bool isPathfindingActive = npc != null && (npc.pathFinder?.Status == PathFinding.PathFinderStatus.RUNNING ||
|
||||||
|
npc.IsVisualizingPath ||
|
||||||
|
npc.IsMoving);
|
||||||
|
|
||||||
// Handle camera panning with middle mouse button
|
// Handle camera panning with middle mouse button
|
||||||
if (Input.GetMouseButton(2)) // Middle mouse button
|
if (Input.GetMouseButton(2)) // Middle mouse button
|
||||||
{
|
{
|
||||||
@ -336,6 +359,13 @@ public class GridMap : MonoBehaviour
|
|||||||
|
|
||||||
if (currentMousePosition != lastMousePosition)
|
if (currentMousePosition != lastMousePosition)
|
||||||
{
|
{
|
||||||
|
// If pathfinding is active, only allow camera movement, no interaction with grid
|
||||||
|
if (isPathfindingActive)
|
||||||
|
{
|
||||||
|
lastMousePosition = currentMousePosition;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Menggambar dinding dengan Shift+Left Click
|
// Menggambar dinding dengan Shift+Left Click
|
||||||
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
|
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
|
||||||
{
|
{
|
||||||
@ -357,7 +387,10 @@ public class GridMap : MonoBehaviour
|
|||||||
// Menetapkan tujuan baru saat tombol kanan mouse ditekan
|
// Menetapkan tujuan baru saat tombol kanan mouse ditekan
|
||||||
if (Input.GetMouseButtonDown(1))
|
if (Input.GetMouseButtonDown(1))
|
||||||
{
|
{
|
||||||
RayCastAndSetDestination();
|
if (!isPathfindingActive)
|
||||||
|
{
|
||||||
|
RayCastAndSetDestination();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Menyesuaikan ukuran kamera dengan scroll wheel
|
// Menyesuaikan ukuran kamera dengan scroll wheel
|
||||||
@ -698,8 +731,24 @@ public class GridMap : MonoBehaviour
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resizes the grid to the specified dimensions
|
/// Resizes the grid to the specified dimensions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ResizeGrid(int newSizeX, int newSizeY)
|
public bool ResizeGrid(int newSizeX, int newSizeY)
|
||||||
{
|
{
|
||||||
|
// Enforce grid size limits
|
||||||
|
const int MAX_GRID_SIZE = 200;
|
||||||
|
const int MIN_GRID_SIZE = 2;
|
||||||
|
|
||||||
|
if (newSizeX > MAX_GRID_SIZE || newSizeY > MAX_GRID_SIZE)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Attempted to resize grid beyond maximum size of {MAX_GRID_SIZE}x{MAX_GRID_SIZE}. Operation cancelled.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSizeX < MIN_GRID_SIZE || newSizeY < MIN_GRID_SIZE)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Attempted to resize grid below minimum size of {MIN_GRID_SIZE}x{MIN_GRID_SIZE}. Operation cancelled.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up existing grid
|
// Clean up existing grid
|
||||||
if (gridNodeViews != null)
|
if (gridNodeViews != null)
|
||||||
{
|
{
|
||||||
@ -749,6 +798,8 @@ public class GridMap : MonoBehaviour
|
|||||||
{
|
{
|
||||||
npc.SetStartNode(gridNodeViews[0, 0].Node);
|
npc.SetStartNode(gridNodeViews[0, 0].Node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -771,7 +822,53 @@ public class GridMap : MonoBehaviour
|
|||||||
/// <param name="wallDensity">Kepadatan dinding dalam persen (0-100), mempengaruhi rasio jalur terhadap ruang terbuka</param>
|
/// <param name="wallDensity">Kepadatan dinding dalam persen (0-100), mempengaruhi rasio jalur terhadap ruang terbuka</param>
|
||||||
public void GenerateRandomMaze(float density = 35f)
|
public void GenerateRandomMaze(float density = 35f)
|
||||||
{
|
{
|
||||||
// Use the recursive backtracking maze generation
|
// Handle special cases for 0% and 100% density
|
||||||
|
if (density <= 0f)
|
||||||
|
{
|
||||||
|
// Make all cells walkable (no walls)
|
||||||
|
for (int x = 0; x < numX; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < numY; y++)
|
||||||
|
{
|
||||||
|
GridNode node = GetGridNode(x, y);
|
||||||
|
if (node != null)
|
||||||
|
{
|
||||||
|
node.IsWalkable = true;
|
||||||
|
GridNodeView gnv = GetGridNodeView(x, y);
|
||||||
|
if (gnv != null)
|
||||||
|
{
|
||||||
|
gnv.SetInnerColor(COLOR_WALKABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (density >= 100f)
|
||||||
|
{
|
||||||
|
// Make all cells non-walkable (all walls)
|
||||||
|
for (int x = 0; x < numX; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < numY; y++)
|
||||||
|
{
|
||||||
|
GridNode node = GetGridNode(x, y);
|
||||||
|
if (node != null)
|
||||||
|
{
|
||||||
|
node.IsWalkable = false;
|
||||||
|
GridNodeView gnv = GetGridNodeView(x, y);
|
||||||
|
if (gnv != null)
|
||||||
|
{
|
||||||
|
gnv.SetInnerColor(COLOR_NONWALKABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No path creation - truly 100% blocked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the recursive backtracking maze generation for normal density values
|
||||||
GenerateRecursiveBacktrackingMaze(density);
|
GenerateRecursiveBacktrackingMaze(density);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,9 +21,12 @@ public struct PathfindingMetrics
|
|||||||
public float totalGCost; // Total biaya G untuk jalur (jarak sebenarnya)
|
public float totalGCost; // Total biaya G untuk jalur (jarak sebenarnya)
|
||||||
public float totalHCost; // Total biaya H untuk jalur (heuristik)
|
public float totalHCost; // Total biaya H untuk jalur (heuristik)
|
||||||
public float totalFCost; // Total biaya F untuk jalur (G + H)
|
public float totalFCost; // Total biaya F untuk jalur (G + H)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// NPC adalah komponen utama yang mengelola pergerakan NPC dalam sistem pathfinding.
|
||||||
|
/// Kelas ini bertanggung jawab untuk membuat, menampilkan, dan mengelola jalur untuk NPC.
|
||||||
|
/// </summary>
|
||||||
public class NPC : MonoBehaviour
|
public class NPC : MonoBehaviour
|
||||||
{
|
{
|
||||||
public float speed = 2.0f;
|
public float speed = 2.0f;
|
||||||
@ -32,6 +35,12 @@ public class NPC : MonoBehaviour
|
|||||||
// Event that fires when pathfinding is complete with performance metrics
|
// Event that fires when pathfinding is complete with performance metrics
|
||||||
public event Action<PathfindingMetrics> OnPathfindingComplete;
|
public event Action<PathfindingMetrics> OnPathfindingComplete;
|
||||||
|
|
||||||
|
// Last measured memory usage (for accessing from outside)
|
||||||
|
public long LastMeasuredMemoryUsage { get; private set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enumerasi yang merepresentasikan berbagai algoritma pathfinding yang tersedia.
|
||||||
|
/// </summary>
|
||||||
public enum PathFinderType
|
public enum PathFinderType
|
||||||
{
|
{
|
||||||
ASTAR,
|
ASTAR,
|
||||||
@ -44,13 +53,26 @@ public class NPC : MonoBehaviour
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
public PathFinderType pathFinderType = PathFinderType.ASTAR;
|
public PathFinderType pathFinderType = PathFinderType.ASTAR;
|
||||||
|
|
||||||
PathFinder<Vector2Int> pathFinder = null;
|
public PathFinder<Vector2Int> pathFinder = null;
|
||||||
|
|
||||||
public GridMap Map { get; set; }
|
public GridMap Map { get; set; }
|
||||||
|
|
||||||
// List to store all steps for visualization playback
|
// List to store all steps for visualization playback
|
||||||
private List<PathfindingVisualizationStep> visualizationSteps = new List<PathfindingVisualizationStep>();
|
private List<PathfindingVisualizationStep> visualizationSteps = new List<PathfindingVisualizationStep>();
|
||||||
private bool isVisualizingPath = false;
|
private bool isVisualizingPath = false;
|
||||||
|
private bool isMoving = false;
|
||||||
|
|
||||||
|
// Public accessor for visualization state
|
||||||
|
public bool IsVisualizingPath => isVisualizingPath;
|
||||||
|
|
||||||
|
// Public accessor for movement state
|
||||||
|
public bool IsMoving => isMoving;
|
||||||
|
|
||||||
|
// Event that fires when visualization is complete
|
||||||
|
public event Action OnVisualizationComplete;
|
||||||
|
|
||||||
|
// Event that fires when movement is complete
|
||||||
|
public event Action OnMovementComplete;
|
||||||
|
|
||||||
// Properties to control visualization
|
// Properties to control visualization
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
@ -110,11 +132,27 @@ public class NPC : MonoBehaviour
|
|||||||
{
|
{
|
||||||
while (wayPoints.Count > 0)
|
while (wayPoints.Count > 0)
|
||||||
{
|
{
|
||||||
|
// Set the moving flag when starting to move
|
||||||
|
if (!isMoving && wayPoints.Count > 0)
|
||||||
|
{
|
||||||
|
isMoving = true;
|
||||||
|
UnityEngine.Debug.Log("NPC movement started");
|
||||||
|
}
|
||||||
|
|
||||||
yield return StartCoroutine(
|
yield return StartCoroutine(
|
||||||
Coroutine_MoveToPoint(
|
Coroutine_MoveToPoint(
|
||||||
wayPoints.Dequeue(),
|
wayPoints.Dequeue(),
|
||||||
speed));
|
speed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we were moving but now have no more waypoints, signal movement completion
|
||||||
|
if (isMoving && wayPoints.Count == 0)
|
||||||
|
{
|
||||||
|
isMoving = false;
|
||||||
|
UnityEngine.Debug.Log("NPC movement complete, invoking OnMovementComplete event");
|
||||||
|
OnMovementComplete?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,8 +274,10 @@ public class NPC : MonoBehaviour
|
|||||||
{
|
{
|
||||||
yield return StartCoroutine(MeasurePerformance(silentMode));
|
yield return StartCoroutine(MeasurePerformance(silentMode));
|
||||||
|
|
||||||
// Start visualization after calculation is complete
|
// Start visualization after calculation is complete regardless of success or failure
|
||||||
if (pathFinder.Status == PathFinderStatus.SUCCESS && showVisualization && !silentMode)
|
// This allows visualization of the explored area even when no path is found
|
||||||
|
if (showVisualization && !silentMode &&
|
||||||
|
(pathFinder.Status == PathFinderStatus.SUCCESS || pathFinder.Status == PathFinderStatus.FAILURE))
|
||||||
{
|
{
|
||||||
yield return StartCoroutine(VisualizePathfinding());
|
yield return StartCoroutine(VisualizePathfinding());
|
||||||
}
|
}
|
||||||
@ -254,8 +294,8 @@ public class NPC : MonoBehaviour
|
|||||||
// Pre-allocate visualizationSteps with estimated capacity to avoid reallocations
|
// Pre-allocate visualizationSteps with estimated capacity to avoid reallocations
|
||||||
visualizationSteps = new List<PathfindingVisualizationStep>(4);
|
visualizationSteps = new List<PathfindingVisualizationStep>(4);
|
||||||
|
|
||||||
GC.Collect();
|
//GC.Collect(2, GCCollectionMode.Forced, true, true);
|
||||||
GC.WaitForPendingFinalizers(); // Tunggu semua finalizers selesai
|
//GC.WaitForPendingFinalizers(); // Tunggu semua finalizers selesai
|
||||||
|
|
||||||
// ===== MEMORY MEASUREMENT START: Ukur memory sebelum algoritma =====
|
// ===== MEMORY MEASUREMENT START: Ukur memory sebelum algoritma =====
|
||||||
long memoryBefore = System.GC.GetTotalMemory(false);
|
long memoryBefore = System.GC.GetTotalMemory(false);
|
||||||
@ -284,12 +324,8 @@ public class NPC : MonoBehaviour
|
|||||||
long memoryAfter = System.GC.GetTotalMemory(false);
|
long memoryAfter = System.GC.GetTotalMemory(false);
|
||||||
long memoryUsed = memoryAfter - memoryBefore;
|
long memoryUsed = memoryAfter - memoryBefore;
|
||||||
|
|
||||||
// float miliseconds = algorithmTimer.ElapsedMilliseconds;
|
// Store the memory usage for external access
|
||||||
|
LastMeasuredMemoryUsage = memoryUsed > 0 ? memoryUsed : 1024;
|
||||||
//UnityEngine.Debug.Log("$algorithmTimer.ElapsedTicks: " + algorithmTimer.ElapsedTicks);
|
|
||||||
//UnityEngine.Debug.Log("$Stopwatch.Frequency: " + Stopwatch.Frequency);
|
|
||||||
//float seconds = (float)algorithmTimer.ElapsedTicks / Stopwatch.Frequency;
|
|
||||||
//UnityEngine.Debug.Log("$seconds: " + seconds);
|
|
||||||
|
|
||||||
float milliseconds = (algorithmTimer.ElapsedTicks * 1000.0f) / Stopwatch.Frequency;
|
float milliseconds = (algorithmTimer.ElapsedTicks * 1000.0f) / Stopwatch.Frequency;
|
||||||
|
|
||||||
@ -324,11 +360,9 @@ public class NPC : MonoBehaviour
|
|||||||
totalFCost = totalFCost,
|
totalFCost = totalFCost,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// *** IMPORTANT FIX: Always invoke the event, regardless of silent mode ***
|
||||||
// Report metrics before visualization
|
// Report metrics before visualization
|
||||||
if (!silentMode)
|
OnPathfindingComplete?.Invoke(metrics);
|
||||||
{
|
|
||||||
OnPathfindingComplete?.Invoke(metrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path visualization and handling
|
// Path visualization and handling
|
||||||
HandlePathFindingResult(silentMode, pathLength);
|
HandlePathFindingResult(silentMode, pathLength);
|
||||||
@ -418,7 +452,6 @@ public class NPC : MonoBehaviour
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandlePathFindingResult(bool silentMode, int pathLength)
|
private void HandlePathFindingResult(bool silentMode, int pathLength)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (pathFinder.Status == PathFinderStatus.SUCCESS)
|
if (pathFinder.Status == PathFinderStatus.SUCCESS)
|
||||||
{
|
{
|
||||||
OnSuccessPathFinding();
|
OnSuccessPathFinding();
|
||||||
@ -449,6 +482,11 @@ public class NPC : MonoBehaviour
|
|||||||
else if (pathFinder.Status == PathFinderStatus.FAILURE)
|
else if (pathFinder.Status == PathFinderStatus.FAILURE)
|
||||||
{
|
{
|
||||||
OnFailurePathFinding();
|
OnFailurePathFinding();
|
||||||
|
|
||||||
|
// For failure case, we don't add any final path visualization steps
|
||||||
|
// The exploration steps (open/closed lists) are already added during the search
|
||||||
|
// and will be visualized to show what nodes were explored before failure
|
||||||
|
UnityEngine.Debug.Log($"Pathfinding failed - visualization will show {visualizationSteps.Count} exploration steps");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,6 +592,7 @@ public class NPC : MonoBehaviour
|
|||||||
if (!showVisualization)
|
if (!showVisualization)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
|
UnityEngine.Debug.Log("Path visualization starting");
|
||||||
isVisualizingPath = true;
|
isVisualizingPath = true;
|
||||||
|
|
||||||
// First, ensure grid is reset
|
// First, ensure grid is reset
|
||||||
@ -563,6 +602,14 @@ public class NPC : MonoBehaviour
|
|||||||
int stepCount = visualizationSteps.Count;
|
int stepCount = visualizationSteps.Count;
|
||||||
int batchSize = Mathf.Min(visualizationBatch, stepCount); // set higher value for faster visualization
|
int batchSize = Mathf.Min(visualizationBatch, stepCount); // set higher value for faster visualization
|
||||||
|
|
||||||
|
// Detect if pathfinding failed - we'll need to know this when processing steps
|
||||||
|
bool pathfindingFailed = pathFinder.Status == PathFinderStatus.FAILURE;
|
||||||
|
|
||||||
|
if (pathfindingFailed)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Log($"Visualizing failed pathfinding attempt with {stepCount} steps");
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < stepCount; i += batchSize)
|
for (int i = 0; i < stepCount; i += batchSize)
|
||||||
{
|
{
|
||||||
int end = Mathf.Min(i + batchSize, stepCount);
|
int end = Mathf.Min(i + batchSize, stepCount);
|
||||||
@ -587,8 +634,8 @@ public class NPC : MonoBehaviour
|
|||||||
break;
|
break;
|
||||||
case PathfindingVisualizationStep.StepType.FinalPath:
|
case PathfindingVisualizationStep.StepType.FinalPath:
|
||||||
gnv.SetInnerColor(Map.COLOR_PATH);
|
gnv.SetInnerColor(Map.COLOR_PATH);
|
||||||
// Also add the waypoint when we process the path
|
// Only add waypoints for successful pathfinding
|
||||||
if (step.type == PathfindingVisualizationStep.StepType.FinalPath)
|
if (!pathfindingFailed)
|
||||||
{
|
{
|
||||||
GridNode pathNode = Map.GetGridNode(step.position.x, step.position.y);
|
GridNode pathNode = Map.GetGridNode(step.position.x, step.position.y);
|
||||||
AddWayPoint(pathNode);
|
AddWayPoint(pathNode);
|
||||||
@ -603,6 +650,9 @@ public class NPC : MonoBehaviour
|
|||||||
}
|
}
|
||||||
|
|
||||||
isVisualizingPath = false;
|
isVisualizingPath = false;
|
||||||
|
UnityEngine.Debug.Log("Path visualization complete, invoking OnVisualizationComplete event");
|
||||||
|
// Notify any listeners that visualization is complete
|
||||||
|
OnVisualizationComplete?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1360,7 +1360,8 @@ namespace PathFinding
|
|||||||
#region Breath-First Search Algorithm
|
#region Breath-First Search Algorithm
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementasi algoritma Breadth-First Search (BFS)
|
/// Implementasi algoritma Breadth-First Search (BFS)
|
||||||
/// Algoritma ini menjelajahi semua node pada jarak yang sama dari titik awal sebelum bergerak ke node yang lebih jauh
|
/// Algoritma ini menjelajahi semua node pada jarak yang sama dari
|
||||||
|
/// titik awal sebelum bergerak ke node yang lebih jauh
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Tipe data nilai yang disimpan dalam node</typeparam>
|
/// <typeparam name="T">Tipe data nilai yang disimpan dalam node</typeparam>
|
||||||
public class BFSPathFinder<T> : PathFinder<T>
|
public class BFSPathFinder<T> : PathFinder<T>
|
||||||
|
419
Assets/Scripts/PathfindingTestAnalyzer.cs
Normal file
419
Assets/Scripts/PathfindingTestAnalyzer.cs
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Utility class to analyze pathfinding test results and display statistics
|
||||||
|
/// </summary>
|
||||||
|
public class PathfindingTestAnalyzer : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("UI References")]
|
||||||
|
public TMP_Text resultsText;
|
||||||
|
public TMP_Dropdown algorithmFilterDropdown;
|
||||||
|
public TMP_Dropdown statisticTypeDropdown;
|
||||||
|
public RectTransform graphContainer;
|
||||||
|
public GameObject barPrefab;
|
||||||
|
|
||||||
|
[Header("File Settings")]
|
||||||
|
public string resultsFileName = "pathfinding_tests.csv";
|
||||||
|
|
||||||
|
// Data structures
|
||||||
|
private List<TestResult> allResults = new List<TestResult>();
|
||||||
|
private Dictionary<string, Color> algorithmColors = new Dictionary<string, Color>()
|
||||||
|
{
|
||||||
|
{ "ASTAR", Color.blue },
|
||||||
|
{ "DIJKSTRA", Color.green },
|
||||||
|
{ "GREEDY", Color.red },
|
||||||
|
{ "BACKTRACKING", Color.yellow },
|
||||||
|
{ "BFS", Color.magenta }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Struct to hold a single test result
|
||||||
|
private struct TestResult
|
||||||
|
{
|
||||||
|
public string algorithm;
|
||||||
|
public int gridSizeX;
|
||||||
|
public int gridSizeY;
|
||||||
|
public float density;
|
||||||
|
public bool diagonalMovement;
|
||||||
|
public float timeTaken;
|
||||||
|
public int pathLength;
|
||||||
|
public int nodesExplored;
|
||||||
|
public long memoryUsed;
|
||||||
|
public bool pathFound;
|
||||||
|
public int testIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
SetupDropdowns();
|
||||||
|
LoadResults();
|
||||||
|
|
||||||
|
// Set default visualization
|
||||||
|
if (allResults.Count > 0)
|
||||||
|
{
|
||||||
|
GenerateStatistics();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupDropdowns()
|
||||||
|
{
|
||||||
|
// Set up algorithm filter dropdown
|
||||||
|
algorithmFilterDropdown.ClearOptions();
|
||||||
|
algorithmFilterDropdown.AddOptions(new List<string> {
|
||||||
|
"All Algorithms",
|
||||||
|
"A*",
|
||||||
|
"Dijkstra",
|
||||||
|
"Greedy BFS",
|
||||||
|
"Backtracking",
|
||||||
|
"BFS"
|
||||||
|
});
|
||||||
|
algorithmFilterDropdown.onValueChanged.AddListener(OnFilterChanged);
|
||||||
|
|
||||||
|
// Set up statistic type dropdown
|
||||||
|
statisticTypeDropdown.ClearOptions();
|
||||||
|
statisticTypeDropdown.AddOptions(new List<string> {
|
||||||
|
"Execution Time",
|
||||||
|
"Path Length",
|
||||||
|
"Nodes Explored",
|
||||||
|
"Memory Used",
|
||||||
|
"Success Rate"
|
||||||
|
});
|
||||||
|
statisticTypeDropdown.onValueChanged.AddListener(OnFilterChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadResults()
|
||||||
|
{
|
||||||
|
string directory = Path.Combine(Application.persistentDataPath, "TestResults");
|
||||||
|
string filePath = Path.Combine(directory, resultsFileName);
|
||||||
|
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
Debug.LogError($"Results file not found: {filePath}");
|
||||||
|
if (resultsText != null)
|
||||||
|
{
|
||||||
|
resultsText.text = "No test results found. Run tests first.";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read all lines and skip header
|
||||||
|
string[] lines = File.ReadAllLines(filePath);
|
||||||
|
if (lines.Length <= 1)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Results file is empty or only contains a header");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear previous results
|
||||||
|
allResults.Clear();
|
||||||
|
|
||||||
|
// Skip header row and parse data rows
|
||||||
|
for (int i = 1; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
string line = lines[i];
|
||||||
|
if (string.IsNullOrWhiteSpace(line))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string[] values = line.Split(',');
|
||||||
|
if (values.Length < 10)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Invalid data in line {i}: {line}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestResult result = new TestResult
|
||||||
|
{
|
||||||
|
algorithm = values[0],
|
||||||
|
gridSizeX = int.Parse(values[1]),
|
||||||
|
gridSizeY = int.Parse(values[2]),
|
||||||
|
density = float.Parse(values[3]),
|
||||||
|
diagonalMovement = bool.Parse(values[4]),
|
||||||
|
timeTaken = float.Parse(values[5]),
|
||||||
|
pathLength = int.Parse(values[6]),
|
||||||
|
nodesExplored = int.Parse(values[7]),
|
||||||
|
memoryUsed = long.Parse(values[8]),
|
||||||
|
pathFound = bool.Parse(values[9]),
|
||||||
|
testIndex = int.Parse(values[10])
|
||||||
|
};
|
||||||
|
|
||||||
|
allResults.Add(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log($"Loaded {allResults.Count} test results");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnFilterChanged(int value)
|
||||||
|
{
|
||||||
|
GenerateStatistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateStatistics()
|
||||||
|
{
|
||||||
|
if (allResults.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Clear previous graph
|
||||||
|
foreach (Transform child in graphContainer)
|
||||||
|
{
|
||||||
|
Destroy(child.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get selected algorithm filter
|
||||||
|
string algorithmFilter = "All";
|
||||||
|
switch (algorithmFilterDropdown.value)
|
||||||
|
{
|
||||||
|
case 0: algorithmFilter = "All"; break;
|
||||||
|
case 1: algorithmFilter = "ASTAR"; break;
|
||||||
|
case 2: algorithmFilter = "DIJKSTRA"; break;
|
||||||
|
case 3: algorithmFilter = "GREEDY"; break;
|
||||||
|
case 4: algorithmFilter = "BACKTRACKING"; break;
|
||||||
|
case 5: algorithmFilter = "BFS"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter results by algorithm if not "All"
|
||||||
|
List<TestResult> filteredResults = allResults;
|
||||||
|
if (algorithmFilter != "All")
|
||||||
|
{
|
||||||
|
filteredResults = allResults.Where(r => r.algorithm == algorithmFilter).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filteredResults.Count == 0)
|
||||||
|
{
|
||||||
|
resultsText.text = "No data for selected filters.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate statistics based on selected metric
|
||||||
|
switch (statisticTypeDropdown.value)
|
||||||
|
{
|
||||||
|
case 0: // Execution Time
|
||||||
|
GenerateTimeStatistics(filteredResults);
|
||||||
|
break;
|
||||||
|
case 1: // Path Length
|
||||||
|
GeneratePathLengthStatistics(filteredResults);
|
||||||
|
break;
|
||||||
|
case 2: // Nodes Explored
|
||||||
|
GenerateNodesExploredStatistics(filteredResults);
|
||||||
|
break;
|
||||||
|
case 3: // Memory Used
|
||||||
|
GenerateMemoryStatistics(filteredResults);
|
||||||
|
break;
|
||||||
|
case 4: // Success Rate
|
||||||
|
GenerateSuccessRateStatistics(filteredResults);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateTimeStatistics(List<TestResult> results)
|
||||||
|
{
|
||||||
|
var averageTimeByAlgorithm = results
|
||||||
|
.GroupBy(r => r.algorithm)
|
||||||
|
.Select(g => new {
|
||||||
|
Algorithm = g.Key,
|
||||||
|
AverageTime = g.Average(r => r.timeTaken)
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.AverageTime)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Generate graph bars
|
||||||
|
CreateBarsForData(averageTimeByAlgorithm.Select(x => x.Algorithm).ToList(),
|
||||||
|
averageTimeByAlgorithm.Select(x => (float)x.AverageTime).ToList(),
|
||||||
|
"ms");
|
||||||
|
|
||||||
|
// Generate text summary
|
||||||
|
resultsText.text = "Average Execution Time by Algorithm:\n\n";
|
||||||
|
foreach (var stat in averageTimeByAlgorithm)
|
||||||
|
{
|
||||||
|
resultsText.text += $"{GetAlgorithmName(stat.Algorithm)}: {stat.AverageTime:F2} ms\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GeneratePathLengthStatistics(List<TestResult> results)
|
||||||
|
{
|
||||||
|
var averagePathByAlgorithm = results
|
||||||
|
.Where(r => r.pathFound) // Only include successful paths
|
||||||
|
.GroupBy(r => r.algorithm)
|
||||||
|
.Select(g => new {
|
||||||
|
Algorithm = g.Key,
|
||||||
|
AveragePath = g.Average(r => r.pathLength)
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.AveragePath)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Generate graph bars
|
||||||
|
CreateBarsForData(averagePathByAlgorithm.Select(x => x.Algorithm).ToList(),
|
||||||
|
averagePathByAlgorithm.Select(x => (float)x.AveragePath).ToList(),
|
||||||
|
"nodes");
|
||||||
|
|
||||||
|
// Generate text summary
|
||||||
|
resultsText.text = "Average Path Length by Algorithm:\n\n";
|
||||||
|
foreach (var stat in averagePathByAlgorithm)
|
||||||
|
{
|
||||||
|
resultsText.text += $"{GetAlgorithmName(stat.Algorithm)}: {stat.AveragePath:F2} nodes\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateNodesExploredStatistics(List<TestResult> results)
|
||||||
|
{
|
||||||
|
var averageNodesExploredByAlgorithm = results
|
||||||
|
.GroupBy(r => r.algorithm)
|
||||||
|
.Select(g => new {
|
||||||
|
Algorithm = g.Key,
|
||||||
|
AverageNodes = g.Average(r => r.nodesExplored)
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.AverageNodes)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Generate graph bars
|
||||||
|
CreateBarsForData(averageNodesExploredByAlgorithm.Select(x => x.Algorithm).ToList(),
|
||||||
|
averageNodesExploredByAlgorithm.Select(x => (float)x.AverageNodes).ToList(),
|
||||||
|
"nodes");
|
||||||
|
|
||||||
|
// Generate text summary
|
||||||
|
resultsText.text = "Average Nodes Explored by Algorithm:\n\n";
|
||||||
|
foreach (var stat in averageNodesExploredByAlgorithm)
|
||||||
|
{
|
||||||
|
resultsText.text += $"{GetAlgorithmName(stat.Algorithm)}: {stat.AverageNodes:F0} nodes\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateMemoryStatistics(List<TestResult> results)
|
||||||
|
{
|
||||||
|
var averageMemoryByAlgorithm = results
|
||||||
|
.GroupBy(r => r.algorithm)
|
||||||
|
.Select(g => new {
|
||||||
|
Algorithm = g.Key,
|
||||||
|
AverageMemory = g.Average(r => r.memoryUsed) / 1024.0f // Convert to KB
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.AverageMemory)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Generate graph bars
|
||||||
|
CreateBarsForData(averageMemoryByAlgorithm.Select(x => x.Algorithm).ToList(),
|
||||||
|
averageMemoryByAlgorithm.Select(x => (float)x.AverageMemory).ToList(),
|
||||||
|
"KB");
|
||||||
|
|
||||||
|
// Generate text summary
|
||||||
|
resultsText.text = "Average Memory Usage by Algorithm:\n\n";
|
||||||
|
foreach (var stat in averageMemoryByAlgorithm)
|
||||||
|
{
|
||||||
|
resultsText.text += $"{GetAlgorithmName(stat.Algorithm)}: {stat.AverageMemory:F2} KB\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateSuccessRateStatistics(List<TestResult> results)
|
||||||
|
{
|
||||||
|
var successRateByAlgorithm = results
|
||||||
|
.GroupBy(r => r.algorithm)
|
||||||
|
.Select(g => new {
|
||||||
|
Algorithm = g.Key,
|
||||||
|
SuccessRate = g.Count(r => r.pathFound) * 100.0f / g.Count()
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.SuccessRate)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Generate graph bars
|
||||||
|
CreateBarsForData(successRateByAlgorithm.Select(x => x.Algorithm).ToList(),
|
||||||
|
successRateByAlgorithm.Select(x => (float)x.SuccessRate).ToList(),
|
||||||
|
"%");
|
||||||
|
|
||||||
|
// Generate text summary
|
||||||
|
resultsText.text = "Success Rate by Algorithm:\n\n";
|
||||||
|
foreach (var stat in successRateByAlgorithm)
|
||||||
|
{
|
||||||
|
resultsText.text += $"{GetAlgorithmName(stat.Algorithm)}: {stat.SuccessRate:F1}%\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateBarsForData(List<string> labels, List<float> values, string unit)
|
||||||
|
{
|
||||||
|
if (barPrefab == null || graphContainer == null || labels.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float graphWidth = graphContainer.rect.width;
|
||||||
|
float graphHeight = graphContainer.rect.height;
|
||||||
|
float maxValue = values.Max();
|
||||||
|
float barWidth = graphWidth / (labels.Count + 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < labels.Count; i++)
|
||||||
|
{
|
||||||
|
// Create bar
|
||||||
|
GameObject barObj = Instantiate(barPrefab, graphContainer);
|
||||||
|
RectTransform barRect = barObj.GetComponent<RectTransform>();
|
||||||
|
Image barImage = barObj.GetComponent<Image>();
|
||||||
|
|
||||||
|
// Calculate height based on value
|
||||||
|
float normalizedValue = values[i] / maxValue;
|
||||||
|
float barHeight = graphHeight * normalizedValue * 0.8f; // 80% of graph height max
|
||||||
|
|
||||||
|
// Position and size bar
|
||||||
|
barRect.anchoredPosition = new Vector2((i + 0.5f) * barWidth, barHeight / 2);
|
||||||
|
barRect.sizeDelta = new Vector2(barWidth * 0.8f, barHeight);
|
||||||
|
|
||||||
|
// Set bar color
|
||||||
|
string algorithm = labels[i];
|
||||||
|
if (algorithmColors.ContainsKey(algorithm))
|
||||||
|
barImage.color = algorithmColors[algorithm];
|
||||||
|
|
||||||
|
// Add label
|
||||||
|
GameObject labelObj = new GameObject($"Label_{labels[i]}");
|
||||||
|
labelObj.transform.SetParent(barObj.transform);
|
||||||
|
|
||||||
|
TMP_Text labelText = labelObj.AddComponent<TMP_Text>();
|
||||||
|
labelText.text = $"{values[i]:F1}{unit}";
|
||||||
|
labelText.fontSize = 12;
|
||||||
|
labelText.alignment = TextAlignmentOptions.Center;
|
||||||
|
labelText.color = Color.black;
|
||||||
|
|
||||||
|
RectTransform labelRect = labelObj.GetComponent<RectTransform>();
|
||||||
|
labelRect.anchoredPosition = new Vector2(0, barHeight + 10);
|
||||||
|
labelRect.sizeDelta = new Vector2(barWidth, 20);
|
||||||
|
|
||||||
|
// Add algorithm name label at bottom
|
||||||
|
GameObject nameObj = new GameObject($"Name_{labels[i]}");
|
||||||
|
nameObj.transform.SetParent(barObj.transform);
|
||||||
|
|
||||||
|
TMP_Text nameText = nameObj.AddComponent<TMP_Text>();
|
||||||
|
nameText.text = GetAlgorithmName(labels[i]);
|
||||||
|
nameText.fontSize = 10;
|
||||||
|
nameText.alignment = TextAlignmentOptions.Center;
|
||||||
|
nameText.color = Color.black;
|
||||||
|
|
||||||
|
RectTransform nameRect = nameObj.GetComponent<RectTransform>();
|
||||||
|
nameRect.anchoredPosition = new Vector2(0, -10);
|
||||||
|
nameRect.sizeDelta = new Vector2(barWidth, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetAlgorithmName(string algorithm)
|
||||||
|
{
|
||||||
|
switch (algorithm)
|
||||||
|
{
|
||||||
|
case "ASTAR": return "A*";
|
||||||
|
case "DIJKSTRA": return "Dijkstra";
|
||||||
|
case "GREEDY": return "Greedy";
|
||||||
|
case "BACKTRACKING": return "Backtracking";
|
||||||
|
case "BFS": return "BFS";
|
||||||
|
default: return algorithm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility function to format memory size
|
||||||
|
private string FormatBytes(long bytes)
|
||||||
|
{
|
||||||
|
string[] sizes = { "B", "KB", "MB", "GB" };
|
||||||
|
int order = 0;
|
||||||
|
double size = bytes;
|
||||||
|
while (size >= 1024 && order < sizes.Length - 1)
|
||||||
|
{
|
||||||
|
order++;
|
||||||
|
size = size / 1024;
|
||||||
|
}
|
||||||
|
return $"{size:0.##} {sizes[order]}";
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Scripts/PathfindingTestAnalyzer.cs.meta
Normal file
11
Assets/Scripts/PathfindingTestAnalyzer.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9fee3f5c29ad21b428f68d801f2377f1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
510
Assets/Scripts/PathfindingTester.cs
Normal file
510
Assets/Scripts/PathfindingTester.cs
Normal file
@ -0,0 +1,510 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
public class PathfindingTester : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("References")]
|
||||||
|
public GridMap gridMap;
|
||||||
|
public NPC npc;
|
||||||
|
public Button startTestButton;
|
||||||
|
public TMP_Text statusText;
|
||||||
|
public Slider progressBar;
|
||||||
|
|
||||||
|
[Header("Test Configuration")]
|
||||||
|
[Tooltip("Number of times to run each test combination")]
|
||||||
|
public int testsPerCombination = 3;
|
||||||
|
|
||||||
|
[Tooltip("Delay between tests in seconds")]
|
||||||
|
public float delayBetweenTests = 0.5f;
|
||||||
|
|
||||||
|
[Tooltip("Whether to save results to a CSV file")]
|
||||||
|
public bool saveResultsToFile = true;
|
||||||
|
|
||||||
|
[Tooltip("File name for test results (CSV)")]
|
||||||
|
public string resultsFileName = "pathfinding_tests.csv";
|
||||||
|
|
||||||
|
// Test matrix parameters
|
||||||
|
private NPC.PathFinderType[] algorithmsToTest = new NPC.PathFinderType[] {
|
||||||
|
NPC.PathFinderType.ASTAR,
|
||||||
|
NPC.PathFinderType.DIJKSTRA,
|
||||||
|
NPC.PathFinderType.GREEDY,
|
||||||
|
NPC.PathFinderType.BACKTRACKING,
|
||||||
|
NPC.PathFinderType.BFS
|
||||||
|
};
|
||||||
|
|
||||||
|
private Vector2Int[] gridSizesToTest = new Vector2Int[] {
|
||||||
|
new Vector2Int(20, 20),
|
||||||
|
new Vector2Int(35, 35),
|
||||||
|
new Vector2Int(50, 50),
|
||||||
|
new Vector2Int(40, 25) // Another non-square grid
|
||||||
|
};
|
||||||
|
|
||||||
|
private float[] mazeDensitiesToTest = new float[] {
|
||||||
|
0f, // Empty (no walls)
|
||||||
|
10f, // Very low
|
||||||
|
30f, // Medium
|
||||||
|
50f, // High
|
||||||
|
100f // Fully blocked (all walls)
|
||||||
|
};
|
||||||
|
|
||||||
|
private bool[] diagonalMovementOptions = new bool[] {
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test state tracking
|
||||||
|
private bool isTestingRunning = false;
|
||||||
|
private int totalTests;
|
||||||
|
private int completedTests;
|
||||||
|
private List<PathfindingTestResult> testResults = new List<PathfindingTestResult>();
|
||||||
|
|
||||||
|
// Current test parameters
|
||||||
|
private NPC.PathFinderType currentTestAlgorithm;
|
||||||
|
private Vector2Int currentTestGridSize;
|
||||||
|
private float currentTestDensity;
|
||||||
|
private bool currentTestDiagonal;
|
||||||
|
private int currentTestIndex;
|
||||||
|
|
||||||
|
// Structure to store test results
|
||||||
|
private struct PathfindingTestResult
|
||||||
|
{
|
||||||
|
public NPC.PathFinderType algorithm;
|
||||||
|
public Vector2Int gridSize;
|
||||||
|
public float mazeDensity;
|
||||||
|
public bool diagonalMovement;
|
||||||
|
public float timeTaken;
|
||||||
|
public int pathLength;
|
||||||
|
public int nodesExplored;
|
||||||
|
public long memoryUsed;
|
||||||
|
public bool pathFound;
|
||||||
|
public int testIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
// Subscribe to NPC's pathfinding completion event
|
||||||
|
npc.OnPathfindingComplete += OnPathfindingComplete;
|
||||||
|
|
||||||
|
// Set up the button listener
|
||||||
|
startTestButton.onClick.AddListener(StartTesting);
|
||||||
|
|
||||||
|
// Initial status message
|
||||||
|
UpdateStatus("Ready to start testing. Click the Start Tests button.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
// Unsubscribe from events
|
||||||
|
if (npc != null)
|
||||||
|
{
|
||||||
|
npc.OnPathfindingComplete -= OnPathfindingComplete;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateStatus(string message)
|
||||||
|
{
|
||||||
|
if (statusText != null)
|
||||||
|
{
|
||||||
|
statusText.text = message;
|
||||||
|
}
|
||||||
|
Debug.Log(message);
|
||||||
|
|
||||||
|
// Update progress bar if available
|
||||||
|
if (progressBar != null && totalTests > 0)
|
||||||
|
{
|
||||||
|
progressBar.value = (float)completedTests / totalTests;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartTesting()
|
||||||
|
{
|
||||||
|
if (isTestingRunning)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Tests are already running.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear previous results
|
||||||
|
testResults.Clear();
|
||||||
|
|
||||||
|
// Calculate total number of tests
|
||||||
|
totalTests = algorithmsToTest.Length *
|
||||||
|
gridSizesToTest.Length *
|
||||||
|
mazeDensitiesToTest.Length *
|
||||||
|
diagonalMovementOptions.Length *
|
||||||
|
testsPerCombination;
|
||||||
|
|
||||||
|
completedTests = 0;
|
||||||
|
isTestingRunning = true;
|
||||||
|
|
||||||
|
UpdateStatus($"Starting {totalTests} tests...");
|
||||||
|
|
||||||
|
// Disable button during testing
|
||||||
|
startTestButton.interactable = false;
|
||||||
|
|
||||||
|
// Start the test coroutine
|
||||||
|
StartCoroutine(RunTestMatrix());
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator RunTestMatrix()
|
||||||
|
{
|
||||||
|
// Iterate through all test combinations
|
||||||
|
foreach (var algorithm in algorithmsToTest)
|
||||||
|
{
|
||||||
|
foreach (var gridSize in gridSizesToTest)
|
||||||
|
{
|
||||||
|
foreach (var density in mazeDensitiesToTest)
|
||||||
|
{
|
||||||
|
foreach (var useDiagonals in diagonalMovementOptions)
|
||||||
|
{
|
||||||
|
for (int testIndex = 0; testIndex < testsPerCombination; testIndex++)
|
||||||
|
{
|
||||||
|
yield return StartCoroutine(RunSingleTest(algorithm, gridSize, density, useDiagonals, testIndex));
|
||||||
|
|
||||||
|
// Wait between tests
|
||||||
|
yield return new WaitForSeconds(delayBetweenTests);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All tests completed
|
||||||
|
isTestingRunning = false;
|
||||||
|
startTestButton.interactable = true;
|
||||||
|
|
||||||
|
// Save results if enabled
|
||||||
|
if (saveResultsToFile)
|
||||||
|
{
|
||||||
|
SaveResultsToCSV();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateStatus($"Testing complete! {completedTests} tests run. Results saved to {resultsFileName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator RunSingleTest(NPC.PathFinderType algorithm, Vector2Int gridSize, float density, bool useDiagonals, int testIndex)
|
||||||
|
{
|
||||||
|
// Update status with current test info
|
||||||
|
UpdateStatus($"Test {completedTests+1}/{totalTests}: {algorithm} - Grid: {gridSize.x}x{gridSize.y} - Density: {density}% - Diagonals: {useDiagonals}");
|
||||||
|
|
||||||
|
// Configure the test environment
|
||||||
|
yield return StartCoroutine(SetupTestEnvironment(algorithm, gridSize, density, useDiagonals));
|
||||||
|
|
||||||
|
// Generate start and destination points
|
||||||
|
GridNode startNode = FindValidStartNode();
|
||||||
|
GridNode destNode = FindValidDestinationNode(startNode);
|
||||||
|
|
||||||
|
if (startNode == null || destNode == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Failed to find valid start/destination nodes for test - density: {density}%");
|
||||||
|
|
||||||
|
// Record the test as "impossible" with a failed path
|
||||||
|
PathfindingTestResult result = new PathfindingTestResult
|
||||||
|
{
|
||||||
|
algorithm = algorithm,
|
||||||
|
gridSize = gridSize,
|
||||||
|
mazeDensity = density,
|
||||||
|
diagonalMovement = useDiagonals,
|
||||||
|
timeTaken = 0f,
|
||||||
|
pathLength = 0,
|
||||||
|
nodesExplored = 0,
|
||||||
|
memoryUsed = 0,
|
||||||
|
pathFound = false,
|
||||||
|
testIndex = testIndex
|
||||||
|
};
|
||||||
|
|
||||||
|
testResults.Add(result);
|
||||||
|
completedTests++;
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position NPC at start node
|
||||||
|
npc.SetStartNode(startNode);
|
||||||
|
|
||||||
|
// Position destination
|
||||||
|
gridMap.SetDestination(destNode.Value.x, destNode.Value.y);
|
||||||
|
|
||||||
|
// Wait a frame to ensure everything is set up
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// Store the current test parameters
|
||||||
|
currentTestAlgorithm = algorithm;
|
||||||
|
currentTestGridSize = gridSize;
|
||||||
|
currentTestDensity = density;
|
||||||
|
currentTestDiagonal = useDiagonals;
|
||||||
|
currentTestIndex = testIndex;
|
||||||
|
|
||||||
|
// Flag to track if callback was triggered
|
||||||
|
bool callbackTriggered = false;
|
||||||
|
|
||||||
|
// Setup a temporary callback listener to detect if the event fires
|
||||||
|
System.Action<PathfindingMetrics> tempCallback = (metrics) => { callbackTriggered = true; };
|
||||||
|
npc.OnPathfindingComplete += tempCallback;
|
||||||
|
|
||||||
|
// Run pathfinding in silent mode - now the event will still fire with our NPC fix
|
||||||
|
npc.MoveTo(destNode, true);
|
||||||
|
|
||||||
|
// Wait for pathfinding to complete
|
||||||
|
float timeout = 10.0f;
|
||||||
|
float elapsed = 0f;
|
||||||
|
|
||||||
|
while (npc.pathFinder != null && npc.pathFinder.Status == PathFinding.PathFinderStatus.RUNNING && elapsed < timeout)
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
elapsed += Time.deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait a bit more to ensure completion
|
||||||
|
yield return new WaitForSeconds(0.1f);
|
||||||
|
|
||||||
|
// Remove the temporary callback
|
||||||
|
npc.OnPathfindingComplete -= tempCallback;
|
||||||
|
|
||||||
|
// If callback wasn't triggered but pathfinding is complete, manually record the result
|
||||||
|
if (!callbackTriggered && npc.pathFinder != null && npc.pathFinder.Status != PathFinding.PathFinderStatus.RUNNING)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Callback wasn't triggered for test {completedTests+1}. Recording results manually.");
|
||||||
|
|
||||||
|
// Create a metrics object with available data
|
||||||
|
PathfindingMetrics metrics = new PathfindingMetrics
|
||||||
|
{
|
||||||
|
timeTaken = elapsed * 1000f, // convert to ms
|
||||||
|
pathLength = CalculatePathLength(npc.pathFinder),
|
||||||
|
nodesExplored = npc.pathFinder.ClosedListCount,
|
||||||
|
memoryUsed = npc.LastMeasuredMemoryUsage // Get the last memory measurement from NPC
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a test result entry directly
|
||||||
|
PathfindingTestResult result = new PathfindingTestResult
|
||||||
|
{
|
||||||
|
algorithm = currentTestAlgorithm,
|
||||||
|
gridSize = currentTestGridSize,
|
||||||
|
mazeDensity = currentTestDensity,
|
||||||
|
diagonalMovement = currentTestDiagonal,
|
||||||
|
timeTaken = metrics.timeTaken,
|
||||||
|
pathLength = metrics.pathLength,
|
||||||
|
nodesExplored = metrics.nodesExplored,
|
||||||
|
memoryUsed = metrics.memoryUsed,
|
||||||
|
pathFound = npc.pathFinder.Status == PathFinding.PathFinderStatus.SUCCESS,
|
||||||
|
testIndex = currentTestIndex
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add to results directly
|
||||||
|
testResults.Add(result);
|
||||||
|
|
||||||
|
// Log result
|
||||||
|
Debug.Log($"Test {completedTests} (manual): {GetAlgorithmName(result.algorithm)} - {result.timeTaken:F2}ms - Path: {result.pathLength} - Nodes: {result.nodesExplored}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment test counter
|
||||||
|
completedTests++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int CalculatePathLength(PathFinding.PathFinder<Vector2Int> pathFinder)
|
||||||
|
{
|
||||||
|
if (pathFinder == null || pathFinder.CurrentNode == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int length = 0;
|
||||||
|
var node = pathFinder.CurrentNode;
|
||||||
|
while (node != null)
|
||||||
|
{
|
||||||
|
length++;
|
||||||
|
node = node.Parent;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator SetupTestEnvironment(NPC.PathFinderType algorithm, Vector2Int gridSize, float density, bool useDiagonals)
|
||||||
|
{
|
||||||
|
Debug.Log($"Setting up test environment: Algorithm={algorithm}, Grid={gridSize.x}x{gridSize.y}, Density={density}, Diagonals={useDiagonals}");
|
||||||
|
|
||||||
|
// Resize grid
|
||||||
|
gridMap.ResizeGrid(gridSize.x, gridSize.y);
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// Set algorithm
|
||||||
|
npc.ChangeAlgorithm(algorithm);
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// Set diagonal movement
|
||||||
|
gridMap.AllowDiagonalMovement = useDiagonals;
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// Generate maze with specified density
|
||||||
|
gridMap.GenerateRandomMaze(density);
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// Note: We no longer change visualization settings here
|
||||||
|
// This is handled in the RunSingleTest method
|
||||||
|
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridNode FindValidStartNode()
|
||||||
|
{
|
||||||
|
// Find a walkable node for start position, starting from the top left
|
||||||
|
for (int x = 0; x < gridMap.NumX; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < gridMap.NumY; y++)
|
||||||
|
{
|
||||||
|
GridNode node = gridMap.GetGridNode(x, y);
|
||||||
|
if (node != null && node.IsWalkable)
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridNode FindValidDestinationNode(GridNode startNode)
|
||||||
|
{
|
||||||
|
if (startNode == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Find a walkable node far from the start position, starting from the bottom right
|
||||||
|
int maxDistance = 0;
|
||||||
|
GridNode bestNode = null;
|
||||||
|
|
||||||
|
// First try to find a node with good distance
|
||||||
|
for (int x = gridMap.NumX - 1; x >= 0; x--)
|
||||||
|
{
|
||||||
|
for (int y = gridMap.NumY - 1; y >= 0; y--)
|
||||||
|
{
|
||||||
|
GridNode node = gridMap.GetGridNode(x, y);
|
||||||
|
if (node != null && node.IsWalkable && node != startNode)
|
||||||
|
{
|
||||||
|
int distance = Mathf.Abs(x - startNode.Value.x) + Mathf.Abs(y - startNode.Value.y);
|
||||||
|
if (distance > maxDistance)
|
||||||
|
{
|
||||||
|
maxDistance = distance;
|
||||||
|
bestNode = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found a node and the distance is decent, use it
|
||||||
|
if (bestNode != null && maxDistance > gridMap.NumX / 4)
|
||||||
|
{
|
||||||
|
return bestNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no good node was found or distance is too small, try harder to find any walkable node
|
||||||
|
// different from start node (this helps with very high density mazes)
|
||||||
|
for (int x = 0; x < gridMap.NumX; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < gridMap.NumY; y++)
|
||||||
|
{
|
||||||
|
GridNode node = gridMap.GetGridNode(x, y);
|
||||||
|
if (node != null && node.IsWalkable && node != startNode)
|
||||||
|
{
|
||||||
|
return node; // Return the first walkable node that isn't the start
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here and bestNode is null, there's only one walkable node in the entire grid
|
||||||
|
// In this case, we have to return null and the test should be skipped
|
||||||
|
return bestNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPathfindingComplete(PathfindingMetrics metrics)
|
||||||
|
{
|
||||||
|
if (!isTestingRunning)
|
||||||
|
{
|
||||||
|
Debug.Log("OnPathfindingComplete called but test is not running - ignoring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log($"OnPathfindingComplete called for test {completedTests+1} with algorithm {currentTestAlgorithm}");
|
||||||
|
|
||||||
|
// Create a test result entry
|
||||||
|
PathfindingTestResult result = new PathfindingTestResult
|
||||||
|
{
|
||||||
|
algorithm = currentTestAlgorithm,
|
||||||
|
gridSize = currentTestGridSize,
|
||||||
|
mazeDensity = currentTestDensity,
|
||||||
|
diagonalMovement = currentTestDiagonal,
|
||||||
|
timeTaken = metrics.timeTaken,
|
||||||
|
pathLength = metrics.pathLength,
|
||||||
|
nodesExplored = metrics.nodesExplored,
|
||||||
|
memoryUsed = metrics.memoryUsed,
|
||||||
|
pathFound = npc.pathFinder.Status == PathFinding.PathFinderStatus.SUCCESS,
|
||||||
|
testIndex = currentTestIndex
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add to results
|
||||||
|
testResults.Add(result);
|
||||||
|
|
||||||
|
// Log result
|
||||||
|
Debug.Log($"Test {completedTests+1}: {GetAlgorithmName(result.algorithm)} - {result.timeTaken:F2}ms - Path: {result.pathLength} - Nodes: {result.nodesExplored} - Success: {result.pathFound} - Results count: {testResults.Count}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveResultsToCSV()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Debug.Log($"Saving {testResults.Count} test results to CSV...");
|
||||||
|
|
||||||
|
if (testResults.Count == 0)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("No test results to save!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create directory if it doesn't exist
|
||||||
|
string directory = Path.Combine(Application.persistentDataPath, "TestResults");
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
string filePath = Path.Combine(directory, resultsFileName);
|
||||||
|
|
||||||
|
StringBuilder csv = new StringBuilder();
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
csv.AppendLine("Algorithm,GridSizeX,GridSizeY,Density,DiagonalMovement,TimeTaken,PathLength,NodesExplored,MemoryUsed,PathFound,TestIndex");
|
||||||
|
|
||||||
|
// Write each result
|
||||||
|
foreach (var result in testResults)
|
||||||
|
{
|
||||||
|
csv.AppendLine($"{result.algorithm},{result.gridSize.x},{result.gridSize.y},{result.mazeDensity},{result.diagonalMovement}," +
|
||||||
|
$"{result.timeTaken},{result.pathLength},{result.nodesExplored},{result.memoryUsed},{result.pathFound},{result.testIndex}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write file
|
||||||
|
File.WriteAllText(filePath, csv.ToString());
|
||||||
|
|
||||||
|
Debug.Log($"Test results saved to {filePath}");
|
||||||
|
|
||||||
|
// Make it easier to find in Windows Explorer
|
||||||
|
System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{filePath}\"");
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError($"Error saving test results: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility method to get algorithm name as a string
|
||||||
|
private string GetAlgorithmName(NPC.PathFinderType algorithm)
|
||||||
|
{
|
||||||
|
switch (algorithm)
|
||||||
|
{
|
||||||
|
case NPC.PathFinderType.ASTAR: return "A*";
|
||||||
|
case NPC.PathFinderType.DIJKSTRA: return "Dijkstra";
|
||||||
|
case NPC.PathFinderType.GREEDY: return "Greedy";
|
||||||
|
case NPC.PathFinderType.BACKTRACKING: return "Backtracking";
|
||||||
|
case NPC.PathFinderType.BFS: return "BFS";
|
||||||
|
default: return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Scripts/PathfindingTester.cs.meta
Normal file
11
Assets/Scripts/PathfindingTester.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ed03b279fa9f3194f8caed356ea838dc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,7 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using System.Collections;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
public class PathfindingUIManager : MonoBehaviour
|
public class PathfindingUIManager : MonoBehaviour
|
||||||
@ -52,9 +54,23 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
public TMP_Dropdown mazeSizeDropdown;
|
public TMP_Dropdown mazeSizeDropdown;
|
||||||
public TMP_Dropdown mazeDensityDropdown;
|
public TMP_Dropdown mazeDensityDropdown;
|
||||||
|
|
||||||
|
[Header("Automated Testing")]
|
||||||
|
[SerializeField] private GameObject testerPanelPrefab;
|
||||||
|
[SerializeField] private Transform testerPanelParent;
|
||||||
|
private GameObject testerPanelInstance;
|
||||||
|
|
||||||
// Konstanta untuk perhitungan CPU usage
|
// Konstanta untuk perhitungan CPU usage
|
||||||
private const float TARGET_FRAME_TIME_MS = 16.67f; // 60 FPS = 16.67ms per frame
|
private const float TARGET_FRAME_TIME_MS = 16.67f; // 60 FPS = 16.67ms per frame
|
||||||
|
|
||||||
|
// Add a flag to track if pathfinding is running
|
||||||
|
private bool isPathfindingRunning = false;
|
||||||
|
|
||||||
|
// Add a flag to track if visualization is running
|
||||||
|
private bool isVisualizationRunning = false;
|
||||||
|
|
||||||
|
// Add a flag to track if NPC is moving
|
||||||
|
private bool isNpcMoving = false;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
// Initialize UI elements
|
// Initialize UI elements
|
||||||
@ -91,6 +107,13 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
|
|
||||||
// Subscribe to NPC's pathfinding events
|
// Subscribe to NPC's pathfinding events
|
||||||
npc.OnPathfindingComplete += UpdatePerformanceMetrics;
|
npc.OnPathfindingComplete += UpdatePerformanceMetrics;
|
||||||
|
npc.OnPathfindingComplete += OnPathfindingCompleted;
|
||||||
|
|
||||||
|
// Subscribe to visualization completion event
|
||||||
|
npc.OnVisualizationComplete += OnVisualizationCompleted;
|
||||||
|
|
||||||
|
// Subscribe to movement completion event
|
||||||
|
npc.OnMovementComplete += OnMovementCompleted;
|
||||||
|
|
||||||
// Initialize performance metrics
|
// Initialize performance metrics
|
||||||
ClearPerformanceMetrics();
|
ClearPerformanceMetrics();
|
||||||
@ -213,6 +236,9 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
if (npc != null)
|
if (npc != null)
|
||||||
{
|
{
|
||||||
npc.OnPathfindingComplete -= UpdatePerformanceMetrics;
|
npc.OnPathfindingComplete -= UpdatePerformanceMetrics;
|
||||||
|
npc.OnPathfindingComplete -= OnPathfindingCompleted;
|
||||||
|
npc.OnVisualizationComplete -= OnVisualizationCompleted;
|
||||||
|
npc.OnMovementComplete -= OnMovementCompleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsubscribe from UI events
|
// Unsubscribe from UI events
|
||||||
@ -228,6 +254,14 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
gridSizeXInput.text = gridMap.NumX.ToString();
|
gridSizeXInput.text = gridMap.NumX.ToString();
|
||||||
gridSizeYInput.text = gridMap.NumY.ToString();
|
gridSizeYInput.text = gridMap.NumY.ToString();
|
||||||
|
|
||||||
|
// Set input fields to only accept integers
|
||||||
|
gridSizeXInput.contentType = TMP_InputField.ContentType.IntegerNumber;
|
||||||
|
gridSizeYInput.contentType = TMP_InputField.ContentType.IntegerNumber;
|
||||||
|
|
||||||
|
// Add input validation events
|
||||||
|
gridSizeXInput.onValidateInput += ValidateNumberInput;
|
||||||
|
gridSizeYInput.onValidateInput += ValidateNumberInput;
|
||||||
|
|
||||||
// Setup algorithm dropdown
|
// Setup algorithm dropdown
|
||||||
algorithmDropdown.ClearOptions();
|
algorithmDropdown.ClearOptions();
|
||||||
algorithmDropdown.AddOptions(new System.Collections.Generic.List<string> {
|
algorithmDropdown.AddOptions(new System.Collections.Generic.List<string> {
|
||||||
@ -270,6 +304,20 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
ClearPerformanceMetrics();
|
ClearPerformanceMetrics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validation function to only allow numeric input
|
||||||
|
private char ValidateNumberInput(string text, int charIndex, char addedChar)
|
||||||
|
{
|
||||||
|
// Only allow digits
|
||||||
|
if (char.IsDigit(addedChar))
|
||||||
|
{
|
||||||
|
return addedChar;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '\0'; // Return null character to reject the input
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ClearPerformanceMetrics()
|
private void ClearPerformanceMetrics()
|
||||||
{
|
{
|
||||||
timeEstimateText.text = "0";
|
timeEstimateText.text = "0";
|
||||||
@ -312,8 +360,42 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
if (int.TryParse(gridSizeXInput.text, out int newSizeX) &&
|
if (int.TryParse(gridSizeXInput.text, out int newSizeX) &&
|
||||||
int.TryParse(gridSizeYInput.text, out int newSizeY))
|
int.TryParse(gridSizeYInput.text, out int newSizeY))
|
||||||
{
|
{
|
||||||
gridMap.ResizeGrid(newSizeX, newSizeY);
|
// Validate grid size limits
|
||||||
ClearPerformanceMetrics();
|
const int MAX_GRID_SIZE = 200;
|
||||||
|
const int MIN_GRID_SIZE = 2;
|
||||||
|
|
||||||
|
if (newSizeX > MAX_GRID_SIZE || newSizeY > MAX_GRID_SIZE)
|
||||||
|
{
|
||||||
|
// Display an error message
|
||||||
|
Debug.LogWarning($"Grid size cannot exceed {MAX_GRID_SIZE}x{MAX_GRID_SIZE}. Resize operation cancelled.");
|
||||||
|
|
||||||
|
// Revert input fields to current grid size
|
||||||
|
gridSizeXInput.text = gridMap.NumX.ToString();
|
||||||
|
gridSizeYInput.text = gridMap.NumY.ToString();
|
||||||
|
|
||||||
|
// Don't proceed with resize
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for minimum size
|
||||||
|
if (newSizeX < MIN_GRID_SIZE || newSizeY < MIN_GRID_SIZE)
|
||||||
|
{
|
||||||
|
// Display an error message
|
||||||
|
Debug.LogWarning($"Grid size cannot be less than {MIN_GRID_SIZE}x{MIN_GRID_SIZE}. Resize operation cancelled.");
|
||||||
|
|
||||||
|
// Revert input fields to current grid size
|
||||||
|
gridSizeXInput.text = gridMap.NumX.ToString();
|
||||||
|
gridSizeYInput.text = gridMap.NumY.ToString();
|
||||||
|
|
||||||
|
// Don't proceed with resize
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the grid size (only if within limits)
|
||||||
|
if (gridMap.ResizeGrid(newSizeX, newSizeY))
|
||||||
|
{
|
||||||
|
ClearPerformanceMetrics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,12 +418,28 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
if (startNode != null && endNode != null)
|
if (startNode != null && endNode != null)
|
||||||
{
|
{
|
||||||
ClearPerformanceMetrics();
|
ClearPerformanceMetrics();
|
||||||
|
|
||||||
|
// Set flags that pathfinding, visualization, and movement will happen
|
||||||
|
isPathfindingRunning = true;
|
||||||
|
isVisualizationRunning = true;
|
||||||
|
isNpcMoving = true; // assume movement will happen
|
||||||
|
SetUIInteractivity(false);
|
||||||
|
|
||||||
npc.MoveTo(endNode);
|
npc.MoveTo(endNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnResetPathfinding()
|
private void OnResetPathfinding()
|
||||||
{
|
{
|
||||||
|
// Reset all flags to ensure UI will be enabled after reload
|
||||||
|
isPathfindingRunning = false;
|
||||||
|
isVisualizationRunning = false;
|
||||||
|
isNpcMoving = false;
|
||||||
|
|
||||||
|
// Force enable UI - this ensures buttons will be enabled
|
||||||
|
// after reset regardless of editor/build status
|
||||||
|
SetUIInteractivity(true);
|
||||||
|
|
||||||
// Reload the current scene
|
// Reload the current scene
|
||||||
UnityEngine.SceneManagement.SceneManager.LoadScene(
|
UnityEngine.SceneManagement.SceneManager.LoadScene(
|
||||||
UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
|
UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
|
||||||
@ -352,10 +450,34 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
private void OnAlgorithmChanged(int index)
|
private void OnAlgorithmChanged(int index)
|
||||||
{
|
{
|
||||||
NPC.PathFinderType newType = (NPC.PathFinderType)index;
|
NPC.PathFinderType newType = (NPC.PathFinderType)index;
|
||||||
|
string algorithmName = GetAlgorithmName(newType);
|
||||||
|
|
||||||
|
Debug.Log($"Algorithm changed - Index: {index}, Type: {newType}, Name: {algorithmName}");
|
||||||
|
|
||||||
npc.ChangeAlgorithm(newType);
|
npc.ChangeAlgorithm(newType);
|
||||||
ClearPerformanceMetrics();
|
ClearPerformanceMetrics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to get the readable name of the algorithm
|
||||||
|
private string GetAlgorithmName(NPC.PathFinderType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case NPC.PathFinderType.ASTAR:
|
||||||
|
return "A*";
|
||||||
|
case NPC.PathFinderType.DIJKSTRA:
|
||||||
|
return "Dijkstra";
|
||||||
|
case NPC.PathFinderType.GREEDY:
|
||||||
|
return "Greedy BFS";
|
||||||
|
case NPC.PathFinderType.BACKTRACKING:
|
||||||
|
return "Backtracking";
|
||||||
|
case NPC.PathFinderType.BFS:
|
||||||
|
return "BFS";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnSaveMap()
|
private void OnSaveMap()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(mapNameInput.text))
|
if (string.IsNullOrEmpty(mapNameInput.text))
|
||||||
@ -426,24 +548,45 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
int sizeY = 20;
|
int sizeY = 20;
|
||||||
bool isLargeGrid = false;
|
bool isLargeGrid = false;
|
||||||
|
|
||||||
|
const int MAX_GRID_SIZE = 200;
|
||||||
|
const int MIN_GRID_SIZE = 2;
|
||||||
|
|
||||||
switch (mazeSizeDropdown.value)
|
switch (mazeSizeDropdown.value)
|
||||||
{
|
{
|
||||||
case 0: // Kecil
|
case 0: // Kecil
|
||||||
sizeX = sizeY = 20;
|
sizeX = sizeY = 20;
|
||||||
break;
|
break;
|
||||||
case 1: // Sedang
|
case 1: // Sedang
|
||||||
sizeX = sizeY = 50;
|
sizeX = sizeY = 35;
|
||||||
break;
|
break;
|
||||||
case 2: // Besar
|
case 2: // Besar
|
||||||
sizeX = sizeY = 100;
|
sizeX = sizeY = 50;
|
||||||
isLargeGrid = true;
|
isLargeGrid = true;
|
||||||
break;
|
break;
|
||||||
|
// If more options are added that exceed MAX_GRID_SIZE, they'll be rejected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if size exceeds maximum or is below minimum - reject if it does
|
||||||
|
if (sizeX > MAX_GRID_SIZE || sizeY > MAX_GRID_SIZE)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Maze size {sizeX}x{sizeY} exceeds maximum of {MAX_GRID_SIZE}x{MAX_GRID_SIZE}. Operation cancelled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeX < MIN_GRID_SIZE || sizeY < MIN_GRID_SIZE)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Maze size {sizeX}x{sizeY} is below minimum of {MIN_GRID_SIZE}x{MIN_GRID_SIZE}. Operation cancelled.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize grid if needed
|
// Resize grid if needed
|
||||||
if (gridMap.NumX != sizeX || gridMap.NumY != sizeY)
|
if (gridMap.NumX != sizeX || gridMap.NumY != sizeY)
|
||||||
{
|
{
|
||||||
gridMap.ResizeGrid(sizeX, sizeY);
|
if (!gridMap.ResizeGrid(sizeX, sizeY))
|
||||||
|
{
|
||||||
|
// Resize failed, abort maze generation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update grid size inputs
|
// Update grid size inputs
|
||||||
gridSizeXInput.text = sizeX.ToString();
|
gridSizeXInput.text = sizeX.ToString();
|
||||||
@ -586,4 +729,196 @@ public class PathfindingUIManager : MonoBehaviour
|
|||||||
// Reset performance metrics
|
// Reset performance metrics
|
||||||
ClearPerformanceMetrics();
|
ClearPerformanceMetrics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New method to handle pathfinding completion
|
||||||
|
private void OnPathfindingCompleted(PathfindingMetrics metrics)
|
||||||
|
{
|
||||||
|
// Pathfinding is completed, but visualization might still be running
|
||||||
|
isPathfindingRunning = false;
|
||||||
|
|
||||||
|
// Check if pathfinding failed by looking at metrics or path length
|
||||||
|
bool pathfindingFailed = (metrics.pathLength == 0) ||
|
||||||
|
(npc.pathFinder != null &&
|
||||||
|
npc.pathFinder.Status == PathFinding.PathFinderStatus.FAILURE);
|
||||||
|
|
||||||
|
if (pathfindingFailed)
|
||||||
|
{
|
||||||
|
// If pathfinding failed, there won't be any visualization or movement
|
||||||
|
Debug.Log("Pathfinding failed - re-enabling UI controls immediately");
|
||||||
|
isVisualizationRunning = false;
|
||||||
|
isNpcMoving = false;
|
||||||
|
|
||||||
|
// Only re-enable in editor mode
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
SetUIInteractivity(true);
|
||||||
|
#else
|
||||||
|
// In build, keep disabled
|
||||||
|
SetUIInteractivity(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If pathfinding succeeded, continue with normal flow
|
||||||
|
// Very important: Keep UI disabled regardless of visualization state to prevent
|
||||||
|
// the brief window of interactivity between pathfinding completion and visualization start
|
||||||
|
if (npc.showVisualization)
|
||||||
|
{
|
||||||
|
// If visualization is enabled in settings, assume it will start soon
|
||||||
|
// Keep UI disabled by keeping isVisualizationRunning true
|
||||||
|
isVisualizationRunning = true;
|
||||||
|
// Do NOT enable UI here - wait for visualization to complete
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only if visualization is completely disabled in settings, enable UI
|
||||||
|
isVisualizationRunning = false;
|
||||||
|
|
||||||
|
// Only re-enable in editor mode
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
SetUIInteractivity(true);
|
||||||
|
#else
|
||||||
|
// In build, keep disabled
|
||||||
|
SetUIInteractivity(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New method to handle visualization completion
|
||||||
|
private void OnVisualizationCompleted()
|
||||||
|
{
|
||||||
|
// Visualization is completed, but NPC may start moving
|
||||||
|
isVisualizationRunning = false;
|
||||||
|
|
||||||
|
// Check if NPC is moving or will move
|
||||||
|
if (npc.IsMoving || npc.wayPoints.Count > 0)
|
||||||
|
{
|
||||||
|
// Movement is starting or in progress
|
||||||
|
isNpcMoving = true;
|
||||||
|
// Leave UI disabled
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No movement expected
|
||||||
|
isNpcMoving = false;
|
||||||
|
|
||||||
|
// Only re-enable in editor mode
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
SetUIInteractivity(true);
|
||||||
|
#else
|
||||||
|
// In build, keep disabled
|
||||||
|
SetUIInteractivity(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New method to handle movement completion
|
||||||
|
private void OnMovementCompleted()
|
||||||
|
{
|
||||||
|
// Movement is completed, re-enable UI buttons only in editor
|
||||||
|
isNpcMoving = false;
|
||||||
|
|
||||||
|
// Only re-enable in editor mode
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
SetUIInteractivity(true);
|
||||||
|
#else
|
||||||
|
// In build, keep disabled
|
||||||
|
Debug.Log("Movement complete but keeping buttons disabled in build mode");
|
||||||
|
SetUIInteractivity(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to enable/disable UI elements based on pathfinding, visualization, and movement state
|
||||||
|
private void SetUIInteractivity(bool enabled)
|
||||||
|
{
|
||||||
|
// If any process is running, disable controls
|
||||||
|
bool shouldEnable = enabled && !isPathfindingRunning && !isVisualizationRunning && !isNpcMoving;
|
||||||
|
|
||||||
|
// In builds (not editor), once disabled, buttons stay disabled until reset
|
||||||
|
#if !UNITY_EDITOR
|
||||||
|
if (shouldEnable && (isPathfindingRunning || isVisualizationRunning || isNpcMoving))
|
||||||
|
{
|
||||||
|
// In builds, once pathfinding started, keep buttons disabled regardless
|
||||||
|
Debug.Log("In build - keeping buttons disabled even after completion");
|
||||||
|
shouldEnable = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add debug logging
|
||||||
|
Debug.Log($"SetUIInteractivity called with enabled={enabled}, pathfinding={isPathfindingRunning}, " +
|
||||||
|
$"visualization={isVisualizationRunning}, movement={isNpcMoving}, shouldEnable={shouldEnable}, " +
|
||||||
|
$"inEditor={Application.isEditor}");
|
||||||
|
|
||||||
|
// Keep reset and exit buttons always enabled
|
||||||
|
// Disable all other buttons when processes are running
|
||||||
|
|
||||||
|
if (applyGridSizeButton != null)
|
||||||
|
applyGridSizeButton.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (runPathfindingButton != null)
|
||||||
|
runPathfindingButton.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (algorithmDropdown != null)
|
||||||
|
algorithmDropdown.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (allowDiagonalToggle != null)
|
||||||
|
allowDiagonalToggle.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (saveButton != null)
|
||||||
|
saveButton.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (loadButton != null)
|
||||||
|
loadButton.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (generateMazeButton != null)
|
||||||
|
generateMazeButton.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (visualizationSpeedSlider != null)
|
||||||
|
visualizationSpeedSlider.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (visualizationBatchSlider != null)
|
||||||
|
visualizationBatchSlider.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (mazeSizeDropdown != null)
|
||||||
|
mazeSizeDropdown.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (mazeDensityDropdown != null)
|
||||||
|
mazeDensityDropdown.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (gridSizeXInput != null)
|
||||||
|
gridSizeXInput.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (gridSizeYInput != null)
|
||||||
|
gridSizeYInput.interactable = shouldEnable;
|
||||||
|
|
||||||
|
if (mapNameInput != null)
|
||||||
|
mapNameInput.interactable = shouldEnable;
|
||||||
|
|
||||||
|
// Reset and exit buttons remain enabled
|
||||||
|
// resetButton and exitButton stay interactable
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
// Continuously check for various states - this ensures buttons stay disabled
|
||||||
|
if (npc != null)
|
||||||
|
{
|
||||||
|
// Check visualization
|
||||||
|
if (npc.IsVisualizingPath && !isVisualizationRunning)
|
||||||
|
{
|
||||||
|
Debug.Log("Detected active visualization - updating UI state");
|
||||||
|
isVisualizationRunning = true;
|
||||||
|
SetUIInteractivity(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check movement
|
||||||
|
if (npc.IsMoving && !isNpcMoving)
|
||||||
|
{
|
||||||
|
Debug.Log("Detected active NPC movement - updating UI state");
|
||||||
|
isNpcMoving = true;
|
||||||
|
SetUIInteractivity(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
167
Assets/Scripts/TestPlan.md
Normal file
167
Assets/Scripts/TestPlan.md
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
# Rencana Pengujian Sistem Pathfinding
|
||||||
|
|
||||||
|
Dokumen ini menguraikan pendekatan pengujian komprehensif untuk sistem pathfinding, termasuk pengujian komponen sistem dan pengujian kinerja algoritma.
|
||||||
|
|
||||||
|
## I. Pengujian Komponen Sistem
|
||||||
|
|
||||||
|
### 1. Pengujian Input Ukuran Grid
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| GS-01 | Memasukkan ukuran grid yang valid (mis., 20x20) | Grid diubah ukuran dengan benar | □ |
|
||||||
|
| GS-02 | Memasukkan ukuran grid maksimum (200x200) | Grid diubah ukuran ke ukuran maksimum | □ |
|
||||||
|
| GS-03 | Memasukkan nilai melebihi maksimum (mis., 201x201) | Operasi ditolak, peringatan ditampilkan | □ |
|
||||||
|
| GS-04 | Memasukkan nilai non-numerik | Input ditolak | □ |
|
||||||
|
| GS-05 | Memasukkan nilai negatif atau nol | Input ditolak | □ |
|
||||||
|
| GS-06 | Mengubah ukuran selama pathfinding | Operasi diblokir selama pathfinding | □ |
|
||||||
|
| GS-07 | Menguji grid tidak persegi (mis., 20x30) | Grid membuat bentuk persegi panjang yang benar | □ |
|
||||||
|
|
||||||
|
### 2. Pengujian Dropdown Algoritma
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| ALG-01 | Pilih A* | Algoritma berubah ke A* | □ |
|
||||||
|
| ALG-02 | Pilih Dijkstra | Algoritma berubah ke Dijkstra | □ |
|
||||||
|
| ALG-03 | Pilih Greedy | Algoritma berubah ke Greedy | □ |
|
||||||
|
| ALG-04 | Pilih Backtracking | Algoritma berubah ke Backtracking | □ |
|
||||||
|
| ALG-05 | Pilih BFS | Algoritma berubah ke BFS | □ |
|
||||||
|
| ALG-06 | Mengubah algoritma selama pathfinding | Operasi diblokir selama pathfinding | □ |
|
||||||
|
|
||||||
|
### 3. Pengujian Toggle Pergerakan Diagonal
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| DIAG-01 | Aktifkan pergerakan diagonal | Pergerakan diagonal diaktifkan, jalur dapat menggunakan diagonal | □ |
|
||||||
|
| DIAG-02 | Nonaktifkan pergerakan diagonal | Pergerakan diagonal dinonaktifkan, jalur hanya menggunakan arah kardinal | □ |
|
||||||
|
| DIAG-03 | Toggle selama pathfinding | Operasi diblokir selama pathfinding | □ |
|
||||||
|
|
||||||
|
### 4. Pengujian Kontrol Visualisasi
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| VIS-01 | Menyesuaikan kecepatan visualisasi (meningkat) | Visualisasi berjalan lebih cepat | □ |
|
||||||
|
| VIS-02 | Menyesuaikan kecepatan visualisasi (menurun) | Visualisasi berjalan lebih lambat | □ |
|
||||||
|
| VIS-03 | Mengatur ukuran batch ke 1 | Setiap langkah divisualisasikan secara individual | □ |
|
||||||
|
| VIS-04 | Mengatur ukuran batch ke nilai lebih tinggi | Beberapa langkah divisualisasikan bersama | □ |
|
||||||
|
| VIS-05 | Menyesuaikan kontrol selama pathfinding | Operasi diblokir selama pathfinding | □ |
|
||||||
|
|
||||||
|
### 5. Pengujian Generator Labirin
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| MAZE-01 | Menghasilkan labirin kecil (kepadatan rendah) | Labirin dihasilkan dengan sedikit rintangan | □ |
|
||||||
|
| MAZE-02 | Menghasilkan labirin sedang (kepadatan sedang) | Labirin dihasilkan dengan rintangan moderat | □ |
|
||||||
|
| MAZE-03 | Menghasilkan labirin besar (kepadatan tinggi) | Labirin dihasilkan dengan banyak rintangan | □ |
|
||||||
|
| MAZE-04 | Menghasilkan labirin dengan kepadatan 0% | Grid kosong sepenuhnya dihasilkan | □ |
|
||||||
|
| MAZE-05 | Menghasilkan labirin dengan kepadatan 100% | Grid terisi penuh dihasilkan | □ |
|
||||||
|
| MAZE-06 | Menghasilkan labirin selama pathfinding | Operasi diblokir selama pathfinding | □ |
|
||||||
|
|
||||||
|
### 6. Pengujian Simpan dan Muat
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| SAVE-01 | Simpan dengan nama file valid | Labirin berhasil disimpan | □ |
|
||||||
|
| SAVE-02 | Simpan dengan nama file kosong | Pesan kesalahan ditampilkan | □ |
|
||||||
|
| SAVE-03 | Simpan selama pathfinding | Operasi diblokir selama pathfinding | □ |
|
||||||
|
| LOAD-01 | Muat file yang ada | Labirin berhasil dimuat | □ |
|
||||||
|
| LOAD-02 | Muat dengan nama file yang tidak ada | Pesan kesalahan ditampilkan | □ |
|
||||||
|
| LOAD-03 | Muat selama pathfinding | Operasi diblokir selama pathfinding | □ |
|
||||||
|
|
||||||
|
### 7. Pengujian Tombol Muat Ulang
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| RELOAD-01 | Klik tombol muat ulang | Scene dimuat ulang ke keadaan awal | □ |
|
||||||
|
| RELOAD-02 | Klik muat ulang selama pathfinding | Scene dimuat ulang, operasi diizinkan selama pathfinding | □ |
|
||||||
|
| RELOAD-03 | Klik muat ulang setelah pathfinding dalam mode build | Tombol diaktifkan kembali setelah reset | □ |
|
||||||
|
|
||||||
|
### 8. Pengujian Status UI
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| UI-01 | Mulai pathfinding | Semua tombol dinonaktifkan kecuali reload dan exit | □ |
|
||||||
|
| UI-02 | Setelah pathfinding selesai (editor) | Tombol diaktifkan kembali | □ |
|
||||||
|
| UI-03 | Setelah pathfinding selesai (build) | Tombol tetap dinonaktifkan | □ |
|
||||||
|
| UI-04 | Interaksi mouse selama pathfinding | Repositioning NPC/tujuan diblokir | □ |
|
||||||
|
|
||||||
|
## II. Pengujian Kinerja Algoritma
|
||||||
|
|
||||||
|
### 1. Pengujian Algoritma A*
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| ASTAR-01 | Grid kecil (20x20), kepadatan rendah | Jalur ditemukan secara efisien | □ |
|
||||||
|
| ASTAR-02 | Grid sedang (50x50), kepadatan sedang | Jalur ditemukan dengan kinerja wajar | □ |
|
||||||
|
| ASTAR-03 | Grid besar (100x100), kepadatan tinggi | Jalur ditemukan tanpa waktu/memori berlebihan | □ |
|
||||||
|
| ASTAR-04 | Jalur mustahil (kepadatan 100%) | Dengan benar melaporkan tidak ada jalur yang ditemukan | □ |
|
||||||
|
| ASTAR-05 | Dengan pergerakan diagonal | Jalur diagonal yang lebih pendek digunakan | □ |
|
||||||
|
| ASTAR-06 | Tanpa pergerakan diagonal | Hanya jalur kardinal yang digunakan | □ |
|
||||||
|
|
||||||
|
### 2. Pengujian Algoritma Dijkstra
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| DIJK-01 | Grid kecil (20x20), kepadatan rendah | Jalur ditemukan dengan eksplorasi lebih dari A* | □ |
|
||||||
|
| DIJK-02 | Grid sedang (50x50), kepadatan sedang | Jalur ditemukan dengan waktu/memori lebih tinggi dari A* | □ |
|
||||||
|
| DIJK-03 | Grid besar (100x100), kepadatan tinggi | Jalur ditemukan, mungkin dengan penggunaan sumber daya tinggi | □ |
|
||||||
|
| DIJK-04 | Jalur mustahil (kepadatan 100%) | Dengan benar melaporkan tidak ada jalur yang ditemukan | □ |
|
||||||
|
| DIJK-05 | Dengan pergerakan diagonal | Jalur optimal ditemukan | □ |
|
||||||
|
| DIJK-06 | Tanpa pergerakan diagonal | Jalur kardinal optimal ditemukan | □ |
|
||||||
|
|
||||||
|
### 3. Pengujian Greedy Best-First Search
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| GREEDY-01 | Grid kecil (20x20), kepadatan rendah | Kinerja cepat, jalur berpotensi tidak optimal | □ |
|
||||||
|
| GREEDY-02 | Grid sedang (50x50), kepadatan sedang | Kinerja cepat dengan memori lebih sedikit dari A*/Dijkstra | □ |
|
||||||
|
| GREEDY-03 | Grid besar (100x100), kepadatan tinggi | Lebih cepat dari A*/Dijkstra, tetapi mungkin tidak optimal | □ |
|
||||||
|
| GREEDY-04 | Jalur mustahil (kepadatan 100%) | Dengan benar melaporkan tidak ada jalur yang ditemukan | □ |
|
||||||
|
| GREEDY-05 | Labirin dengan bottleneck | Mungkin menghasilkan jalur yang tidak optimal | □ |
|
||||||
|
|
||||||
|
### 4. Pengujian Algoritma Backtracking
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| BACK-01 | Grid kecil (20x20), kepadatan rendah | Jalur ditemukan, kemungkinan lebih lambat dari algoritma lain | □ |
|
||||||
|
| BACK-02 | Grid sedang (50x50), kepadatan sedang | Degradasi kinerja dengan ukuran meningkat | □ |
|
||||||
|
| BACK-03 | Labirin kecil dengan kepadatan tinggi | Mungkin kesulitan dengan labirin kompleks | □ |
|
||||||
|
| BACK-04 | Jalur mustahil (kepadatan 100%) | Dengan benar melaporkan tidak ada jalur yang ditemukan | □ |
|
||||||
|
|
||||||
|
### 5. Pengujian Algoritma BFS
|
||||||
|
|
||||||
|
| ID Tes | Kasus Uji | Hasil yang Diharapkan | Lulus/Gagal |
|
||||||
|
|---------|-----------|----------------|-----------|
|
||||||
|
| BFS-01 | Grid kecil (20x20), kepadatan rendah | Jalur optimal untuk grid tanpa bobot | □ |
|
||||||
|
| BFS-02 | Grid sedang (50x50), kepadatan sedang | Penggunaan memori lebih tinggi dari A* | □ |
|
||||||
|
| BFS-03 | Grid besar (100x100), kepadatan tinggi | Konsumsi memori tinggi | □ |
|
||||||
|
| BFS-04 | Jalur mustahil (kepadatan 100%) | Dengan benar melaporkan tidak ada jalur yang ditemukan | □ |
|
||||||
|
|
||||||
|
## III. Matriks Kinerja Sistem Keseluruhan
|
||||||
|
|
||||||
|
| Algoritma | Grid Kecil | Grid Sedang | Grid Besar | Kepadatan Rendah | Kepadatan Tinggi | Dengan Diagonal | Tanpa Diagonal |
|
||||||
|
|-----------|------------|-------------|------------|------------------|-----------------|----------------|----------------|
|
||||||
|
| A* | □ | □ | □ | □ | □ | □ | □ |
|
||||||
|
| Dijkstra | □ | □ | □ | □ | □ | □ | □ |
|
||||||
|
| Greedy | □ | □ | □ | □ | □ | □ | □ |
|
||||||
|
| Backtracking | □ | □ | □ | □ | □ | □ | □ |
|
||||||
|
| BFS | □ | □ | □ | □ | □ | □ | □ |
|
||||||
|
|
||||||
|
## IV. Instruksi Pelaksanaan Pengujian
|
||||||
|
|
||||||
|
1. **Persiapan**:
|
||||||
|
- Pastikan proyek dalam keadaan bersih
|
||||||
|
- Untuk pengujian sistem, uji satu komponen pada satu waktu
|
||||||
|
- Untuk pengujian algoritma, gunakan penguji otomatis dengan berbagai kombinasi
|
||||||
|
|
||||||
|
2. **Dokumentasi**:
|
||||||
|
- Tandai setiap pengujian sebagai Lulus/Gagal dalam daftar periksa
|
||||||
|
- Catat anomali atau perilaku tidak terduga
|
||||||
|
- Dokumentasikan metrik kinerja jika berlaku
|
||||||
|
|
||||||
|
3. **Pengujian Regresi**:
|
||||||
|
- Setelah memperbaiki bug, jalankan kembali pengujian terkait untuk memastikan lulus
|
||||||
|
- Secara berkala jalankan rangkaian pengujian lengkap untuk menangkap regresi
|
||||||
|
|
||||||
|
4. **Pengujian Otomatis**:
|
||||||
|
- Gunakan PathfindingTester untuk pengujian algoritma otomatis
|
||||||
|
- Rekam dan analisis output CSV untuk perbandingan komprehensif
|
7
Assets/Scripts/TestPlan.md.meta
Normal file
7
Assets/Scripts/TestPlan.md.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 97b0707a63200c94cb3f55a0beb75ef2
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
69
Assets/Scripts/TestScene_README.txt
Normal file
69
Assets/Scripts/TestScene_README.txt
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Pathfinding Greybox Matrix Testing Setup Instructions
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This document outlines the step-by-step process for setting up a scene to perform automated greybox matrix testing of the pathfinding algorithms.
|
||||||
|
|
||||||
|
## Scene Setup Steps
|
||||||
|
|
||||||
|
1. Create a new scene or use an existing pathfinding scene
|
||||||
|
|
||||||
|
2. Add the required components to the scene:
|
||||||
|
- GridMap
|
||||||
|
- NPC
|
||||||
|
- UI Canvas for the test controls
|
||||||
|
|
||||||
|
3. Create the following UI elements on the Canvas:
|
||||||
|
- Panel (as a container)
|
||||||
|
- Text (TMP) for status display
|
||||||
|
- Button for starting tests
|
||||||
|
- Slider for progress visualization
|
||||||
|
|
||||||
|
4. Create an empty GameObject and attach the PathfindingTester.cs script
|
||||||
|
|
||||||
|
5. Configure the PathfindingTester component:
|
||||||
|
- Assign the GridMap reference
|
||||||
|
- Assign the NPC reference
|
||||||
|
- Assign the UI components (button, text, progress bar)
|
||||||
|
- Configure test parameters as needed:
|
||||||
|
- Tests Per Combination
|
||||||
|
- Delay Between Tests
|
||||||
|
- Results File Name
|
||||||
|
|
||||||
|
## UI Layout Recommendations
|
||||||
|
|
||||||
|
1. Place the status text at the top of the panel to show current test status
|
||||||
|
2. Place the progress bar below the status text
|
||||||
|
3. Place the "Start Tests" button at the bottom
|
||||||
|
4. Make the panel semi-transparent so you can still see the grid behind it
|
||||||
|
|
||||||
|
## Test Matrix Configuration
|
||||||
|
|
||||||
|
You can customize the test matrix by modifying these arrays in the PathfindingTester.cs script:
|
||||||
|
|
||||||
|
- algorithmsToTest: Which algorithms to test
|
||||||
|
- gridSizesToTest: Which grid sizes to test
|
||||||
|
- mazeDensitiesToTest: Which maze densities to test
|
||||||
|
- diagonalMovementOptions: Whether to test with diagonals enabled/disabled
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
1. Enter Play mode in the Unity editor
|
||||||
|
2. Click the "Start Tests" button
|
||||||
|
3. Wait for all tests to complete
|
||||||
|
4. Test results will be saved in a CSV file in the "TestResults" folder in the persistent data path
|
||||||
|
|
||||||
|
## Analyzing Results
|
||||||
|
|
||||||
|
The CSV file contains detailed information about each test:
|
||||||
|
- Algorithm used
|
||||||
|
- Grid size
|
||||||
|
- Maze density
|
||||||
|
- Diagonal movement setting
|
||||||
|
- Time taken (ms)
|
||||||
|
- Path length (nodes)
|
||||||
|
- Nodes explored
|
||||||
|
- Memory used
|
||||||
|
- Whether a path was found
|
||||||
|
- Test index (for repeated tests)
|
||||||
|
|
||||||
|
Import the CSV into a spreadsheet application for further analysis and visualization.
|
7
Assets/Scripts/TestScene_README.txt.meta
Normal file
7
Assets/Scripts/TestScene_README.txt.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5fd2581c099e0644fa3c48212c93208d
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
271
Assets/Scripts/pathfinding_tests.csv
Normal file
271
Assets/Scripts/pathfinding_tests.csv
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
Algorithm,GridSizeX,GridSizeY,Density,DiagonalMovement,TimeTaken,PathLength,NodesExplored,MemoryUsed,PathFound,TestIndex
|
||||||
|
ASTAR,20,20,10,True,1.0282,24,26,4096,True,0
|
||||||
|
ASTAR,20,20,10,True,0.1261,22,22,4096,True,1
|
||||||
|
ASTAR,20,20,10,True,0.1369,21,20,4096,True,2
|
||||||
|
ASTAR,20,20,10,False,0.12,39,38,4096,True,0
|
||||||
|
ASTAR,20,20,10,False,0.1708,39,53,8192,True,1
|
||||||
|
ASTAR,20,20,10,False,0.2009,39,69,12288,True,2
|
||||||
|
ASTAR,20,20,30,True,0.1264,26,27,8192,True,0
|
||||||
|
ASTAR,20,20,30,True,0.1366,26,29,8192,True,1
|
||||||
|
ASTAR,20,20,30,True,0.1186,24,25,8192,True,2
|
||||||
|
ASTAR,20,20,30,False,0.1441,39,45,4096,True,0
|
||||||
|
ASTAR,20,20,30,False,0.1042,39,48,12288,True,1
|
||||||
|
ASTAR,20,20,30,False,0.2301,39,87,24576,True,2
|
||||||
|
ASTAR,20,20,50,True,0.1618,43,89,16384,True,0
|
||||||
|
ASTAR,20,20,50,True,0.3753,54,171,8192,True,1
|
||||||
|
ASTAR,20,20,50,True,0.2745,48,130,8192,True,2
|
||||||
|
ASTAR,20,20,50,False,0.1702,63,104,0,True,0
|
||||||
|
ASTAR,20,20,50,False,0.1628,59,98,12288,True,1
|
||||||
|
ASTAR,20,20,50,False,0.3159,135,180,40960,True,2
|
||||||
|
ASTAR,35,35,10,True,0.2377,36,35,16384,True,0
|
||||||
|
ASTAR,35,35,10,True,0.2482,38,39,16384,True,1
|
||||||
|
ASTAR,35,35,10,True,0.2412,40,39,16384,True,2
|
||||||
|
ASTAR,35,35,10,False,0.2433,69,68,8192,True,0
|
||||||
|
ASTAR,35,35,10,False,0.281,69,95,24576,True,1
|
||||||
|
ASTAR,35,35,10,False,0.2874,69,93,20480,True,2
|
||||||
|
ASTAR,35,35,30,True,0.2388,47,46,20480,True,0
|
||||||
|
ASTAR,35,35,30,True,0.3082,45,68,4096,True,1
|
||||||
|
ASTAR,35,35,30,True,0.2438,42,44,4096,True,2
|
||||||
|
ASTAR,35,35,30,False,0.3319,69,111,4096,True,0
|
||||||
|
ASTAR,35,35,30,False,0.4247,69,139,20480,True,1
|
||||||
|
ASTAR,35,35,30,False,0.2607,69,86,12288,True,2
|
||||||
|
ASTAR,35,35,50,True,0.4856,101,261,36864,True,0
|
||||||
|
ASTAR,35,35,50,True,1.0796,219,563,98304,True,1
|
||||||
|
ASTAR,35,35,50,True,1.0919,97,529,114688,True,2
|
||||||
|
ASTAR,35,35,50,False,0.4922,145,300,69632,True,0
|
||||||
|
ASTAR,35,35,50,False,0.2173,97,134,24576,True,1
|
||||||
|
ASTAR,35,35,50,False,0.4082,77,191,28672,True,2
|
||||||
|
ASTAR,50,50,10,True,0.3457,54,53,40960,True,0
|
||||||
|
ASTAR,50,50,10,True,0.3793,54,53,16384,True,1
|
||||||
|
ASTAR,50,50,10,True,0.3698,57,56,16384,True,2
|
||||||
|
ASTAR,50,50,10,False,0.3816,99,98,20480,True,0
|
||||||
|
ASTAR,50,50,10,False,0.3855,99,120,20480,True,1
|
||||||
|
ASTAR,50,50,10,False,0.4885,99,158,24576,True,2
|
||||||
|
ASTAR,50,50,30,True,0.3388,59,61,16384,True,0
|
||||||
|
ASTAR,50,50,30,True,0.3565,57,59,20480,True,1
|
||||||
|
ASTAR,50,50,30,True,0.3343,64,67,20480,True,2
|
||||||
|
ASTAR,50,50,30,False,1.1702,99,412,102400,True,0
|
||||||
|
ASTAR,50,50,30,False,0.4831,99,153,32768,True,1
|
||||||
|
ASTAR,50,50,30,False,0.4641,99,200,8192,True,2
|
||||||
|
ASTAR,50,50,50,True,2.2106,147,926,73728,True,0
|
||||||
|
ASTAR,50,50,50,True,1.8848,162,854,73728,True,1
|
||||||
|
ASTAR,50,50,50,True,1.8428,305,1033,196608,True,2
|
||||||
|
ASTAR,50,50,50,False,1.3853,259,813,155648,True,0
|
||||||
|
ASTAR,50,50,50,False,1.3047,289,809,151552,True,1
|
||||||
|
ASTAR,50,50,50,False,0.7769,223,485,77824,True,2
|
||||||
|
DIJKSTRA,20,20,10,True,0.5732,21,360,69632,True,0
|
||||||
|
DIJKSTRA,20,20,10,True,0.6119,21,360,69632,True,1
|
||||||
|
DIJKSTRA,20,20,10,True,0.5995,20,360,81920,True,2
|
||||||
|
DIJKSTRA,20,20,10,False,0.4575,39,360,126976,True,0
|
||||||
|
DIJKSTRA,20,20,10,False,0.4468,39,359,114688,True,1
|
||||||
|
DIJKSTRA,20,20,10,False,0.4462,39,361,32768,True,2
|
||||||
|
DIJKSTRA,20,20,30,True,0.4703,23,281,32768,True,0
|
||||||
|
DIJKSTRA,20,20,30,True,0.4805,25,281,32768,True,1
|
||||||
|
DIJKSTRA,20,20,30,True,0.4821,24,281,61440,True,2
|
||||||
|
DIJKSTRA,20,20,30,False,0.3919,39,282,65536,True,0
|
||||||
|
DIJKSTRA,20,20,30,False,0.3812,41,280,61440,True,1
|
||||||
|
DIJKSTRA,20,20,30,False,0.3457,39,281,61440,True,2
|
||||||
|
DIJKSTRA,20,20,50,True,0.2829,44,197,28672,True,0
|
||||||
|
DIJKSTRA,20,20,50,True,0.2141,58,144,20480,True,1
|
||||||
|
DIJKSTRA,20,20,50,True,0.2861,66,192,32768,True,2
|
||||||
|
DIJKSTRA,20,20,50,False,0.2427,59,189,28672,True,0
|
||||||
|
DIJKSTRA,20,20,50,False,0.1485,51,115,24576,True,1
|
||||||
|
DIJKSTRA,20,20,50,False,0.1985,91,159,45056,True,2
|
||||||
|
DIJKSTRA,35,35,10,True,2.1114,37,1103,327680,True,0
|
||||||
|
DIJKSTRA,35,35,10,True,2.0576,37,1103,94208,True,1
|
||||||
|
DIJKSTRA,35,35,10,True,2.1407,37,1104,94208,True,2
|
||||||
|
DIJKSTRA,35,35,10,False,1.5362,69,1103,253952,True,0
|
||||||
|
DIJKSTRA,35,35,10,False,1.4893,69,1103,204800,True,1
|
||||||
|
DIJKSTRA,35,35,10,False,1.4763,69,1103,200704,True,2
|
||||||
|
DIJKSTRA,35,35,30,True,1.5209,42,858,163840,True,0
|
||||||
|
DIJKSTRA,35,35,30,True,1.435,42,857,155648,True,1
|
||||||
|
DIJKSTRA,35,35,30,True,1.4548,40,857,159744,True,2
|
||||||
|
DIJKSTRA,35,35,30,False,1.129,69,856,253952,True,0
|
||||||
|
DIJKSTRA,35,35,30,False,1.1949,69,855,253952,True,1
|
||||||
|
DIJKSTRA,35,35,30,False,1.1977,69,856,294912,True,2
|
||||||
|
DIJKSTRA,35,35,50,True,0.6041,136,400,28672,True,0
|
||||||
|
DIJKSTRA,35,35,50,True,0.6758,145,487,28672,True,1
|
||||||
|
DIJKSTRA,35,35,50,True,0.6081,137,424,28672,True,2
|
||||||
|
DIJKSTRA,35,35,50,False,0.58,0,0,8192,False,0
|
||||||
|
DIJKSTRA,35,35,50,False,0.4809,129,362,65536,True,1
|
||||||
|
DIJKSTRA,35,35,50,False,0.7123,77,532,98304,True,2
|
||||||
|
DIJKSTRA,50,50,10,True,4.5189,51,2250,409600,True,0
|
||||||
|
DIJKSTRA,50,50,10,True,4.5321,53,2250,409600,True,1
|
||||||
|
DIJKSTRA,50,50,10,True,4.3824,54,2251,573440,True,2
|
||||||
|
DIJKSTRA,50,50,10,False,3.1707,99,2250,659456,True,0
|
||||||
|
DIJKSTRA,50,50,10,False,3.3113,99,2250,663552,True,1
|
||||||
|
DIJKSTRA,50,50,10,False,3.3981,99,2251,188416,True,2
|
||||||
|
DIJKSTRA,50,50,30,True,3.2778,58,1750,258048,True,0
|
||||||
|
DIJKSTRA,50,50,30,True,3.0818,58,1751,327680,True,1
|
||||||
|
DIJKSTRA,50,50,30,True,3.1183,58,1750,323584,True,2
|
||||||
|
DIJKSTRA,50,50,30,False,2.4624,99,1749,323584,True,0
|
||||||
|
DIJKSTRA,50,50,30,False,2.5493,99,1751,323584,True,1
|
||||||
|
DIJKSTRA,50,50,30,False,2.4891,99,1749,319488,True,2
|
||||||
|
DIJKSTRA,50,50,50,True,1.2986,301,880,217088,True,0
|
||||||
|
DIJKSTRA,50,50,50,True,1.6238,194,1187,344064,True,1
|
||||||
|
DIJKSTRA,50,50,50,True,2.5347,174,565,184320,True,2
|
||||||
|
DIJKSTRA,50,50,50,False,1.2548,271,896,73728,True,0
|
||||||
|
DIJKSTRA,50,50,50,False,1.3304,409,934,90112,True,1
|
||||||
|
DIJKSTRA,50,50,50,False,0.7657,357,612,122880,True,2
|
||||||
|
GREEDY,20,20,10,True,0.1293,22,22,8192,True,0
|
||||||
|
GREEDY,20,20,10,True,0.1508,21,21,8192,True,1
|
||||||
|
GREEDY,20,20,10,True,0.1445,21,21,4096,True,2
|
||||||
|
GREEDY,20,20,10,False,0.1191,39,39,4096,True,0
|
||||||
|
GREEDY,20,20,10,False,0.1347,41,41,4096,True,1
|
||||||
|
GREEDY,20,20,10,False,0.1692,43,46,12288,True,2
|
||||||
|
GREEDY,20,20,30,True,0.1515,25,27,4096,True,0
|
||||||
|
GREEDY,20,20,30,True,0.1471,25,25,8192,True,1
|
||||||
|
GREEDY,20,20,30,True,0.1325,28,28,8192,True,2
|
||||||
|
GREEDY,20,20,30,False,0.166,43,46,0,True,0
|
||||||
|
GREEDY,20,20,30,False,0.1449,39,45,0,True,1
|
||||||
|
GREEDY,20,20,30,False,0.1382,41,45,0,True,2
|
||||||
|
GREEDY,20,20,50,True,0.2456,47,95,0,True,0
|
||||||
|
GREEDY,20,20,50,True,0.3083,60,119,12288,True,1
|
||||||
|
GREEDY,20,20,50,True,0.2403,60,80,8192,True,2
|
||||||
|
GREEDY,20,20,50,False,0.2485,67,115,12288,True,0
|
||||||
|
GREEDY,20,20,50,False,0.173,59,91,20480,True,1
|
||||||
|
GREEDY,20,20,50,False,0.3466,79,193,20480,True,2
|
||||||
|
GREEDY,35,35,10,True,0.2559,39,39,16384,True,0
|
||||||
|
GREEDY,35,35,10,True,0.2487,38,38,16384,True,1
|
||||||
|
GREEDY,35,35,10,True,0.2573,40,40,24576,True,2
|
||||||
|
GREEDY,35,35,10,False,0.3217,83,95,20480,True,0
|
||||||
|
GREEDY,35,35,10,False,0.6061,69,69,32768,True,1
|
||||||
|
GREEDY,35,35,10,False,0.281,69,69,4096,True,2
|
||||||
|
GREEDY,35,35,30,True,0.2408,43,45,8192,True,0
|
||||||
|
GREEDY,35,35,30,True,0.2331,43,43,4096,True,1
|
||||||
|
GREEDY,35,35,30,True,0.2392,42,42,12288,True,2
|
||||||
|
GREEDY,35,35,30,False,0.225,71,77,8192,True,0
|
||||||
|
GREEDY,35,35,30,False,0.2613,83,83,12288,True,1
|
||||||
|
GREEDY,35,35,30,False,0.23,71,71,8192,True,2
|
||||||
|
GREEDY,35,35,50,True,0.9538,91,365,65536,True,0
|
||||||
|
GREEDY,35,35,50,True,0.9843,147,364,81920,True,1
|
||||||
|
GREEDY,35,35,50,True,0.7238,197,300,94208,True,2
|
||||||
|
GREEDY,35,35,50,False,0.3991,147,194,28672,True,0
|
||||||
|
GREEDY,35,35,50,False,0.4047,117,211,49152,True,1
|
||||||
|
GREEDY,35,35,50,False,0.3874,183,196,4096,True,2
|
||||||
|
GREEDY,50,50,10,True,0.3848,57,58,16384,True,0
|
||||||
|
GREEDY,50,50,10,True,0.3706,58,58,20480,True,1
|
||||||
|
GREEDY,50,50,10,True,0.3754,54,54,24576,True,2
|
||||||
|
GREEDY,50,50,10,False,0.3671,99,99,28672,True,0
|
||||||
|
GREEDY,50,50,10,False,0.3749,99,99,12288,True,1
|
||||||
|
GREEDY,50,50,10,False,0.3661,101,102,24576,True,2
|
||||||
|
GREEDY,50,50,30,True,0.3392,63,63,24576,True,0
|
||||||
|
GREEDY,50,50,30,True,0.3247,64,64,20480,True,1
|
||||||
|
GREEDY,50,50,30,True,0.3234,68,69,24576,True,2
|
||||||
|
GREEDY,50,50,30,False,0.4684,123,147,8192,True,0
|
||||||
|
GREEDY,50,50,30,False,0.3809,107,108,4096,True,1
|
||||||
|
GREEDY,50,50,30,False,0.3617,101,109,4096,True,2
|
||||||
|
GREEDY,50,50,50,True,0.7341,208,268,45056,True,0
|
||||||
|
GREEDY,50,50,50,True,0.849,172,316,65536,True,1
|
||||||
|
GREEDY,50,50,50,True,0.6744,168,222,32768,True,2
|
||||||
|
GREEDY,50,50,50,False,1.0245,211,568,98304,True,0
|
||||||
|
GREEDY,50,50,50,False,1.2286,507,721,143360,True,1
|
||||||
|
GREEDY,50,50,50,False,1.2725,419,670,172032,True,2
|
||||||
|
BACKTRACKING,20,20,10,True,0.3594,121,131,69632,True,0
|
||||||
|
BACKTRACKING,20,20,10,True,0.3929,111,164,61440,True,1
|
||||||
|
BACKTRACKING,20,20,10,True,0.2945,104,116,65536,True,2
|
||||||
|
BACKTRACKING,20,20,10,False,0.4242,183,241,28672,True,0
|
||||||
|
BACKTRACKING,20,20,10,False,0.3568,187,205,28672,True,1
|
||||||
|
BACKTRACKING,20,20,10,False,0.3895,177,221,28672,True,2
|
||||||
|
BACKTRACKING,20,20,30,True,0.3235,75,129,28672,True,0
|
||||||
|
BACKTRACKING,20,20,30,True,0.3471,77,167,36864,True,1
|
||||||
|
BACKTRACKING,20,20,30,True,0.3286,92,140,36864,True,2
|
||||||
|
BACKTRACKING,20,20,30,False,0.3422,147,203,45056,True,0
|
||||||
|
BACKTRACKING,20,20,30,False,0.2824,137,191,32768,True,1
|
||||||
|
BACKTRACKING,20,20,30,False,0.3286,157,193,36864,True,2
|
||||||
|
BACKTRACKING,20,20,50,True,0.2677,30,137,28672,True,0
|
||||||
|
BACKTRACKING,20,20,50,True,0.2214,37,130,24576,True,1
|
||||||
|
BACKTRACKING,20,20,50,True,0.1721,42,104,20480,True,2
|
||||||
|
BACKTRACKING,20,20,50,False,0.1367,71,124,36864,True,0
|
||||||
|
BACKTRACKING,20,20,50,False,0.2432,79,179,8192,True,1
|
||||||
|
BACKTRACKING,20,20,50,False,0.2324,43,186,8192,True,2
|
||||||
|
BACKTRACKING,35,35,10,True,1.465,328,401,106496,True,0
|
||||||
|
BACKTRACKING,35,35,10,True,1.3811,323,409,188416,True,1
|
||||||
|
BACKTRACKING,35,35,10,True,1.1492,285,349,147456,True,2
|
||||||
|
BACKTRACKING,35,35,10,False,1.4213,521,635,188416,True,0
|
||||||
|
BACKTRACKING,35,35,10,False,1.4778,527,680,188416,True,1
|
||||||
|
BACKTRACKING,35,35,10,False,1.4704,573,649,184320,True,2
|
||||||
|
BACKTRACKING,35,35,30,True,1.1103,290,408,110592,True,0
|
||||||
|
BACKTRACKING,35,35,30,True,1.0674,241,456,208896,True,1
|
||||||
|
BACKTRACKING,35,35,30,True,1.1679,270,445,212992,True,2
|
||||||
|
BACKTRACKING,35,35,30,False,0.931,429,556,245760,True,0
|
||||||
|
BACKTRACKING,35,35,30,False,1.0727,403,561,69632,True,1
|
||||||
|
BACKTRACKING,35,35,30,False,1.5718,401,618,69632,True,2
|
||||||
|
BACKTRACKING,35,35,50,True,0.6532,77,428,24576,True,0
|
||||||
|
BACKTRACKING,35,35,50,True,0.2979,79,179,28672,True,1
|
||||||
|
BACKTRACKING,35,35,50,True,0.4046,125,241,40960,True,2
|
||||||
|
BACKTRACKING,35,35,50,False,0.3571,0,0,4096,False,0
|
||||||
|
BACKTRACKING,35,35,50,False,0.652,193,506,102400,True,1
|
||||||
|
BACKTRACKING,35,35,50,False,0.3799,0,0,16384,False,2
|
||||||
|
BACKTRACKING,50,50,10,True,3.1519,636,758,438272,True,0
|
||||||
|
BACKTRACKING,50,50,10,True,2.5557,565,614,495616,True,1
|
||||||
|
BACKTRACKING,50,50,10,True,3.3404,651,845,610304,True,2
|
||||||
|
BACKTRACKING,50,50,10,False,3.7901,1137,1239,241664,True,0
|
||||||
|
BACKTRACKING,50,50,10,False,3.601,1099,1299,200704,True,1
|
||||||
|
BACKTRACKING,50,50,10,False,3.2003,967,1197,319488,True,2
|
||||||
|
BACKTRACKING,50,50,30,True,2.6415,593,733,212992,True,0
|
||||||
|
BACKTRACKING,50,50,30,True,2.1968,520,708,217088,True,1
|
||||||
|
BACKTRACKING,50,50,30,True,2.4687,557,787,225280,True,2
|
||||||
|
BACKTRACKING,50,50,30,False,2.5318,703,1337,294912,True,0
|
||||||
|
BACKTRACKING,50,50,30,False,2.1927,687,1132,430080,True,1
|
||||||
|
BACKTRACKING,50,50,30,False,2.2509,821,1179,438272,True,2
|
||||||
|
BACKTRACKING,50,50,50,True,1.2183,145,849,262144,True,0
|
||||||
|
BACKTRACKING,50,50,50,True,0.8606,234,570,204800,True,1
|
||||||
|
BACKTRACKING,50,50,50,True,1.8035,150,1043,131072,True,2
|
||||||
|
BACKTRACKING,50,50,50,False,1.2391,655,933,98304,True,0
|
||||||
|
BACKTRACKING,50,50,50,False,0.9434,335,763,131072,True,1
|
||||||
|
BACKTRACKING,50,50,50,False,0.7697,195,577,114688,True,2
|
||||||
|
BFS,20,20,10,True,0.4677,20,360,61440,True,0
|
||||||
|
BFS,20,20,10,True,0.621,21,361,77824,True,1
|
||||||
|
BFS,20,20,10,True,0.5292,21,361,65536,True,2
|
||||||
|
BFS,20,20,10,False,0.3891,39,361,65536,True,0
|
||||||
|
BFS,20,20,10,False,0.4235,39,361,65536,True,1
|
||||||
|
BFS,20,20,10,False,0.4674,39,360,90112,True,2
|
||||||
|
BFS,20,20,30,True,0.3917,25,282,73728,True,0
|
||||||
|
BFS,20,20,30,True,0.3715,26,281,86016,True,1
|
||||||
|
BFS,20,20,30,True,0.449,23,282,24576,True,2
|
||||||
|
BFS,20,20,30,False,0.3117,39,255,16384,True,0
|
||||||
|
BFS,20,20,30,False,0.3499,39,281,24576,True,1
|
||||||
|
BFS,20,20,30,False,0.3472,39,282,57344,True,2
|
||||||
|
BFS,20,20,50,True,0.2092,42,144,20480,True,0
|
||||||
|
BFS,20,20,50,True,0.2498,41,161,32768,True,1
|
||||||
|
BFS,20,20,50,True,0.2399,38,163,24576,True,2
|
||||||
|
BFS,20,20,50,False,0.2321,59,155,24576,True,0
|
||||||
|
BFS,20,20,50,False,0.2403,71,162,24576,True,1
|
||||||
|
BFS,20,20,50,False,0.1412,51,100,16384,True,2
|
||||||
|
BFS,35,35,10,True,1.679,38,1104,233472,True,0
|
||||||
|
BFS,35,35,10,True,1.6694,36,1103,294912,True,1
|
||||||
|
BFS,35,35,10,True,1.7347,39,1104,425984,True,2
|
||||||
|
BFS,35,35,10,False,1.4652,69,1103,118784,True,0
|
||||||
|
BFS,35,35,10,False,1.3521,69,1103,118784,True,1
|
||||||
|
BFS,35,35,10,False,1.3525,69,1103,221184,True,2
|
||||||
|
BFS,35,35,30,True,1.2777,40,855,139264,True,0
|
||||||
|
BFS,35,35,30,True,1.2761,43,857,143360,True,1
|
||||||
|
BFS,35,35,30,True,1.3204,43,857,147456,True,2
|
||||||
|
BFS,35,35,30,False,1.1577,69,857,176128,True,0
|
||||||
|
BFS,35,35,30,False,1.1088,69,854,143360,True,1
|
||||||
|
BFS,35,35,30,False,1.1091,69,857,188416,True,2
|
||||||
|
BFS,35,35,50,True,0.6461,53,490,155648,True,0
|
||||||
|
BFS,35,35,50,True,0.6363,88,510,155648,True,1
|
||||||
|
BFS,35,35,50,True,0.4843,100,350,110592,True,2
|
||||||
|
BFS,35,35,50,False,0.9047,79,544,57344,True,0
|
||||||
|
BFS,35,35,50,False,0.3727,0,0,4096,False,1
|
||||||
|
BFS,35,35,50,False,0.4923,0,0,8192,False,2
|
||||||
|
BFS,50,50,10,True,3.7701,53,2250,581632,True,0
|
||||||
|
BFS,50,50,10,True,3.4752,52,2250,462848,True,1
|
||||||
|
BFS,50,50,10,True,3.5727,52,2250,458752,True,2
|
||||||
|
BFS,50,50,10,False,2.7849,99,2251,471040,True,0
|
||||||
|
BFS,50,50,10,False,2.7301,99,2251,598016,True,1
|
||||||
|
BFS,50,50,10,False,2.6218,99,2251,716800,True,2
|
||||||
|
BFS,50,50,30,True,2.346,62,1751,491520,True,0
|
||||||
|
BFS,50,50,30,True,2.3452,58,1750,118784,True,1
|
||||||
|
BFS,50,50,30,True,2.6295,58,1751,118784,True,2
|
||||||
|
BFS,50,50,30,False,2.2686,99,1751,290816,True,0
|
||||||
|
BFS,50,50,30,False,2.1289,99,1751,286720,True,1
|
||||||
|
BFS,50,50,30,False,2.2602,99,1751,294912,True,2
|
||||||
|
BFS,50,50,50,True,1.0863,240,773,139264,True,0
|
||||||
|
BFS,50,50,50,True,0.8318,174,592,118784,True,1
|
||||||
|
BFS,50,50,50,True,0.7613,160,535,110592,True,2
|
||||||
|
BFS,50,50,50,False,1.3722,487,1120,282624,True,0
|
||||||
|
BFS,50,50,50,False,0.8369,227,677,200704,True,1
|
||||||
|
BFS,50,50,50,False,1.3386,223,996,311296,True,2
|
|
7
Assets/Scripts/pathfinding_tests.csv.meta
Normal file
7
Assets/Scripts/pathfinding_tests.csv.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b5f5e061be1cbf946b769794cb0ba604
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Reference in New Issue
Block a user