Need help with automatically creating Subclass instance

I have been trying to make a modular class system for my game using System.Reflection. However using CreateInstance is throwing “Object is not set to an instance of an object” and i really cant pinpoint why… Here is the basic rundown of what i am trying todo:

void Start()
{
    Assembly assembly = Assembly.GetAssembly(GetType()); //Using GetType() to find our loaded assembly

    foreach (Type type in assembly.GetTypes())
    {
        if (type.IsSubclassOf(assembly.GetType("Haystan.EnemyType.Base")))
        {
            EnemyTypes.Add(type.Name, (EnemyType.Base)assembly.CreateInstance(type.FullName)); //EnemyTypes is a dictionary
        }
    }
}

I wonder what that would be good for? What are you trying to do? Could you elaborate on that?
There’s almost always a way without reflection to achieve something similar (or even the same). You often lose type safety and performance and run the risk to have unexpected behaviour!
Last but not least, don’t overcomplicate things.

Reflection is something that should be used carefully and only if you really know what you do, e.g. if you need to access the meta data and so on.

Anyway, back to topic:

Note: This shouldn’t be used with MonoBehaviours or ScriptableObjects as they are meant to be created with AddComponent
2 ways that would work, there may be others, too.

  1. If you wanna find it via string (really error-prone, you should take every possible misbehaviour into account):
Type baseType = assembly.GetType("Haystan.EnemyType").GetNestedType("Base");
  1. If you definitely know the class
Type baseType = assembly.GetType((typeof(Haystan.EnemyType.Base)).FullName);

A small but complete example, given the following test hierarchy

namespace Haystan
{
    public class EnemyType
    {
        public class Base
        {
            public Base()
            {
                Debug.Log("Constructor of Haystan.EnemyType.Base");
            }
        }
    }

    public class SubClass : EnemyType.Base
    {
        public SubClass() : base()
        {
            Debug.Log("Constructor of Haystan.SubClass");
        }
    }
}

you can use the following code to achieve what you want:

using UnityEngine;
using System;
using System.Reflection;
using System.Collections.Generic;

using Haystan;

public class ReflectionCreateInstance_System64 : MonoBehaviour
{
    private Dictionary<string, EnemyType.Base> EnemyTypes = new Dictionary<string, EnemyType.Base>();

    void Start()
    {
        Assembly assembly = Assembly.GetAssembly(GetType());

        // find the type once before the loop
        Type baseType = assembly.GetType((typeof(EnemyType.Base)).FullName);

        foreach (Type type in assembly.GetTypes())
        {
            if (type.IsSubclassOf(baseType))
            {
                Debug.Log("Type found: " + type.Name);
                EnemyTypes.Add(type.Name, (EnemyType.Base)assembly.CreateInstance(type.FullName)); //EnemyTypes is a dictionary
            }
        }
    }
}

Thanks, got any games of you i can check out?

I think what you’re looking for in your case is Activator.CreateInstance. But, if you can avoid using Reflection to create instances you probably should. Read up on Factory patterns instead. If you knew the types ahead of time you could use generics and constraints, but since you don’t, the below example should give you a much easier way using a simple factory that returns your type instance. As long as your types all have parameterless constructor, you could do this:

public static class EnemyFactory
{
    public static EnemyType.Base CreateInstance(Type instanceType)
    {
        if(!typeof(EnemyType.Base).IsAssignableFrom(instanceType))
              throw new ArgumentException("instanceType must inherit EnemyType.Base", "instanceType");

        return Activator.CreateInstance(instanceType) as EnemyType;
    }

}
1 Like

Nope. I haven’t done any games by myself so far. I mainly work on a personal project which includes my own networking system from scratch, targeting massive amounts of synchronizations (consider a MMORPG). Still just a fun project to see how far I can push that.
Even though it’s probably one of the toughest area of game programming that I’ve encountered so far (tbh I haven’t tried a complex AI yet :stuck_out_tongue: ) it’s certainly one of the most interesting as there are so many things to learn, for instance all the ways to reduce bandwidth.