- Home /
Automatically create enum based on class children types? (C#)
I would like to create an enum based on a base class's children.
For instance, I have a bunch of weapon classes that all extend from a single weapon base class. I have a script which acts as a pickup for weapons and/or ammo, based on inspector settings. I would like to automatically create an enum that specifies which weapon that the pickup will modify so it would be easy for the level designer in our group to place what pickups he wants in the level, just by changing the enum in the inspector.
I would like the enum to be generated automatically, so that new weapons can be created without needing to worry about adding or removing from the enum manually.
Note that I do NOT need this to be modified at runtime.
Here's an example of my class structure: (I tried to format it in an easy to visualize way)
abstract GunBase : Monobehaviour
abstract GunRay : GunBase - public Pistol : GunRay (This should be in the enum) - public Rifle : GunRay (This should be in the enum) - public Shotgun : GunRay (This should be in the enum)
abstract GunPrefab : GunBase - public RPG : GunPrefab (This should be in the enum)
Answer by Kiwasi · Nov 19, 2014 at 09:19 PM
This can't be done using a real enum as you have described it. However you can do some trickery to achieve the end effect you want.
You will need to do the following. Someone more experienced may be able to provide code.
Use reflection to get all of the classes in your assembly
Iterate through the list to find all classes that inherit from your GunBase
Add the classes to a list or dictionary
Create a custom inspector to display the collection. Format it to look like an enum
Take action based on the user selection
I'd be interested to see what code you come up with. I'm pretty sure most of the details can be found on google for the steps I've described.
You'll also need to consider error proofing. What happens to already defined pickups if a class is removed or renamed during development.
Yeah, if you want the list automatically generated, Reflection is probably the only way. Here's a link to an SO question about getting subclasses: http://stackoverflow.com/questions/8928464/for-an-object-can-i-get-all-its-subclasses-using-reflection-or-other-ways
Hmm... after some research into reflections, I have found that I have already put "Finished" weapon scripts into their own assembly namespace. This means I can simply do something like this:
using System;
using System.Reflection
namespace WeaponSystem.Weapons //abstract classes are in 'WeaponSystem'
{
class Example
{
// Get assembly.
Assembly assembly = Assembly.GetCallingAssembly();
// Get array of types.
Type[] types = assembly.GetTypes();
}
}
And that will knock out the first three steps. (Since all the classes in that namespace already extend from GunBase.)
I'm not that experienced with creating editors, however I think I could have the script search for new weapon classes when 'EditorApplication.isCompiling' changes from 'true' to 'false'.
Adding new weapon types to my fake enum should be easy, however as you pointed out, it is more difficult to remove those weapons when a script is already referencing it.
I have a few ideas of how this last part could be done*, however they are complicated and a system like this is a bit overkill. I think I will just add or remove from an enum manually. Thanks for your help, Bored$$anonymous$$ormon.
*($$anonymous$$eep an array of scripts that use the enum value, and then if we don't have the selected weapon anymore, set to some default value and notify the user via Console?)
Your answer
Follow this Question
Related Questions
Accessible collection of Type 1 Answer
PropertyDrawer: Enum to select extended class 0 Answers
C# Edit enum values in inspector 1 Answer
Can I add an enum value in the inspector? 4 Answers
Distribute terrain in zones 3 Answers