Maybe I missed something while watching the lecture but I have this problem of the path not recognizing other units on the map. The white line would simply move through it. Asking for advice on where I should start looking for the problem.
I’d like to make a update on this matter, first here are my codes:
<PathNode.cs>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PathNode//<1>
{
private GridPosition gridPosition;
private int gCost;//<4>
private int hCost;
private int fCost;
private PathNode cameFromPathNode;//<5>
public PathNode(GridPosition gridPosition) {//<2>
this.gridPosition = gridPosition;
}
public override string ToString()
{
return gridPosition.ToString();//<3>
}
public int GetGCost() {
return gCost;
}
public int GetHCost() {
return hCost;
}
public int GetFCost() {
return fCost;
}
public void SetGCost(int gCost) {//<6>
this.gCost = gCost;
}
public void SetHCost(int hCost) {
this.hCost = hCost;
}
public void CalculateFCost() {//<7>
fCost = gCost + hCost;
}
public void ResetCameFromPathNode() {//<8>
cameFromPathNode = null;
}
public void SetCameFromPathNode(PathNode pathNode) {//<10>
cameFromPathNode = pathNode;
}
public PathNode GetCameFromPathNode() {//<11>
return cameFromPathNode;
}
public GridPosition GetGridPosition() {//<9>
return gridPosition;
}
}
//===============================================
<Pathfinding.cs>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pathfinding : MonoBehaviour//<1>
{
public static Pathfinding Instance { get; private set;}//<34>
private const int MOVE_STRAIGHT_COST = 10;//<12>
private const int MOVE_DIAGONAL_COST = 14;
[SerializeField] private Transform gridDebugObjectPrefab;
private int width;
private int height;
private float cellSize;
private GridSystem<PathNode> gridSystem;//<3>
private void Awake() {
if(Instance != null) {//<34>
Debug.LogError("There's more than one Pathfinding! " + transform + " - " + Instance);
Destroy(gameObject);
return;
}
Instance = this;
gridSystem = new GridSystem<PathNode>(10, 10, 2f,
(GridSystem<PathNode> g, GridPosition gridPosition) => new PathNode(gridPosition));//<2>
gridSystem.CreateDebugObjects(gridDebugObjectPrefab);//<3>
}
public List<GridPosition> FindPath(GridPosition startGridPosition, GridPosition endGridPosition){//<4>
List<PathNode> openList = new List<PathNode>();//<5>
List<PathNode> closedList = new List<PathNode>();
PathNode startNode = gridSystem.GetGridObject(startGridPosition);//<6>
PathNode endNode = gridSystem.GetGridObject(endGridPosition);//<17>
openList.Add(startNode);
for(int x = 0; x < gridSystem.GetWidth(); x++) {//<7>
for(int z = 0; z < gridSystem.GetHeight(); z++) {
GridPosition gridPosition = new GridPosition(x, z);//<7>
PathNode pathNode = gridSystem.GetGridObject(gridPosition);
pathNode.SetGCost(int.MaxValue);//<8>
pathNode.SetHCost(0);
pathNode.CalculateFCost();
pathNode.ResetCameFromPathNode();//<9>
}
}
startNode.SetGCost(0);//<10>
startNode.SetHCost(CalculateDistance(startGridPosition, endGridPosition));//<11>
startNode.CalculateFCost();
while(openList.Count > 0) { //<14>
PathNode currentNode = GetLowestFCostPathNode(openList);//<15>
if(currentNode == endNode) {//<17>
//Reached the final node.
return CalculatePath(endNode);//<29>
}
openList.Remove(currentNode);
closedList.Add(currentNode);//<18>
foreach(PathNode neighbourNode in GetNeighbourList(currentNode)) {//<23>
if(closedList.Contains(neighbourNode)) {
continue;
}
int tentativeGCost =
currentNode.GetGCost() + CalculateDistance(currentNode.GetGridPosition(), neighbourNode.GetGridPosition());//<24>//<25>
if(tentativeGCost < neighbourNode.GetFCost()) {//<26>
neighbourNode.SetCameFromPathNode(currentNode);
neighbourNode.SetGCost(tentativeGCost);
neighbourNode.SetHCost(CalculateDistance(neighbourNode.GetGridPosition(), endGridPosition));
neighbourNode.CalculateFCost();
if(!openList.Contains(neighbourNode)) {//<27>
openList.Add(neighbourNode);
}
}
}
}
//No path found//<28>
return null;
}
public int CalculateDistance(GridPosition gridPositionA, GridPosition gridPositionB) {//<11>
GridPosition gridPositionDistance = gridPositionA - gridPositionB;
int xDistance = Mathf.Abs(gridPositionDistance.x);//<25>
int zDistance = Mathf.Abs(gridPositionDistance.z);
int remaining = Mathf.Abs(xDistance - zDistance);
return MOVE_DIAGONAL_COST * Mathf.Min(xDistance, zDistance) + MOVE_STRAIGHT_COST * remaining;//<13>
}
private PathNode GetLowestFCostPathNode(List<PathNode> pathNodeList) {//<16>
PathNode lowestFCostPathNode = pathNodeList[0];
for(int i = 0; i < pathNodeList.Count; i++) {
if(pathNodeList[i].GetFCost() < lowestFCostPathNode.GetFCost()) {
lowestFCostPathNode = pathNodeList[i];
}
}
return lowestFCostPathNode;
}
private PathNode GetNode(int x, int z) {//<21>
return gridSystem.GetGridObject(new GridPosition(x, z));
}
private List<PathNode> GetNeighbourList(PathNode currentNode) {//<19>
List<PathNode> neighbourList = new List<PathNode>();
GridPosition gridPosition = currentNode.GetGridPosition();//<20>
if(gridPosition.x - 1 >= 0) {//<22>
//Left
neighbourList.Add(GetNode(gridPosition.x - 1, gridPosition.z + 0));//<21>
if(gridPosition.z - 1 >= 0) {
//Left Down
neighbourList.Add(GetNode(gridPosition.x - 1, gridPosition.z - 1));
}
if(gridPosition.z + 1 < gridSystem.GetHeight()) {
//Left Up
neighbourList.Add(GetNode(gridPosition.x - 1, gridPosition.z + 1));
}
}
if(gridPosition.x + 1 < gridSystem.GetWidth()) {
//Right
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z + 0));
if(gridPosition.z - 1 >= 0) {
//Right Down
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z - 1));
}
if(gridPosition.z + 1 < gridSystem.GetHeight()) {
//Right Up
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z + 1));
}
}
if(gridPosition.z - 1 >= 0) {
//Down
neighbourList.Add(GetNode(gridPosition.x + 0, gridPosition.z - 1));
}
if(gridPosition.z + 1 < gridSystem.GetHeight()) {
//Up
neighbourList.Add(GetNode(gridPosition.x + 0, gridPosition.z + 1));
}
return neighbourList;
}
private List<GridPosition> CalculatePath(PathNode endNode) {//<29>
List<PathNode> pathNodeList = new List<PathNode>();
pathNodeList.Add(endNode);
PathNode currentNode = endNode;//<30>
while(currentNode.GetCameFromPathNode() != null) {
pathNodeList.Add(currentNode.GetCameFromPathNode());//<31>
currentNode = currentNode.GetCameFromPathNode();
}
pathNodeList.Reverse();//<32>
List<GridPosition> gridPositionList = new List<GridPosition>();//<33>
foreach(PathNode pathNode in pathNodeList) {
gridPositionList.Add(pathNode.GetGridPosition());
}
return gridPositionList;
}
}
//============================================
<Testing.cs>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Testing : MonoBehaviour
{
[SerializeField] private Unit unit;
private void Start() {
}
private void Update() {
//Debug.Log(gridSystem.GetGridPosition(MouseWorld.GetPosition()));//<1>
if(Input.GetKeyDown(KeyCode.T)) {
GridPosition mouseGridPosition = LevelGrid.Instance.GetGridPosition(MouseWorld.GetPosition());
GridPosition startGridPosition = new GridPosition(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
);
}
}
}
}
As for solving the problem, I first tried replacing all these codes with the ones in this lecture’s resource files and it has given me the same result.
The //<1>s are just my text pins I make for studying. As I keep my lecture notes somewhere else to avoid having too much text in the code.
I then tried replacing all the script codes from ‘C# Generics’ to this one and see if it made any difference. MoveAction.cs, Unit.cs and so on…(as for my original codes I stored them as text and compared them to the resource file codes.) I didn’t find much differences between them because they were basically made step by step from the lectures but if there is a script that anyone is wondering about I can upload them.
And finally if I recall from a previous lecture dealing with GridObject.cs, there was something quoted by CodeMonkey about units being able to move pass each other. As this problem is also happening with the enemy units as well I’m currently looking at this script and seeing if there was any mistakes I made.
I’m also considering of making a new conditional statement on either GridObject.cs or MoveAction.cs to make a workaround to move around the units, or at least, the enemies.
I think by logic it’s reasonable to be able to move pass ally units but not be able to against enemies.
Maybe this problem is addressed in the next lectures so as for now I’m gonna keep on going until I get new ideas to fix this.
All in all, I’m open to all advice and suggestions. Thank you
When we pathfind we get a list of neighbours for the current cell. We ignore cells that are not ‘walkable’. I don’t see this in your code so it may come in a later lesson, still. It’s here that you can also check if there are any units on that cell and also ignore those. That’s all you need to do.
Thank you for the reply, I’ve added notes to keep in mind on the code relating to the list of neighbours when working on determining walkable objects.
Embarrassing to say, it also turns out that this topic is actually dealt on in the next video. I knew something was missing but didn’t want to move on until I solved this problem.
But at least I got to review the whole project and better understand it.
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.