从数组中选择没有重复的随机位置

Selecting random positions from array without duplicates

在我的游戏中,有很多敌人并且上面有这个脚本,我通过从位置数组中随机选择一个元素来设置他们的导航网格目的地。然而,有时所有的敌人都在同一个位置,所以我试图跳过以前生成的数组索引并找到一个新的索引。对此有什么建议吗?我不想使用 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;
    }
}

您可以尝试的一件事是保留可用职位的动态列表,而不是数组。 (别担心 - 它们在 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);
}

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

您尚未确定什么条件可以使某个职位再次可用,但如果确定了,您可以调用 RegisterFiringPosition() 将其重新添加到列表中。作为一个很好的副作用,这也使得为敌人分配全新的位置成为可能,例如响应玩家触发的事件。

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