Pathfinding Implementation

Polish
DJh2o2 2023-05-24 09:36:12 +07:00
parent fd86b03a4c
commit db4a35a83b
1236 changed files with 86067 additions and 80636 deletions

File diff suppressed because it is too large Load Diff

@ -577,8 +577,8 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
gridText: {fileID: 6019877198273519714}
gCostText: {fileID: 766478950501946128}
hCostText: {fileID: 7608016431660212678}
gCostText: {fileID: 7608016431660212678}
hCostText: {fileID: 766478950501946128}
fCostText: {fileID: 2698401074965240056}
--- !u!1 &7855068981580310195
GameObject:

@ -787,7 +787,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2527f37f5a49dc8b1bb1708df4129bb6, type: 3}
m_Name:
m_EditorClassIdentifier:
unit: {fileID: 0}
unit: {fileID: 2554385331328250168}
--- !u!1001 &4317887677737669656
PrefabInstance:
m_ObjectHideFlags: 0

@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.17838746, g: 0.22335976, b: 0.30537635, a: 1}
m_IndirectSpecularColor: {r: 0.17838746, g: 0.2233598, b: 0.30537635, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
@ -421,7 +421,7 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 330585543}
m_LocalRotation: {x: 0.3006394, y: 0.000000016410377, z: -0.000000005172915, w: 0.9537379}
m_LocalRotation: {x: 0.3006394, y: -0.000000016410377, z: 0.000000005172915, w: 0.9537379}
m_LocalPosition: {x: 3.01, y: 7, z: -6.75}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@ -822,7 +822,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!114 &506381887
MonoBehaviour:
m_ObjectHideFlags: 0
@ -988,7 +988,7 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 598754947}
m_LocalRotation: {x: 0.3006394, y: 0.000000016410377, z: -0.000000005172915, w: 0.9537379}
m_LocalRotation: {x: 0.3006394, y: -0.000000016410377, z: 0.000000005172915, w: 0.9537379}
m_LocalPosition: {x: 3.01, y: 7, z: -6.75}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 1
@ -1696,7 +1696,7 @@ Transform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 6
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &885582184
GameObject:
@ -2516,7 +2516,7 @@ PrefabInstance:
- target: {fileID: 2266715941421909531, guid: adae4f13d5306d4518212283c7892fd0,
type: 3}
propertyPath: m_RootOrder
value: 5
value: 6
objectReference: {fileID: 0}
- target: {fileID: 2266715941421909531, guid: adae4f13d5306d4518212283c7892fd0,
type: 3}

@ -1,5 +1,76 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-6751563108509869087
MonoBehaviour:
m_ObjectHideFlags: 3
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c01700fd266d6914ababb731e09af2eb, type: 3}
m_Name: DepthOfField
m_EditorClassIdentifier:
active: 1
mode:
m_OverrideState: 1
m_Value: 1
gaussianStart:
m_OverrideState: 1
m_Value: 20
gaussianEnd:
m_OverrideState: 1
m_Value: 100
gaussianMaxRadius:
m_OverrideState: 1
m_Value: 0.5
highQualitySampling:
m_OverrideState: 1
m_Value: 1
focusDistance:
m_OverrideState: 0
m_Value: 10
aperture:
m_OverrideState: 0
m_Value: 5.6
focalLength:
m_OverrideState: 0
m_Value: 50
bladeCount:
m_OverrideState: 0
m_Value: 5
bladeCurvature:
m_OverrideState: 0
m_Value: 1
bladeRotation:
m_OverrideState: 0
m_Value: 0
--- !u!114 &-5780637882506665317
MonoBehaviour:
m_ObjectHideFlags: 3
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ccf1aba9553839d41ae37dd52e9ebcce, type: 3}
m_Name: MotionBlur
m_EditorClassIdentifier:
active: 1
mode:
m_OverrideState: 1
m_Value: 1
quality:
m_OverrideState: 1
m_Value: 2
intensity:
m_OverrideState: 1
m_Value: 0.5
clamp:
m_OverrideState: 1
m_Value: 0.1
--- !u!114 &-4945800967145002492
MonoBehaviour:
m_ObjectHideFlags: 3
@ -18,7 +89,7 @@ MonoBehaviour:
m_Value: 0
contrast:
m_OverrideState: 1
m_Value: 37
m_Value: 40
colorFilter:
m_OverrideState: 0
m_Value: {r: 1, g: 1, b: 1, a: 1}
@ -27,7 +98,7 @@ MonoBehaviour:
m_Value: 74
saturation:
m_OverrideState: 1
m_Value: 46
m_Value: 50
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
@ -45,6 +116,8 @@ MonoBehaviour:
- {fileID: -4945800967145002492}
- {fileID: 4110088290242408507}
- {fileID: 1739641996749212652}
- {fileID: -6751563108509869087}
- {fileID: -5780637882506665317}
--- !u!114 &1739641996749212652
MonoBehaviour:
m_ObjectHideFlags: 3
@ -66,10 +139,10 @@ MonoBehaviour:
m_Value: {x: 0.5, y: 0.5}
intensity:
m_OverrideState: 1
m_Value: 0.4
m_Value: 0.45
smoothness:
m_OverrideState: 1
m_Value: 0.2
m_Value: 0.25
rounded:
m_OverrideState: 1
m_Value: 0
@ -88,7 +161,7 @@ MonoBehaviour:
active: 1
mode:
m_OverrideState: 1
m_Value: 1
m_Value: 2
neutralHDRRangeReductionMode:
m_OverrideState: 0
m_Value: 2
@ -131,10 +204,10 @@ MonoBehaviour:
m_Value: 1
threshold:
m_OverrideState: 1
m_Value: 1
m_Value: 0.9
intensity:
m_OverrideState: 1
m_Value: 1
m_Value: 1.1
scatter:
m_OverrideState: 0
m_Value: 0.7

