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

时间:2018-03-15 02:14:23

标签: c# unity3d

我目前正在为游戏地图开发一个随机网格生成库,我有点陷入如何根据游戏坐标(而不是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<HexCell>(cellPrefab);
    cell.coordinates = HexCoordinates.FromOffsetCoordinates(x, z);
}

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

这就是我根据每个十六进制位置给出坐标的方法;

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坐标调用/选择所需的十六进制?

2 个答案:

答案 0 :(得分:2)

  

那么如何根据HexCell坐标调用/选择所需的十六进制?

这很容易做到,因为您使用int代替float来表示坐标。只需遍历cells数组。在每个循环中,访问coordinates组件中的HexCell变量,然后比较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而不是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;
}

答案 1 :(得分:0)

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

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周期而使用for循环来代码。

相关问题