首页 > 解决方案 > 避免随机选择同一点来模仿“类人”行为

问题描述

我有一个类在舞台上随机创建一些对象,这些对象出现在两个随机点。问题是Random.Range有连续多次选择一个点的概率,即我选择相同的点5或6次。我只是想以某种方式限制自己,如果Random.Range最多选择3次相同的点,它将选择另一个点。

public ObjectSequence ObstacleSequence;
public float WaitSpawnTime;
public float DistanceFromObstacleIndex;
public Transform[] spawnPoints;
private List<int> Point = new List<int>();

void Start()
{
    InvokeRepeating("Spawn", WaitSpawnTime, DistanceFromObstacleIndex);
}

void Spawn()
{
    int spawnPointIndex;
    do
    {
        spawnPointIndex = Random.Range(0, spawnPoints.Length);
        Point.Add(spawnPointIndex);
    } while (SwitchPoint());
    if (SwitchPoint())
        Point.Clear();
    ObjectSequence obstacle = Instantiate(ObstacleSequence,
       spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
    obstacle.setRandomCurrentChildIndex();
    obstacle.CurrentChild.GetComponent<SpriteRenderer>().flipY = 
       (obstacle.transform.position == spawnPoints[1].position) ? true : false;
}

private bool SwitchPoint()
{
    if (Point.Count >= 2)
    {
        return Point[0].Equals(Point[1]) && Point[1].Equals(Point[2]);
    }
    return false;
}

我只有两点,所以“洗牌”方法(如Randomize a List<T>或许多其他“独特随机”帖子)不起作用。

标签: c#unity3drandom

解决方案


总的想法,不管有多少人认为它效率低下,都是简单地丢弃值,直到你得到一个好的,我保证这对于少数选择比任何基于洗牌整个列表的解决方案更有效。无论如何,要解决您的问题,您需要存储最后 3 个生成的数字,如果它们都相同,您可以简单地选择另一个生成点,如下所示:

if (generated[0] == generated[1] && generated[0] == generated[2])
    return 1 - generated[0]; // flip 0 to 1 and 1 to 0
else
    return Random.Range(0, 2);

但是,如果你有超过 2 个数字,你会这样做(仍然基于重试,并且仍然比洗牌更有效):

if (generated[0] == generated[1] && generated[0] == generated[2])
{
    int newNumber;
    do
        newNumber = Random.Range(0, maximum);
    while (newNumber == generated[0]);
}
else
    return Random.Range(0, maximum);

推荐阅读