Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Nov 20, 2013 at 08:38 PM by zombience for the following reason:

Question was refined and moved to new thread

avatar image
0
Question by zombience · Aug 20, 2013 at 09:38 PM · custom editorassembly

using System.Reflection in Custom Editor for flexible tool (somewhat long)

I'm attempting to create a custom editor that allows for multiple behaviors to be attached to an object in the editor.

The goal of the tool: I'd like to be able to create subclasses that derive from a base class that can be assigned into a custom script I've written.

The goal of the inspector: I'd like to be able to automatically detect available subclasses and offer them as selections to be added, without having to write new code each time a new subclass is written.

The code I've got so far: please note, this is my first foray both into System.Reflection and also Custom Editors, so please point out if I'm just barking up the wrong tree entirely, or flat out doing things wrong. Thanks in advance!

Editor Class:

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 
 [CustomEditor (typeof(Container))]
 public class ContainerEditor: Editor
 {
     private SerializedObject obj;
 
     public void OnEnable()
     {
         obj = new SerializedObject(target);
     }
 
     public override void OnInspectorGUI()
     {
         foreach (var item in SubclassFinder.FindDerivedTypes<ReturnBehavior>(null)) //this works if I only return the names of classes. if I can somehow return a reference or create a way to instantiate a class from here, that would be ideal
             GUILayout.Label(item.ToString(), EditorStyles.miniBoldLabel);
     }
 }

container class:

 public class Container : MonoBehaviour 
 {
 
 
     public FunBehaviors[] funBehaviors;
     
     void Start () 
     {
         
     }
     
     void Update () 
     {
     
     }
 }

base FunBehavior class:

             public class FunBehavior 
             {
                 public Container container;
                 public FunBehavior ()
                 {
                     //CONTAINER OF FUN
                 }
             }

   

 
 

child class #1

 public class SooperOssmFun: FunBehavior 
     {
     
         public SooperOssmFun(Container c)
         {
             //OMG ALL TEH FUNTIEMZ
                 container = c;
         }
     }

child class #2

 public class MegaOssmFun: FunBehavior 
         {
         
             public MegaOssmFun(Container c)
             {
                 //NO SRSLY LIEK WOAH FUNTIEMZ
                         container = c;
             }
         }


static class to return classes to be displayed in inspector and later added to the container script on Editor controls.

 using System;
 using System.Reflection;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 
 
  public static class SubclassFinder
     {
         public static IEnumerable<T> FindDerivedTypes<T>(params object[] args) where T: class
         {
             List<T> objects = new List<T>();
             foreach (Type type in Assembly.GetAssembly(typeof(T)).GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(T))))
             {
                 objects.Add(Activator.CreateInstance(type, args) as T);
             }
     
             return objects;
                                                   
         }
     }
 
Comment
Add comment · Show 17
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image frarees · Aug 20, 2013 at 09:50 PM 1
Share

I imagine you want to end up with something like a popup (actually a dropdown, but it's called popup here) where you see all your derived types, and once you select one of those a new instance of that type is created. You already have the types (via FindDerivedTypes), and as all of those are after all $$anonymous$$onoBehaviours (note that won't be the same if you're working for example with ScriptableObjects), depending on what you actually want to do you'll do something like new GameObject (myType); or alreadyExistingGameObject.AddComponent (myType);

avatar image Jamora · Aug 20, 2013 at 11:22 PM 1
Share

If you get the class names as strings, you should check out what the good folks at Stack Overflow have to say about it: c# instantiate class from string

avatar image Benproductions1 · Aug 21, 2013 at 04:22 AM 1
Share

If you want a list of all derrived classes as a list of references, here is a good link:
http://stackoverflow.com/questions/5045297/net-get-all-classes-derived-from-specific-class

avatar image yoyo · Aug 21, 2013 at 06:36 AM 3
Share

Ins$$anonymous$$d of calling the constructor when you find the types, I would just return a list of types. You can then get the constructor for the type and invoke it when the user selects that type to be added (e.g. presses a button, or chooses from a drop-down list). (And I suggest Type.GetConstructor ins$$anonymous$$d of using Activator.)

avatar image whydoidoit · Aug 21, 2013 at 06:38 AM 3
Share

I don't think you want to be instantiating inside that FindDerivedTypes right? That would be creating class instances every time the InspectorGUI was processed (I.e. frequently).

It looks to me like you should be returning an IEnumerable< Type> so you can create the instances later.

You can create instances if there are a constructor with parameters by using Type.GetConstructor and using Invoke on that... Use Linq to convert the parameter arrays to an array of types.

Show more comments

0 Replies

  • Sort: 

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

System.Reflection types and GetConstructor issues 1 Answer

Why does Boo not see namespaces from dlls? 1 Answer

Can't call custom Debug class (assembly issue?) 2 Answers

The type or namespace name `SingletonMonoBehaviour`1' could not be found 2 Answers

Is it legal to tamper in the Assembly file libunity.so? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges