2
\$\begingroup\$

I'm trying to remove the Reflection part of one of my scripts so it works in WebGL, however I am having some trouble.

Basically I need a way to store references to classes in an Inspector array so that I can then use AddComponent() to add them to an object I spawn.

The code I'm using uses arrays to hold different types of AI modules and then chooses a random set of modules and add them to an base enemy prefab. Previously I was using Reflection to create the array and add the modules but that doesn't seem to work in WebGL. Currently the modules are Monobehaviours but it is possible for me to make them normal classes.

\$\endgroup\$
2
  • \$\begingroup\$ Does the AddComponent(type componentType) method use reflection internally? Or are we able to use it as long as we can get a list of types to use at runtime? If so, I may have a way to do that. \$\endgroup\$
    – DMGregory
    Commented Sep 26, 2019 at 13:31
  • \$\begingroup\$ Is there any particular reason you cannot just add the scripts directly instead of using an array? My guess is that you use the array to find all behaviours in a system automatically instead of hard coding them. Personally I would manually create a few different collections of them so I can change AI behaviors per level (for example if one level has a brewery you could use special drunk behaviours). \$\endgroup\$ Commented Oct 21, 2020 at 1:57

1 Answer 1

0
\$\begingroup\$

My best guess as to how to do this would be to use the MonoScript type to expose a list of script references in the Inspector. This type is in the UnityEditor namespace, so we need to smuggle the type information out of those objects to use at runtime:

[SerializeField]
System.Type[] _types;

#if UNITY_EDITOR
public UnityEditor.MonoScript[] _scripts;

private void OnValidate() {
    _types = new System.Type[_scripts.Length];

    for (int i = 0; i < _scripts.Length; i++)
        if(_scripts[i] != null)
            _types[i] = _scripts[i].GetClass();
}
#endif


public void AddComponentByIndex(GameObject host, int index) {
    host.AddComponent(_types[index]);
}

If serializing System.Type references, or the System.Type overload of AddComponent isn't working for you, we could instead store the names of the component types to use the string overload.

If neither works, then we might need to do something more drastic, like mapping our component types to enum values and using a switch statement to jump to the appropriate hard-coded AddComponent<Foo>();

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .