简体   繁体   中英

How can I specify the contents of a multidimensional array and select objects matching the criteria from a list?

Premise

We are creating a tower defense type game. So we want to build a Wave system and be able to set the number of Wave times each enemy will spring up according to their respective types.

  • Select the type of enemy to be generated from EnemyFactor
  • Select the number of enemies to be generated from EnemyAmount

在此处输入图像描述

What you want to achieve

  • Select enemy type from list and game object

Applicable source code

    public class WaveListFactor : MonoBehaviour
    {
        public List<EnemyEnum> enemyFactor = new List<EnemyEnum>();

        public List<int> enemyAmount = new List<int>();
    }
    public class WaveList : MonoBehaviour
    {
        public List<GameObject> enemyList = new List<GameObject>();

        public List<WaveListFactor> waveEnemies = new List<WaveListFactor>();
    }
    public class WaveManager : MonoBehaviour
    {
        public void EnemySpawn()
        {
            int enemyFactor = waveList.waveEnemies.waveEnemyFactor;
            GameObject enemy = waveList.enemyList[enemyFactor];
            waveSpawner.Spawn(enemy);
        }
    }

Problems

int enemyFactor = waveList.waveEnemies.waveEnemyFactor;

Now I can't change EnemyEnum in EnemyFactor to int and can't specify the contents of enemyList .

Supplementary information (FW / tool version, etc.)

  • Unity 2020.3.20f

I would recommend you rather use a SerializedDictionary<EnemyEnum, GameObject[]> and simply configure beforehand which enum value results in which GameObject prefab options (so you can still randomize a bit)

public SerializedDictionary<EnemyEnum, GameObject[]> enemyList = new SerializedDictionary<EnemyEnum, GameObject[]>();

and then later select one doing

var options = enemyList[enemyFactor];

and then select a random one like eg

var selectedPrefab = options[Random.Range(0, options.Length)];

Otherwise you would need some dedicated component on your enemies that provides the information about which EnemyEnum it responds to like eg

public class Enemy : MonoBehaviour
{
    public EnymeEnum Type;
}

and rather have

public List<Enemy> enemyList = new List<Enemy>();

then you could filter your available options using Linq

using System.Linq;

...

var options = enemyList.Where(enemy => enemy.Type == enemyFactor).ToArray();

and pick a random one from the existing matches like

var selectedPrefab = options[Random.Range(0, options.Length)];

if this results in null it simply means there is no matching prefab.

Disadvantage : Each prefab can only belong to one single enum category. That's not the case for the other two solutions.


Or even simplier: Why store the information in separate collections at all?

Simply rather have a

[Seriaizable]
public class EnemyInfo
{
    public GameObject Prefab;
    public int Amount;
}

[Seriaizable]
public class WaveInfo
{
    public EnemyInfo[] EnemyInfos;
}

this way you don't have to care about any enum but rather simply define how many instances of which prefab will be spawned.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM