Search Unity

How to cast Activator.CreateInstance to the child class?

Discussion in 'Scripting' started by RedVonix, Aug 20, 2014.

  1. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    422
    In my code, I am attempting to create a custom inspector editor which allows selecting a script which is not derived from a MonoBehavior. It looks like there is no standard way of doing this, therefore I've had to come up with another method. And while this method DOES work, it does not work for child classes.

    So in my code, I have the class VerbCard. Then each card type has its own logic script which is derived from VerbCard. In the inspector editor, the developer is able to specify certain properties for each individual card. The following code does get and properly store the script, but ONLY the VerbCard class - not the child class. I need it to store the child class.

    Code (csharp):
    1.  
    2. MonoScript thisScript = null;
    3. thisScript = EditorGUILayout.ObjectField(thisScript, typeof(MonoScript), null) as MonoScript;
    4.  
    5. if(thisScript != null)
    6.  {
    7.     VerbCard cardObj = Activator.CreateInstance(thisScript.GetClass()) as VerbCard;
    8.     thisEntry.cardScript = cardObj;
    9.     thisEntry.scriptSet = true;
    10.  }
    11.  
    Any help would be appreciated! Thank you!
     
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    VerbCard is deriving from MonoBehaviour? If so, it won't be saved properly if created outside the normal creation pipeline, such as gameObject.AddComponent.

    If it's not deriving from MonoBehaviour, it is also normal that it get reverted to the base type of the field holding it, as only MonoBehaviour and ScriptableObject can be properly polymorphic.

    If you are looking for a sub-component/composition pattern, check my signature for the Advanced Inspector.
     
  3. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    422
    It is not being derived from MonoBehavior. That makes sense and is what I thought was going on... Is there a way though that I could make it save as the child class and not VerbCard? Maybe as a generic or something?
     
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    No. Unity allows polymorphism to be properly be save only if the class derive from MonoBehaviour or ScriptableObject. Nothing else.
     
  5. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    422
    Allrighty then. So then I either need to derive from MonoBehavior or do this entirely a different way.

    Thank you for your assistance!
     
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    You got three choices;

    1) Use a different serialization. You can search for "Full Inspector", which is a asset package that offer alternative serialization.

    2) You can use a package that mimic the pattern of subcomponent/composition, such as this;


    3) You code your own setup that uses pieces of the two previous one.
     
  7. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    422
    Currently trying FullInspector2. Seems like an awesome solution, though it may not work as it requires BaseBehavior to be applied to the classes, however my classes are not derived from anything, and looking through things, I believe they have to stay that way. Emailed the FullInspector2 support though to see if they can point the way using their tech.
     
  8. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    422
    Got it! The developer of FullInspector2 helped get it working - the problem was that fiEditorSerializationManager.SetDirty(vcLib); needed to be added to the custom inspector editor. It works great now and does exactly what I need - thank you everyone for your help!