如何将Foreach循环结果作为自身参数?Unity网格十字标记需求
Unity网格十字线标记问题解决方案
你遇到的报错核心是foreach遍历集合时不允许修改原集合,直接在循环里给neighbourCells添加元素会触发集合修改异常,以下是两种实用解决思路:
方法一:用队列实现广度优先搜索(贴合你的迭代扩展逻辑)
用队列存储待检查的单元格,避免遍历过程中修改原集合,同时加入去重逻辑防止重复处理:
public void MarkStraightTiles(Cell cell) { // 初始化队列,先加入原点的所有相邻单元格 Queue<Cell> checkQueue = new Queue<Cell>(); foreach(var neighbour in Origin.GetNeighbours(allCells)) { checkQueue.Enqueue(neighbour); } // 存储最终的十字线单元格,避免重复添加 HashSet<Cell> crossCells = new HashSet<Cell>(); while(checkQueue.Count > 0) { Cell current = checkQueue.Dequeue(); // 检查是否和原点同X或Y轴 if(current.OffsetCoord.x == Origin.OffsetCoord.x || current.OffsetCoord.y == Origin.OffsetCoord.y) { crossCells.Add(current); // 获取当前单元格的相邻单元格,加入队列继续检查 foreach(var nextNeighbour in current.GetNeighbours(allCells)) { if(!crossCells.Contains(nextNeighbour) && !checkQueue.Contains(nextNeighbour)) { checkQueue.Enqueue(nextNeighbour); } } } } // 把结果赋值给原变量使用 neighbourCells = crossCells.ToList(); }
方法二:直接遍历筛选(更高效的方案)
既然需求是标记所有与原点同X/Y轴的单元格,完全不需要迭代找邻居,直接遍历全量网格筛选即可:
public void MarkStraightTiles(Cell cell) { int originX = Origin.OffsetCoord.x; int originY = Origin.OffsetCoord.y; // 直接筛选符合条件的单元格,不需要包含原点可加 && c != Origin neighbourCells = allCells.Where(c => c.OffsetCoord.x == originX || c.OffsetCoord.y == originY).ToList(); }
适用场景说明
- 方法一适合带障碍的网格场景(比如十字线遇到障碍需要停止扩展);
- 方法二更简洁高效,适用于无遮挡的完整十字线需求。
内容的提问来源于stack exchange,提问作者Wigglepuff
相关产品推荐
相关产品推荐