@ -1,11 +1,12 @@
using Grid;
public class PathNode {
private GridPosition GridPosition { get; }
public int GCost { get; private set; }
public int HCost { get; private set; }
public int FCost { get; private set; }
private PathNode cameFromPathNode;
public GridPosition GridPosition { get; }
public int GCost { get; set; }
public int HCost { get; set; }
public int FCost => GCost + HCost;
public PathNode CameFromPathNode { get; set; }
public PathNode(GridPosition gridPosition) => GridPosition = gridPosition;

@ -1,15 +1,119 @@
using System.Collections.Generic;
using System.Linq;
using Grid;
using UnityEngine;
public class Pathfinding : MonoBehaviour {
[SerializeField] private Transform gridDebugObjectPrefab;
private int width;
private int height;
private float cellSize;
private GridSystem<PathNode> gridSystem;
private void Awake() {
gridSystem = new(10, 10, 2f, (_, gridPosition) => new(gridPosition));
gridSystem.CreateDebugObjects(gridDebugObjectPrefab);
}
}
public static Pathfinding Instance { get; private set; }
private const int moveStraightCost = 10;
private const int moveDiagonalCost = 14;
[SerializeField] private Transform gridDebugObjectPrefab;
private float cellSize;
private GridSystem<PathNode> gridSystem;
private int height;
private int width;
private void Awake() {
if (Instance is not null) {
Debug.LogError($"There is more than one Pathfinding! {transform} - {Instance}");
Destroy(gameObject);
return;
}
Instance = this;
gridSystem = new(10, 10, 2f, (_, gridPosition) => new(gridPosition));
gridSystem.CreateDebugObjects(gridDebugObjectPrefab);
}
public List<GridPosition> FindPath(GridPosition startGridPosition, GridPosition endGridPosition) {
List<PathNode> openList = new();
List<PathNode> closedList = new();
PathNode startNode = gridSystem.GetGridObject(startGridPosition);
PathNode endNode = gridSystem.GetGridObject(endGridPosition);
openList.Add(startNode);
for (int x = 0; x < gridSystem.Width; x++) {
for (int z = 0; z < gridSystem.Height; z++) {
PathNode pathNode = gridSystem.GetGridObject(new(x, z));
pathNode.GCost = int.MaxValue;
pathNode.HCost = 0;
pathNode.CameFromPathNode = null;
}
}
startNode.GCost = 0;
startNode.HCost = CalculateDistance(startGridPosition, endGridPosition);
while (openList.Count > 0) {
PathNode currentNode = GetLowestFCostPathNode(openList);
if (currentNode == endNode) return CalculatePath(endNode); // Reached final node
openList.Remove(currentNode);
closedList.Add(currentNode); //currentNode is tested
foreach (PathNode neighbourNode in GetNeighbourList(currentNode)) {
if (closedList.Contains(neighbourNode)) continue;
int tentativeGCost = currentNode.GCost + CalculateDistance(currentNode.GridPosition, neighbourNode.GridPosition);
if (tentativeGCost < neighbourNode.GCost) {
neighbourNode.CameFromPathNode = currentNode;
neighbourNode.GCost = tentativeGCost;
neighbourNode.HCost = CalculateDistance(neighbourNode.GridPosition, endGridPosition);
if (!openList.Contains(neighbourNode)) openList.Add(neighbourNode);
}
}
}
return null; //no path found
}
private int CalculateDistance(GridPosition gridPositionA, GridPosition gridPositionB) {
GridPosition gridPositionDistance = gridPositionA - gridPositionB;
int xDistance = Mathf.Abs(gridPositionDistance.X);
int zDistance = Mathf.Abs(gridPositionDistance.Z);
int remaining = Mathf.Abs(xDistance - zDistance);
return moveDiagonalCost * Mathf.Min(xDistance, zDistance) + moveStraightCost * remaining;
}
private PathNode GetLowestFCostPathNode(IReadOnlyList<PathNode> pathNodeList) {
PathNode lowestFCostPathNode = pathNodeList[0];
foreach (PathNode currentPathNode in pathNodeList.Where(t => t.FCost < lowestFCostPathNode.FCost)) lowestFCostPathNode = currentPathNode;
return lowestFCostPathNode;
}
private List<PathNode> GetNeighbourList(PathNode currentNode) {
List<PathNode> neighbourList = new();
GridPosition gridPosition = currentNode.GridPosition;
if (gridPosition.X - 1 >= 0) {
neighbourList.Add(GetNode(gridPosition.X - 1, gridPosition.Z + 0)); //Left
if (gridPosition.Z - 1 >= 0) neighbourList.Add(GetNode(gridPosition.X - 1, gridPosition.Z - 1)); //LeftDown
if (gridPosition.Z < gridSystem.Height) neighbourList.Add(GetNode(gridPosition.X - 1, gridPosition.Z + 1)); //LeftUp
}
if (gridPosition.X + 1 < gridSystem.Width) {
neighbourList.Add(GetNode(gridPosition.X + 1, gridPosition.Z + 0)); //Right
if (gridPosition.Z - 1 >= 0) neighbourList.Add(GetNode(gridPosition.X + 1, gridPosition.Z - 1)); //RightDown
if (gridPosition.Z + 1 < gridSystem.Height) neighbourList.Add(GetNode(gridPosition.X + 1, gridPosition.Z + 1)); //RightUp
}
if (gridPosition.Z - 1 >= 0) neighbourList.Add(GetNode(gridPosition.X - 0, gridPosition.Z - 1)); //Down
if (gridPosition.Z + 1 < gridSystem.Height) neighbourList.Add(GetNode(gridPosition.X - 0, gridPosition.Z + 1)); //Up
return neighbourList;
}
private PathNode GetNode(int x, int z) => gridSystem.GetGridObject(new(x, z));
private List<GridPosition> CalculatePath(PathNode endNode) {
List<PathNode> pathNodeList = new() { endNode };
PathNode currentNode = endNode;
while (currentNode.CameFromPathNode != null) {
pathNodeList.Add(currentNode.CameFromPathNode);
currentNode = currentNode.CameFromPathNode;
}
pathNodeList.Reverse();
return pathNodeList.Select(pathNode => pathNode.GridPosition).ToList();
}
}

