mirror of
https://github.com/BobbyRafael31/Unity-MazeRunner-Pathfinding-Visualizer.git
synced 2025-08-10 08:22: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_EditorClassIdentifier:
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -2212,6 +2379,96 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 332997443}
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -4605,6 +4862,82 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 809150985}
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -4829,9 +5162,11 @@ MonoBehaviour:
|
||||
loadButton: {fileID: 332997445}
|
||||
exitButton: {fileID: 1403363528}
|
||||
performWarmup: 1
|
||||
showWarmupMessage: 0
|
||||
showWarmupMessage: 1
|
||||
mazeSizeDropdown: {fileID: 770082012}
|
||||
mazeDensityDropdown: {fileID: 1448650261}
|
||||
testerPanelPrefab: {fileID: 0}
|
||||
testerPanelParent: {fileID: 0}
|
||||
--- !u!4 &840407876
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -5023,6 +5358,45 @@ MonoBehaviour:
|
||||
m_isRichTextEditingAllowed: 0
|
||||
m_LineLimit: 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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -5158,6 +5532,82 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 877190939}
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -7627,6 +8077,7 @@ RectTransform:
|
||||
- {fileID: 442352525}
|
||||
- {fileID: 1963564225}
|
||||
- {fileID: 1649005401}
|
||||
- {fileID: 873489265}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 5
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
@ -7711,6 +8162,128 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1269161862}
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -11124,6 +11697,141 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding: {x: -8, y: -5, z: -8, w: -5}
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -12326,6 +13034,141 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1939810452}
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -12447,6 +13290,43 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1963564224}
|
||||
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
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -239,6 +239,15 @@ public class GridMap : MonoBehaviour
|
||||
/// </summary>
|
||||
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
|
||||
Vector2 rayPos = new Vector2(
|
||||
Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
|
||||
@ -291,6 +300,15 @@ public class GridMap : MonoBehaviour
|
||||
/// </summary>
|
||||
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
|
||||
Vector2 rayPos = new Vector2(
|
||||
Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
|
||||
@ -318,6 +336,11 @@ public class GridMap : MonoBehaviour
|
||||
/// </summary>
|
||||
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
|
||||
if (Input.GetMouseButton(2)) // Middle mouse button
|
||||
{
|
||||
@ -336,6 +359,13 @@ public class GridMap : MonoBehaviour
|
||||
|
||||
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
|
||||
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
|
||||
if (Input.GetMouseButtonDown(1))
|
||||
{
|
||||
RayCastAndSetDestination();
|
||||
if (!isPathfindingActive)
|
||||
{
|
||||
RayCastAndSetDestination();
|
||||
}
|
||||
}
|
||||
|
||||
// Menyesuaikan ukuran kamera dengan scroll wheel
|
||||
@ -698,8 +731,24 @@ public class GridMap : MonoBehaviour
|
||||
/// <summary>
|
||||
/// Resizes the grid to the specified dimensions
|
||||
/// </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
|
||||
if (gridNodeViews != null)
|
||||
{
|
||||
@ -749,6 +798,8 @@ public class GridMap : MonoBehaviour
|
||||
{
|
||||
npc.SetStartNode(gridNodeViews[0, 0].Node);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <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>
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -21,17 +21,26 @@ public struct PathfindingMetrics
|
||||
public float totalGCost; // Total biaya G untuk jalur (jarak sebenarnya)
|
||||
public float totalHCost; // Total biaya H untuk jalur (heuristik)
|
||||
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 float speed = 2.0f;
|
||||
public Queue<Vector2> wayPoints = new Queue<Vector2>();
|
||||
|
||||
|
||||
// Event that fires when pathfinding is complete with performance metrics
|
||||
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
|
||||
{
|
||||
ASTAR,
|
||||
@ -44,13 +53,26 @@ public class NPC : MonoBehaviour
|
||||
[SerializeField]
|
||||
public PathFinderType pathFinderType = PathFinderType.ASTAR;
|
||||
|
||||
PathFinder<Vector2Int> pathFinder = null;
|
||||
public PathFinder<Vector2Int> pathFinder = null;
|
||||
|
||||
public GridMap Map { get; set; }
|
||||
|
||||
// List to store all steps for visualization playback
|
||||
private List<PathfindingVisualizationStep> visualizationSteps = new List<PathfindingVisualizationStep>();
|
||||
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
|
||||
[SerializeField]
|
||||
@ -110,11 +132,27 @@ public class NPC : MonoBehaviour
|
||||
{
|
||||
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(
|
||||
Coroutine_MoveToPoint(
|
||||
wayPoints.Dequeue(),
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -236,8 +274,10 @@ public class NPC : MonoBehaviour
|
||||
{
|
||||
yield return StartCoroutine(MeasurePerformance(silentMode));
|
||||
|
||||
// Start visualization after calculation is complete
|
||||
if (pathFinder.Status == PathFinderStatus.SUCCESS && showVisualization && !silentMode)
|
||||
// Start visualization after calculation is complete regardless of success or failure
|
||||
// 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());
|
||||
}
|
||||
@ -254,8 +294,8 @@ public class NPC : MonoBehaviour
|
||||
// Pre-allocate visualizationSteps with estimated capacity to avoid reallocations
|
||||
visualizationSteps = new List<PathfindingVisualizationStep>(4);
|
||||
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers(); // Tunggu semua finalizers selesai
|
||||
//GC.Collect(2, GCCollectionMode.Forced, true, true);
|
||||
//GC.WaitForPendingFinalizers(); // Tunggu semua finalizers selesai
|
||||
|
||||
// ===== MEMORY MEASUREMENT START: Ukur memory sebelum algoritma =====
|
||||
long memoryBefore = System.GC.GetTotalMemory(false);
|
||||
@ -284,13 +324,9 @@ public class NPC : MonoBehaviour
|
||||
long memoryAfter = System.GC.GetTotalMemory(false);
|
||||
long memoryUsed = memoryAfter - memoryBefore;
|
||||
|
||||
// float miliseconds = algorithmTimer.ElapsedMilliseconds;
|
||||
|
||||
//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);
|
||||
|
||||
// Store the memory usage for external access
|
||||
LastMeasuredMemoryUsage = memoryUsed > 0 ? memoryUsed : 1024;
|
||||
|
||||
float milliseconds = (algorithmTimer.ElapsedTicks * 1000.0f) / Stopwatch.Frequency;
|
||||
|
||||
// Calculate path length once and reuse
|
||||
@ -324,11 +360,9 @@ public class NPC : MonoBehaviour
|
||||
totalFCost = totalFCost,
|
||||
};
|
||||
|
||||
// *** IMPORTANT FIX: Always invoke the event, regardless of silent mode ***
|
||||
// Report metrics before visualization
|
||||
if (!silentMode)
|
||||
{
|
||||
OnPathfindingComplete?.Invoke(metrics);
|
||||
}
|
||||
OnPathfindingComplete?.Invoke(metrics);
|
||||
|
||||
// Path visualization and handling
|
||||
HandlePathFindingResult(silentMode, pathLength);
|
||||
@ -418,7 +452,6 @@ public class NPC : MonoBehaviour
|
||||
/// </summary>
|
||||
private void HandlePathFindingResult(bool silentMode, int pathLength)
|
||||
{
|
||||
|
||||
if (pathFinder.Status == PathFinderStatus.SUCCESS)
|
||||
{
|
||||
OnSuccessPathFinding();
|
||||
@ -449,6 +482,11 @@ public class NPC : MonoBehaviour
|
||||
else if (pathFinder.Status == PathFinderStatus.FAILURE)
|
||||
{
|
||||
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,8 +592,9 @@ public class NPC : MonoBehaviour
|
||||
if (!showVisualization)
|
||||
yield break;
|
||||
|
||||
UnityEngine.Debug.Log("Path visualization starting");
|
||||
isVisualizingPath = true;
|
||||
|
||||
|
||||
// First, ensure grid is reset
|
||||
Map.ResetGridNodeColours();
|
||||
|
||||
@ -563,6 +602,14 @@ public class NPC : MonoBehaviour
|
||||
int stepCount = visualizationSteps.Count;
|
||||
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)
|
||||
{
|
||||
int end = Mathf.Min(i + batchSize, stepCount);
|
||||
@ -587,8 +634,8 @@ public class NPC : MonoBehaviour
|
||||
break;
|
||||
case PathfindingVisualizationStep.StepType.FinalPath:
|
||||
gnv.SetInnerColor(Map.COLOR_PATH);
|
||||
// Also add the waypoint when we process the path
|
||||
if (step.type == PathfindingVisualizationStep.StepType.FinalPath)
|
||||
// Only add waypoints for successful pathfinding
|
||||
if (!pathfindingFailed)
|
||||
{
|
||||
GridNode pathNode = Map.GetGridNode(step.position.x, step.position.y);
|
||||
AddWayPoint(pathNode);
|
||||
@ -603,6 +650,9 @@ public class NPC : MonoBehaviour
|
||||
}
|
||||
|
||||
isVisualizingPath = false;
|
||||
UnityEngine.Debug.Log("Path visualization complete, invoking OnVisualizationComplete event");
|
||||
// Notify any listeners that visualization is complete
|
||||
OnVisualizationComplete?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1360,7 +1360,8 @@ namespace PathFinding
|
||||
#region Breath-First Search Algorithm
|
||||
/// <summary>
|
||||
/// 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>
|
||||
/// <typeparam name="T">Tipe data nilai yang disimpan dalam node</typeparam>
|
||||
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.UI;
|
||||
using TMPro;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
public class PathfindingUIManager : MonoBehaviour
|
||||
@ -52,9 +54,23 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
public TMP_Dropdown mazeSizeDropdown;
|
||||
public TMP_Dropdown mazeDensityDropdown;
|
||||
|
||||
[Header("Automated Testing")]
|
||||
[SerializeField] private GameObject testerPanelPrefab;
|
||||
[SerializeField] private Transform testerPanelParent;
|
||||
private GameObject testerPanelInstance;
|
||||
|
||||
// Konstanta untuk perhitungan CPU usage
|
||||
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()
|
||||
{
|
||||
// Initialize UI elements
|
||||
@ -91,6 +107,13 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
|
||||
// Subscribe to NPC's pathfinding events
|
||||
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
|
||||
ClearPerformanceMetrics();
|
||||
@ -213,6 +236,9 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
if (npc != null)
|
||||
{
|
||||
npc.OnPathfindingComplete -= UpdatePerformanceMetrics;
|
||||
npc.OnPathfindingComplete -= OnPathfindingCompleted;
|
||||
npc.OnVisualizationComplete -= OnVisualizationCompleted;
|
||||
npc.OnMovementComplete -= OnMovementCompleted;
|
||||
}
|
||||
|
||||
// Unsubscribe from UI events
|
||||
@ -228,6 +254,14 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
gridSizeXInput.text = gridMap.NumX.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
|
||||
algorithmDropdown.ClearOptions();
|
||||
algorithmDropdown.AddOptions(new System.Collections.Generic.List<string> {
|
||||
@ -270,6 +304,20 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
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()
|
||||
{
|
||||
timeEstimateText.text = "0";
|
||||
@ -312,8 +360,42 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
if (int.TryParse(gridSizeXInput.text, out int newSizeX) &&
|
||||
int.TryParse(gridSizeYInput.text, out int newSizeY))
|
||||
{
|
||||
gridMap.ResizeGrid(newSizeX, newSizeY);
|
||||
ClearPerformanceMetrics();
|
||||
// Validate grid size limits
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
UnityEngine.SceneManagement.SceneManager.LoadScene(
|
||||
UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
|
||||
@ -352,10 +450,34 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
private void OnAlgorithmChanged(int index)
|
||||
{
|
||||
NPC.PathFinderType newType = (NPC.PathFinderType)index;
|
||||
string algorithmName = GetAlgorithmName(newType);
|
||||
|
||||
Debug.Log($"Algorithm changed - Index: {index}, Type: {newType}, Name: {algorithmName}");
|
||||
|
||||
npc.ChangeAlgorithm(newType);
|
||||
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()
|
||||
{
|
||||
if (string.IsNullOrEmpty(mapNameInput.text))
|
||||
@ -426,24 +548,45 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
int sizeY = 20;
|
||||
bool isLargeGrid = false;
|
||||
|
||||
const int MAX_GRID_SIZE = 200;
|
||||
const int MIN_GRID_SIZE = 2;
|
||||
|
||||
switch (mazeSizeDropdown.value)
|
||||
{
|
||||
case 0: // Kecil
|
||||
sizeX = sizeY = 20;
|
||||
break;
|
||||
case 1: // Sedang
|
||||
sizeX = sizeY = 50;
|
||||
sizeX = sizeY = 35;
|
||||
break;
|
||||
case 2: // Besar
|
||||
sizeX = sizeY = 100;
|
||||
sizeX = sizeY = 50;
|
||||
isLargeGrid = true;
|
||||
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
|
||||
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
|
||||
gridSizeXInput.text = sizeX.ToString();
|
||||
@ -586,4 +729,196 @@ public class PathfindingUIManager : MonoBehaviour
|
||||
// Reset performance metrics
|
||||
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