Object.Instantiate throwing InvalidCastException when trying to instantiate object stored in scriptable object

Hello everyone!

I have a problem with pooling system that I’m doing. Short version of the problem is, when I try to instantiate object that I receive from scriptable object with Object.Instantiate, I get an InvalidCastException from it.

Here is the code that throws the error on line 17:

public class ObjectPool<T> where T : PooledObject
{
    private int _amountToPool = 20;
    private T _objectToPool;

    private readonly List<T> _pool = new();
    private Transform _parentTransform = null;

    public ObjectPool(T initialObjectToPool, Transform parentTransform)
    {
        _parentTransform = parentTransform;
        _pool.Clear();
        _objectToPool = initialObjectToPool;

        for (int i = 0; i < _amountToPool; i++)
        {
            var obj = Object.Instantiate(_objectToPool, _parentTransform);
            obj.gameObject.SetActive(false);
            _pool.Add(obj);
        }
    }

    public T GetPooledObject()
    {
        var pooledObject = _pool.Where(x => !x.gameObject.activeSelf).FirstOrDefault();
        
        if (pooledObject != null)
        {
            return pooledObject;
        }
        else
        {
            var obj = Object.Instantiate(_objectToPool, _parentTransform);
            obj.gameObject.SetActive(false);
            _pool.Add(obj);

            Debug.LogWarning($"Pool {_parentTransform.name} exceeded limit! New amount pooled: {_pool.Count}");
            return obj;
        }
    }
}

PooledObject is just an empty MonoBehaviour class for now that is inherited by each entity that i want to pool (Projectiles, enemies, …). Inheritance for enemies follows like this: EnemyName → Enemy → PooledObject → MonoBehaviour

Object pool is created by Enemy pool script, that has reference to _enemyData as scriptable object:

public class EnemyPool : MonoBehaviour
{
    [SerializeField] 
    private Transform _playerTransform;
    [SerializeField]
    private EnemyData _enemyData;

    private EnemyType _currentEnemy = EnemyType.None;
    private ObjectPool<Enemy> _enemyPool;

    public void InitializeEnemyPool(EnemyType initialEnemy)
    {
        _currentEnemy = initialEnemy;

        Enemy objectToPool = _enemyData.GetEnemyInfo(initialEnemy);
        _enemyPool = new(objectToPool, transform);
    }
}

EnemyData class looks like this:

using System;
using System.Linq;
using UnityEngine;

public enum EnemyType
{
    None = 0,
    Goblin = 1,
    Wolf = 2
}

[Serializable]
public class EnemyDataEntry
{
    public EnemyType Type;
    public Enemy Object;
}

[CreateAssetMenu]
public class EnemyData : ScriptableObject
{
    [SerializeField]
    private EnemyDataEntry[] _enemyPrefabs;

    public Enemy GetEnemyInfo(EnemyType enemy)
    {
        var entry = _enemyPrefabs.Where(x => x.Type == enemy).FirstOrDefault();

        if (entry == null)
            Debug.LogError($"Enemy you are trying to get does not exist {enemy}");

        return entry.Object;
    }
}

Here is also a screenshot of an actual error that i get:

Funny enough, if I reference prefab of an enemy (ie. Goblin) in EnemyPool directly via SerializeField and try to make pool out of it, it works like a charm, so the problem occurs only when i try to instantiate prefabs that i receive from scriptable object.

Thank you all in advance for your answers :smiley:

Sounds like a simple skill issue