Home > Back-end >  OnDrawGizmos not drawing all Grid positions in generated Grid
OnDrawGizmos not drawing all Grid positions in generated Grid

Time:02-25

I have a Grid I am generating to perform path finding. When storing all the walkable Nodes I perform a check if the Obstacles HashSet has an obstacle placed there. I am passing a Node to the IsCellOccupied(Node node) function but I think .Contains is failing to recognise the passed in Node.

Pastebin enter image description here

Removing the IEquatable inheritance and it's method produces the full Grid. However, the whole Grid is now being generated even under the obstacles, where it should be empty

enter image description here

I can't seem to figure out where it's going wrong. I think it has to do with the .Contains check performed by the IsCellOccupied function but I am not sure what I am missing.

Node

public class Node : IEquatable<Node>
{ 
    public Vector3 Position { get; set; }
    public CellType CellType { get; set; }
    public int Cost { get; set; }
    public Node parentNode {get; set;}

public Node(Vector3 position, CellType cellType, int cost)
{
    Position = position;
    CellType = cellType;
    Cost = cost;
}

public override int GetHashCode()
{
    return Position.GetHashCode();
}

public bool Equals(Node other)
{
    if (ReferenceEquals(null, other))
    {
        return false;
    }

    if (ReferenceEquals(this, other))
    {
        return true;
    }

    return GetHashCode() == other.GetHashCode();
}

public override bool Equals(object obj)
{
    if((obj == null) || ! this.GetType().Equals(obj.GetType()))
    {
        return false;
    } 
    else
    {
        Node n = (Node)obj;
        return Position == n.Position;
    }
}
}

IsCellOccupied Function

private bool IsCellOccupied(Node node)
{
    if (Obstacles.Contains(node))
        return true;

    return false;
}

CodePudding user response:

try instantiating the obstacles in your grid way and the object that will be instantiated is modified as an obstacle instead of making the whole thing through scripts

CodePudding user response:

The issue can be found in the PlaceObject function of Grid.cs

var cellPosition = new Node(new Vector3(positionX, 0, positionZ), CellType.Land, 1); 
...

var objectPosition = cellPosition; // <- objectPosition references the same object!

objectPosition.Position = new Vector3(
    objectPosition.Position.x, 
    ObstaclePrefab.transform.position.y, // <- you are altering the y component here
    objectPosition.Position.z
);

This does make sense, until you get to your GetHashCode() implementation.

return Position.GetHashCode();

The y component of your vector is not zero anymore, it is based on your obstacle. So now if you try to compare a new node with y=0, there will be no match (unless obstacle y component is zero).

if (!IsCellOccupied(new Node(new Vector3(x, 0, z), CellType.Land, 1)))

We can test this in unity with a couple of Debugs.

var v1 = new Vector3(3, 0, 3);
var v2 = new Vector3(3, 1, 3);

Debug.Log($"V1) {v1.GetHashCode()}");
Debug.Log($"V2) {v2.GetHashCode()}");

// Outputs:
// V1) 1347420160
// V2) -1370488832

The Solution

Ignore the y component of Position in your GetHashCode() function.

public override int GetHashCode()
{
    return new Vector3(Position.x, 0, Position.y).GetHashCode();
}
  • Related