C#Animal Spawner Logic - 需要建议

时间:2016-04-30 20:39:57

标签: c# unity3d logic unity5

我在游戏中有分散在地形上的动物的产卵者。这个想法是让动物只在玩家处于产卵者范围内时才会产卵,但如果动物在距离产卵者近的范围内有太多动物则不会产卵。这就是我到目前为止所做的,但现在我有点卡住了。任何人都可以给我一些指导:

  • 产生的赔率是否正确计算?设置两只动物,例如10%和90%的生成机会实际上使动物A有10%的机会产卵,而动物B有90%的机会或者我的数学错误?
  • 我的半径计算是否正确?
  • 最重要的是:我可以改进吗?

代码:

[System.Serializable]
public class SpawnableAnimal
{
public string AnimalName;
public float spawnWeight;

public float spawnPercentage;
}

public class AnimalSpawner : MonoBehaviour {

public float maxSpawnRadius = 1000.0f;
public float noSpawnRadius = 700.0f;

public GameObject spawnedAnimal;

public SpawnableAnimal[] spawnableAnimals;

void Start () {
    System.Random rand = new System.Random();
    int randInt = rand.Next(0, 100);

    float startTime = randInt / 100f;
    float repeatTime = randInt / 100f;
    InvokeRepeating("ReadyToSpawn", startTime, (60.0f + repeatTime));
}

void ReadyToSpawn()
{
    Debug.Log("Ready to spawn");
    bool canSpawn = true;

    GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
    GameObject[] animals = GameObject.FindGameObjectsWithTag("Animal");
    for(int i = 0; i < players.Length; i++)
    {
        if (Vector3.Distance(this.transform.position, players[i].transform.position) > maxSpawnRadius)
            canSpawn = false;

        if (Vector3.Distance(this.transform.position, players[i].transform.position) < noSpawnRadius)
            canSpawn = false;
    }

    if (players.Length < 1)
        canSpawn = false;

    if (spawnedAnimal != null)
        canSpawn = false;

    if (canSpawn)
        SpawnAnimal();
}

void SpawnAnimal()
{
    System.Random rand = new System.Random();
    double x = rand.NextDouble();

    var totalWeight = spawnableAnimals.Select(a => a.spawnWeight).Sum();

    for(int i = 0; i < spawnableAnimals.Length; i++)
    {
        float spawnPercentage = spawnableAnimals[i].spawnWeight / totalWeight;

        if(x < spawnPercentage)
        {
            InstantiateAnimal(i);
            return;
        }

        x -= spawnPercentage;
    }
}

void InstantiateAnimal(int animalToSpawn)
{
    if (animalToSpawn != -1)
        spawnedAnimal = GameObject.Find("AnimalManager").GetComponent<AnimalManager>().SpawnAnimal(spawnableAnimals[animalToSpawn].AnimalName, this.transform.position, this.transform.rotation);
    else Debug.Log("No animal to spawn!");
}

}

2 个答案:

答案 0 :(得分:1)

Vector3.Distance(this.transform.position, players[i].transform.position)

这些位置是否在同一空间? Vector3.Distance(x, y)|x - y|的意思吗?如果是这样,那么计算对我来说很好。

SpawnAnimal似乎很奇怪。我不确定它在做什么。如果你能解释一下你背后的想法,那么我可能会理解它。

我会为每只动物分配一个重量。这个数字是任意的,但它们的相对大小很重要。如果猫的体重为100,而狗的体重为1000,则狗的产卵可能性比猫高10倍。

除此之外:为什么称重而不是百分比?如果你定义猫有10%的产卵机会和狗产生90%的产卵几率然后你添加沙鼠,那么分配沙鼠的比例是多少?百分比必须加1,因此您必须调整所有其他动物的百分比以腾出空间。如果我们使用重量,猫为100,狗为1000,那么我们可以添加重量为500的沙鼠,我们知道沙鼠的产卵量是猫的5倍,狗的频率是狗的一半 - 无需调整。

让我们假设您在x中生成一个随机数[0,1)(这可以通过NextDouble()来完成。)

我们希望在[0,1)中为每只动物分配一个与其体重成正比的间隔。首先找出总重量。

var totalWeight = spawnableAnimals.Select(a => a.Weight).Sum();

由此我们可以为每只动物指定一个百分比a.Weight / totalWeight。这些百分比加1,因此您可以在[0,1)区间内分配这些百分比。 Pi是从AiA0 <= i < n的索引动物n中产生动物|A|的概率(即数字{}动物)。

0.0    0.1    0.2    0.3 …    1.0
 [  P1  )[     P2     )[ …  Pn )

现在你只需要确定哪个区间x就在哪里,那就是要产卵的动物。这是一个程序算法。

  1. 初始化A = the set of animalsi = 0x = NextDouble()n = |A|
  2. 如果i < n
    • 然后:如果x < Pi
      • 然后:停止并产生Ai
      • 否则:
        1. Pi
        2. 中减去x
        3. 增量i
        4. 转到(2)。
    • 其他:停止没有动物产卵。
  3. ith间隔(0 <= i < n),其中汇总由0 <= j < i编制索引:

    1. ΣP(j-1) <= x < ΣP(j-1) + Pi(参见示例表)
    2. ΣP(j-1) - ΣP(j-1) <= x - ΣP(j-1) < ΣP(j-1) + Pi - ΣP(j-1)(减去ΣP(j-1)
    3. 0 <= x - ΣP(j-1) < Pi(简化)

      • x - ΣP(j-1)是通过累积减法实现的。
      • 0 <= x0 <= NextDouble() < 1x >= Pi然后x - Pi >= 0(循环不变量)实现。
      • 因此,我们只需要测试x < Pi
    4. 注意:这取决于具有均匀分布的随机数生成器。

答案 1 :(得分:0)

你在这里进行整数除法:

float startTime = randInt / 100

我认为你想要的是:

float startTime = randInt / 100f

你正在获得产卵机会&#34;逆转&#34; :

if(randInt <= spawnableAnimals[i].spawnChance

应该是:

if(randInt >= spawnableAnimals[i].spawnChance

然而,这并没有完全解决所有问题,因为:

arraySum += randInt;

的做法如下:

break;

因此,如果spawnableAnimals中的第一个元素的spawnChance为10%,而spawnableAnimals中的第二个元素的spawnChance为90%,那么第一个元素的分布为10%,90%* 90 %= 81%,因为第二个元素仅在第一个元素失败时才会尝试。