@ -15,8 +15,8 @@ public class PathfindingGridDebugObject : GridDebugObject {
protected override void Update() {
base.Update();
gCostText.text = pathNode.GCost.ToString();
hCostText.text = pathNode.HCost.ToString();
fCostText.text = pathNode.FCost.ToString();
gCostText.text = $"G:{pathNode.GCost.ToString()}";
hCostText.text = $"H:{pathNode.HCost.ToString()}";
fCostText.text = $"F:{pathNode.FCost.ToString()}";
}
}

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Grid;
using UnityEngine;
using UnityEngine.Serialization;
@ -5,10 +6,19 @@ using UnityEngine.Serialization;
public class Testing : MonoBehaviour {
[FormerlySerializedAs("Unit")] [SerializeField] private Unit unit;
// private void Update() {
// if (Input.GetKeyDown(KeyCode.T)) {
// GridSystemVisual.Instance.HideAllGridPosition();
// GridSystemVisual.Instance.ShowGridPositionList(unit.MoveAction.GetValidActionGridPositionList());
// }
// }
private void Update() {
if (Input.GetKeyDown(KeyCode.T)) {
GridPosition mouseGridPosition = LevelGrid.Instance.GetGridPosition(MouseWorld.GetPosition());
GridPosition startGridPosition = new(0, 0);
List<GridPosition> gridPositionList = Pathfinding.Instance.FindPath(startGridPosition, mouseGridPosition);
for (int i = 0; i < gridPositionList.Count - 1; i++) {
Debug.DrawLine(
LevelGrid.Instance.GetWorldPosition(gridPositionList[i]),
LevelGrid.Instance.GetWorldPosition(gridPositionList[i + 1]),
Color.white,
10f
);
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More