如何在没有usind索引的情况下选择/调用数组中的Instantiated GameObject

我目前正在为游戏地图开发一个随机网格生成库,我有点陷入如何根据游戏坐标(而不是Vector3)调用实例化对象。

这是我的十六代脚本:

public HexCell cellPrefab; HexCell[] cells; void CreateCell (int x, int z, int i) { Vector3 position; position.x = (x + z * 0.5f - z / 2) * (HexMetrics.innerRadius * 2f); position.y = 0f; position.z = z * (HexMetrics.outerRadius * 1.5f); HexCell cell = cells[i] = Instantiate(cellPrefab); cell.coordinates = HexCoordinates.FromOffsetCoordinates(x, z); } 

我可以使用对象数组的索引来调用对象,但我无法根据给定的坐标调整它的想法。

这就是我根据每个hex位置给出它们的坐标;

 public class HexCell : MonoBehaviour { public HexCoordinates coordinates; } public struct HexCoordinates { [SerializeField] private int x, z; public int X { get { return x; } } public int Y { get { return -X - Z; } } public int Z { get { return z; } } public HexCoordinates (int x, int z) { this.x = x; this.z = z; } public static HexCoordinates FromOffsetCoordinates (int x, int z) { return new HexCoordinates(x - z / 2, z); } } 

那么如何根据HexCell坐标调用/选择所需的hex?

那么如何根据HexCell坐标调用/选择所需的hex?

这很容易做到,因为您使用int而不是float来表示坐标。 只需循环遍历cells数组。 在每个循环中,从HexCell组件访问coordinates变量,然后比较x, y和z值。 如果匹配,则返回循环中的当前HexCell 。 如果没有,只需返回null 。 您也可以使用linq执行此操作,但请避免使用它。

你的单元格数组:

 HexCell[] cells; 

从坐标获取HexCell

 HexCell getHexCellFromCoordinate(int x, int y, int z) { //Loop thorugh each HexCell for (int i = 0; i < cells.Length; i++) { HexCoordinates hc = cells[i].coordinates; //Check if coordinate matches then return it if ((hc.X == x) && (hc.Y == y) && (hc.Z == z)) { return cells[i]; } } //No match. Return null return null; } 

由于坐标是int而不是float ,您还可以使用Vector3Int (需要Unity 2017.2及更高版本)来表示它们而不是x,y和z。 请注意,这与Vector3不同。

 HexCell getHexCellFromCoordinate(Vector3Int coord) { //Loop thorugh each HexCell for (int i = 0; i < cells.Length; i++) { HexCoordinates hc = cells[i].coordinates; //Check if coordinate matches then return it if ((hc.X == coord.x) && (hc.Y == coord.y) && (hc.Z == coord.z)) { return cells[i]; } } //No match. Return null return null; } 

或者,您可以使用一些内置函数使其更具可读性。

 HexCell getHexCellFromCoordinate(int x, int y, int z) { return cells.FirstOrDefault( cell => cell.x == x && cell.y == y && cell.z == z ); } HexCell getHexCellFromCoordinate(Vector3Int coord) { return cells.FirstOrDefault(cell => cell.x == coord.x && cell.y == coord.y && cell.z == coord.z ); } 

值得注意的是,因为我不确定你需要在哪里找到单元格,所以FirstOrDefault进行堆分配,因此在太大的列表中经常调用它(每帧数万次,并且/或者针对数以万计的对象)它可能导致不希望的垃圾收集,这可能会导致应用程序出现断断续续的情况,并且如果与其他使用堆分配的代码结合起来,那么这种口吃可能会很明显。

因此,作为一般规则,从简单的事情开始。 如果您的应用程序开始变慢或占用太多内存,请返回并使用最热门(性能最差)代码进行优化。 您可以使用分析器来帮助您找到这些位置。 但是,请不要为了循环而谜语代码只是为了节省一些额外的cpu周期。