Spawning AI enemies using object pool and Photon

FunkyYosh
FunkyYosh
edited March 2023 in Any Topic & Chat

Hi there, I'm making a 3D unity multiplayer game and I'm currently trying to implement the AI with multiplayer. I got the AI to work in a seperate test scene using object pooling, but now I have to implement this AI into my actual game scene with the multiplayer but I'm unsure how to do this.

I have a photonview component on the gameobject that uses the below script, I've tried using photonView.RPC but I then get the error that I "can't use custom types" like the Enemy or enemyObjectPools variables.


This is my current EnemySpawner script:

public class EnemySpawner : MonoBehaviourPunCallbacks
{
  public int numberOfEnemies = 4;
  public float spawnDelay = 1f;
  public List<Enemy> enemyPrefabs = new List<Enemy>();
  public SpawnMethod enemySpawnMethod = SpawnMethod.RoundRobin;

  private Dictionary<int, ObjectPool> enemyObjectPools = new Dictionary<int, ObjectPool>();

  private PhotonView photonView;

  private void Start()
  {
    photonView = gameObject.GetComponent<PhotonView>(); 
    for (int i = 0; i < enemyPrefabs.Count; i++)
    {
      enemyObjectPools.Add(i, ObjectPool.CreateInstance(enemyPrefabs[i], numberOfEnemies));
    }
      StartCoroutine(SpawnEnemies());
  }

  private IEnumerator SpawnEnemies()
  {
    WaitForSeconds wait = new WaitForSeconds(spawnDelay);

    int spawnedEnemies = 0;

    while(spawnedEnemies < numberOfEnemies)
    {
      if(enemySpawnMethod == SpawnMethod.RoundRobin)
      {
        SpawnRoundRobinEnemy(spawnedEnemies);
      }
      else if(enemySpawnMethod == SpawnMethod.Random)
      {
        SpawnRandomEnemy();
      }

      spawnedEnemies++;

      yield return wait;
    }
  }

  private void SpawnRoundRobinEnemy(int spawnedEnemies)
  {
    int spawnIndex = spawnedEnemies % enemyPrefabs.Count; // 0 % 4 = 0, 1 % 4 = 1, 2 % 4 = 2, ... 4 % 4 = 0

    DoSpawnEnemy(spawnIndex);
  }

  private void SpawnRandomEnemy()
  {
    DoSpawnEnemy(Random.Range(0, enemyPrefabs.Count));
  }

  private void DoSpawnEnemy(int spawnIndex)
  {
    PoolableObject poolableObject = enemyObjectPools[spawnIndex].GetObject();

    if(poolableObject != null)
    {  
      Enemy enemy = poolableObject.GetComponent<Enemy>();

      NavMeshTriangulation triangulation = NavMesh.CalculateTriangulation();

      enemy.agent.Warp(new Vector3(0, 0, 10)); // set spawn location
      enemy.movement.triangulation = triangulation;
      enemy.agent.enabled = true;
      enemy.movement.Spawn();
    } else
    {
      Debug.LogError($"Unable to fetch enemy of type {spawnIndex} from object pool. Out of objects?");
    }
  }

  public enum SpawnMethod
  {
    RoundRobin, // cycle through each enemy one at a time
    Random
  }
}

I would be very grateful for any help on how to get started, if I need to provide more scripts or context I'd be happy doing so.

Answers

  • The error "can't use custom types" like the Enemy or enemyObjectPools variables is due to those not being serializable for Photon. You need to write code that sends instances of those types via the network (as a byte[]).

    When we fixed the doc pages for this topic, check out the info about Custom Types.