如何查找网格实例化位置?解决GetRandomRoadPoint返回null问题
程序化城镇行人AI系统Grid问题排查
我正在搭建一个用于程序化生成城镇的行人AI系统,初始采用Pack Publishing提供的Grid系统进行开发,以下是该系统的初始化代码:
public class Point { public int X { get; set; } public int Y { get; set; } public Point(int x, int y) { this.X = x; this.Y = y; } public override bool Equals(object obj) { if (obj == null) { return false; } if (obj is Point) { Point p = obj as Point; return this.X == p.X && this.Y == p.Y; } return false; } public override int GetHashCode() { unchecked { int hash = 6949; hash = hash * 7907 + X.GetHashCode(); hash = hash * 7907 + Y.GetHashCode(); return hash; } } public override string ToString() { return "P(" + this.X + ", " + this.Y + ")"; } } public enum CellType { Empty, Road, Structure, SpecialStructure, None } public class Grid { private CellType[,] _grid; private int _width; public int Width { get { return _width; } } private int _height; public int Height { get { return _height; } } private List<Point> _roadList = new List<Point>(); private List<Point> _specialStructure = new List<Point>(); private List<Point> _houseStructure = new List<Point>(); public Grid(int width, int height) { _width = width; _height = height; _grid = new CellType[width, height]; } // 代码存在重复定义问题:重复声明了CellType和Grid类 public enum CellType { Empty, Road, Structure, SpecialStructure, None } public class Grid { private CellType[,] _grid; private int _width; public int Width { get { return _width; } } private int _height; public int Height { get { return _height; } } private List<Point> _roadList = new List<Point>(); private List<Point> _specialStructure = new List<Point>(); private List<Point> _houseStructure = new List<Point>(); public Grid(int width, int height) { _width = width; _height = height; _grid = new CellType[width, height]; } public void Update() { Console.Write("GRID IS RUNNING"); } // 索引器:通过grid[i,j]访问单元格 public CellType this[int i, int j] { get { return _grid[i, j]; } set { if (value == CellType.Road) { _roadList.Add(new Point(i, j)); } if (value == CellType.SpecialStructure) { _specialStructure.Add(new Point(i, j)); } if (value == CellType.Structure) { _houseStructure.Add(new Point(i, j)); } _grid[i, j] = value; } } // 获取随机道路点方法 public Point GetRandomRoadPoint() { if (_roadList.Count == 0) { return null; } return _roadList[UnityEngine.Random.Range(0, _roadList.Count)]; } }
初始化后调用网格的代码:
public int width, height; Grid placementGrid; private void Start() { placementGrid = new Grid(width, height); Debug.Log(placementGrid.GetRandomRoadPoint()); }
问题分析与解决方案
1. GetRandomRoadPoint返回null的直接原因
_roadList为空列表,说明没有任何道路类型的单元格被添加到网格中:
- 检查
width和height变量:如果未赋值,默认值为0,会创建一个宽高为0的空网格,无法添加任何单元格。 - 当前
Start方法仅初始化网格,未通过索引器placementGrid[i,j] = CellType.Road添加道路单元格,自然_roadList无数据。
2. 代码语法错误修复
提供的初始化代码存在重复定义类的问题:删除重复的CellType枚举和Grid类声明,保留包含索引器、Update方法及GetRandomRoadPoint方法的完整版本。
3. 查找网格实例化位置的方法
- 如果Grid是MonoBehaviour子类:在Unity Hierarchy窗口搜索Grid组件,或用
FindObjectsOfType<Grid>()在代码中获取所有实例。 - 如果是普通C#类:在Grid构造函数中添加日志追踪调用位置:
public Grid(int width, int height) { _width = width; _height = height; _grid = new CellType[width, height]; // 输出调用构造函数的方法信息 Debug.Log($"Grid实例化于:{new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().Name}"); }
修复后的示例调用代码
public int width = 10, height = 10; // 给宽高赋值 Grid placementGrid; private void Start() { placementGrid = new Grid(width, height); // 添加一行道路单元格 for (int i = 0; i < width; i++) { placementGrid[i, 5] = CellType.Road; } Point randomRoad = placementGrid.GetRandomRoadPoint(); Debug.Log(randomRoad?.ToString() ?? "无可用道路点"); }
内容的提问来源于stack exchange,提问作者VChuckShunA
相关产品推荐
相关产品推荐

