Есть ли лучший способ рандомизировать, какого врага появиться? - PullRequest
0 голосов
/ 13 мая 2019

Я сейчас создаю игру, в которой я хочу породить множество разных врагов. В настоящее время у меня есть много контейнеров данных для модулей, которые я создаю с помощью ScriptableObjects. Эти юниты содержат разные виды данных, такие как HP, добыча, урон и т. Д. Я думал о добавлении другого типа данных, который будет их индивидуальным% к порождению или что-то подобное, но я немного застрял, не зная, как реализовать что-то вроде того.

Вот мой текущий код, в котором я порождаю врагов, полностью рандомизированных из двух разных списков врагов ближнего и дальнего боя.

IEnumerator SpawnEnemies()
    {
        //Spawn enemies while amount of enemies are under predetermined enemy amount.
        while (spawnedEnemies < totalEnemiesInCurrentWave)
        {
            //Randomize if Melee or Ranged enemy.
            whichEnemyType = Random.Range(0, 2);
            GameObject enemy = waves[currentWave].enemyPrefab[whichEnemyType];

            spawnedEnemies++;
            enemiesInWaveLeft++;

            //Can I get a probability % to spawn each enemy? Currently completely random.
            switch (whichEnemyType)
            {
                case 0:
                    GameObject Melee = Instantiate(enemy, spawnPoint.position, Quaternion.identity);
                    Melee.GetComponent<Melee>().unit = meleeUnits[Random.Range(0, meleeUnits.Count)];
                    break;
                case 1:
                    GameObject Ranged = Instantiate(enemy, spawnPoint.position, Quaternion.identity);
                    Ranged.GetComponent<Ranged>().unit = rangedUnits[Random.Range(0, rangedUnits.Count)];
                    break;
                default:
                    break;
            }
            yield return new WaitForSeconds(timeBetweenEnemies);
        }
        yield return null;

    }

Может ли кто-нибудь указать мне лучший способ справиться со случайными врагами или, если возможно, дать мне какую-то идею, как это сделать.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Этот код не учитывает ваш отдельный список юнитов дальнего боя и ближнего боя, но вы можете использовать его, чтобы назначить вес каждому объекту Scriptable противника, и тогда враги, которые появляются, будут основываться на весах всехтвои враги.Я рекомендую иметь только один список врагов, а не отдельные списки для врагов ближнего и дальнего боя.

В этом коде предполагается, что ваш объект сценариев называется Enemy, и вы добавляете в него поле weight.Если вы хотите, чтобы ваши веса были специфическими для каждой волны (вместо каждого типа врага), то переместите поле weight на префаб противника вместо его объекта ScriptableObject.

IEnumerator SpawnEnemies()
{
    int totalWeight = 0;   
    foreach (var enemy in waves[currentWave].enemyPrefab)
    {
       totalWeight += enemy.GetComponent<Enemy>().weight;
    }

    // Spawn enemies while amount of enemies are under predetermined enemy amount.
    while (spawnedEnemies < totalEnemiesInCurrentWave)
    {
        spawnedEnemies++;
        enemiesInWaveLeft++;  // I think you should be decrementing instead of incrementing?

        // Determine which enemy to spawn, based on all enemy weights
        var enemy = GetEnemyToSpawn(totalWeight);
        var spawnedEnemy = Instantiate(enemy, spawnPoint.position, Quaternion.identity);

        // Here you'll have to handle adding the enemy to the appropriate
        // "enemies" list

        yield return new WaitForSeconds(timeBetweenEnemies);
    }
    yield return null;
}

// Suppose:
//    enemy A: weight 2
//    enemy B: weight 6
//    enemy C: weight 3
// Then
//    enemy A: 2/11 chance of spawning
//    enemy B: 6/11 chance of spawning
//    enemy C: 3/11 chance of spawning   
private GameObject GetEnemyToSpawn(int totalWeight)
{
    int weight = Random.Range(1, totalWeight);

    foreach (var enemy in waves[currentWave].enemyPrefab)
    {
        if (weight <= enemy.GetComponent<Enemy>().weight)
        {
            return enemy;
        }
        weight -= enemy.GetComponent<Enemy>().weight;
    }
}
0 голосов
/ 13 мая 2019

Вместо использования Random.Range((int)0, (int)2), который возвращает только 0 или 1. Используйте Random.Range(0f, 1f) вместо того, чтобы получить число от 0 до 1:

IEnumerator SpawnEnemies()
{
    const float MeleeSpawnRatio = 0.8f; // assuming a 8:2 ratio between melee/ranged

    //Spawn enemies while amount of enemies are under predetermined enemy amount.
    while (spawnedEnemies < totalEnemiesInCurrentWave)
    {           
        //Randomize if Melee or Ranged enemy.
        whichEnemyType = Random.Range(0f, 1f) >= MeleeSpawnRatio ? 0 : 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...