Spawning AI enemies using object pool and Photon

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

Spawning AI enemies using object pool and Photon

FunkyYosh
2023-03-22 13:57:56

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.

Comments

Tobias
2023-03-27 15:04:49

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.

Back to top