OnDrawGizmos 未在生成的网格中绘制所有网格位置

OnDrawGizmos not drawing all Grid positions in generated Grid

我正在生成一个网格来执行路径查找。当存储所有可行走的节点时,我会检查 Obstacles HashSet 是否有障碍物放在那里。我正在将 Node 传递给 IsCellOccupied(Node node) 函数,但我认为 .Contains 无法识别传入的 Node.

Pastebin Grid.cs

节点 class 继承 IEquatable 但是使用此方法并实施 public bool Equals(Node other) 方法会产生奇怪的网格结果,其中可以找到许多空白点。只有放置红色障碍物的区域应该是空的而不是绿色的。

删除 IEquatable 继承及其方法生成完整的网格。但是现在整个Grid连障碍物下都在生成,本来应该是空的

我似乎无法弄清楚哪里出了问题。我认为这与 IsCellOccupied 函数执行的 .Contains 检查有关,但我不确定我遗漏了什么。

节点

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 函数

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

    return false;
}

实施建议的更改

建议将 y 设置为 0。这似乎仍然会在障碍物所在的位置放置一个绿色节点。

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

尝试以您的网格方式实例化障碍物,将实例化的对象修改为障碍物,而不是通过脚本制作整个事物

问题可以在 Grid.cs

的 PlaceObject 函数中找到
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
);

这确实有意义,直到您开始 GetHashCode() 实施。

return Position.GetHashCode();

向量的 y 分量不再为零,它基于您的障碍物。所以现在如果你尝试将一个新节点与 y=0 进行比较,将不会匹配(除非障碍物 y 分量为零)。

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

我们可以通过几个调试统一测试它。

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

解决方案

忽略 GetHashCode() 函数中 Position 的 y 分量。

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