从数组中选择随机位置而不重复

时间:2016-10-17 12:23:34

标签: c# unity3d unity5

在我的游戏中,有很多敌人并且有这个脚本,我通过从一系列位置随机选择一个元素来设置他们的navmesh目的地。但是,有时所有敌人都在同一个位置,所以我试图跳过以前生成的数组索引并找到一个新索引。有什么建议吗?我不想使用goto声明。

这是我到目前为止所做的代码:

void move_on_fired_positions()
{
    navmesh.Resume ();
  again:
    new_position = Random.Range (0, firedpoints.Length);

    if (prev_num != new_position) {
        navmesh.SetDestination (firedpoints [new_position].position);
        prev_num = new_position;
    } else 
    {
        goto again;
    }
}

1 个答案:

答案 0 :(得分:2)

您可以尝试的一件事是保留可用位置的动态列表,而不是数组。 (别担心 - 它们在Unity编辑器界面中都以相同的方式进行序列化和修改。)这样,您可以从列表中删除分配给敌人的位置,确保您永远不会分配重复项。以下是对它的外观的看法:

public List<Transform> firedpoints;

// Returns available firing position, if any
public Transform GetRandomFiringPosition()
{
    if (firedpoints.Count > 0)
    {
        // Get reference to transform, then remove it from list
        int newPositionIndex = Random.Range (0, firedpoints.Length);
        Transform returnedPosition = firedpoints[newPositionIndex];
        firedpoints.RemoveAt(newPositionIndex);
        return returnedPosition;
    }
    else
    {
        // Or you can specify some default transform
        return null;
    }
}

// Makes firing position available for use
public void RegisterFiringPosition(Transform newPosition)
{
    firedpoints.Add(newPosition);
}

此代码应该在场景中的单个对象的脚本中,敌人应该引用它(或者,您可以稍微更改代码并使类成为单例,因此可以调用其方法没有直接参考)。每当敌人需要新职位时,它可以调用GetRandomFiringPosition()并将返回的Transform存储在变量中以供将来参考。

您尚未确定哪个条件可以再次使用该位置,但是当您拥有该位置时,您可以调用RegisterFiringPosition()将其恢复到列表中。作为一个很好的副作用,这也可以为敌人分配全新的位置,例如响应玩家触发的事件。

希望这有帮助!如果您有任何问题,请告诉我。