• 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 /
avatar image
0
Question by Ian Smithers · Jan 03, 2013 at 05:25 AM · guiuieditorassets

How do you get a list of project scripts at edit-time?

I have a custom class called MyCustomClass.

I would like to provide a UI selector in the editor so that the user can choose from one of their own classes that derives from MyCustomClass.

Either something similar to an ObjectField (which doesn't work for this purpose) where a user can open up a selector that lists all the objects you specify, or, a dropdown menu that lists all the objects you specify.

Then when the user selects one, I can set a backing variable to the user's choice, and store it on another class for later use at runtime.

My question is, how do I obtain a list of classes from within an editor script, both a CustomInspector, and an EditorWindow?

EditorGUILayout.ObjectField doesn't seem to work. I get an "InvalidCastException" error, yet when I print the member I feed that function, and the returned result, both print as being of type MyCustomClass. So I think that is an editor bug. I also tried Object.FindObjectsOfTypeIncludingAssets however I see some strange behaviour with this, as follows:

 // Returns all meshes.
 Mesh[] meshes = (Mesh[])Object.FindObjectsOfTypeIncludingAssets( typeof( Mesh ) );

 // Returns all shaders, including built in shaders.
 Shaders[] shaders = (Shader[])Object.FindObjectsOfTypeIncludingAssets( typeof( Shader ) );
     
 // Returns every single asset.
 MyCustomClass[] myClasses = (MyCustomClass[])Object.FindObjectsOfTypeIncludingAssets( typeof( MyCustomClass) );

Any information and help appreciated, perhaps there is a solution I have not considered, and am approaching this the wrong way.

Comment
Add comment
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

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Ian Smithers · Jan 03, 2013 at 10:20 AM

Hello, I managed to find a solution as follows - hope this helps if anyone has a similar task:

     public static MonoScript[] GetScriptAssetsOfType<T>()
     {
         MonoScript[] scripts = (MonoScript[])Object.FindObjectsOfTypeIncludingAssets( typeof( MonoScript ) );
         
         List<MonoScript> result = new List<MonoScript>();
         
         foreach( MonoScript m in scripts )
         {
             if( m.GetClass() != null && m.GetClass().IsSubclassOf( typeof( T ) ) )
             {
                 result.Add( m );
             }
         }
         return result.ToArray();
     }
Comment
Add comment · Show 3 · Share
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 Shinzironine · Apr 01, 2014 at 10:39 AM 0
Share

Unity crashes when I iterate over array "scripts". I'm calling your method OnGui in editor script. Do you know why this could happen?

avatar image Shinzironine · Apr 02, 2014 at 05:38 AM 0
Share

The problem was in the fact that the script is also finding Shaders, so you need an additional check. s.GetType() != typeof(Shader)

avatar image Djayp · Dec 12, 2020 at 01:51 PM 0
Share

If you don't need editor scripts :

             public static $$anonymous$$onoScript Find$$anonymous$$onoScriptFromType(Type type)
                 => Array.Find($$anonymous$$onoImporter.GetAllRuntime$$anonymous$$onoScripts(), 
                     (m) => m.GetClass() != null && m.GetClass().IsSubclassOf(type));
     
             public static $$anonymous$$onoScript[] Find$$anonymous$$onoScriptsFromType(Type type)
                 => Array.FindAll($$anonymous$$onoImporter.GetAllRuntime$$anonymous$$onoScripts(),
                     (m) => m.GetClass() != null && m.GetClass().IsSubclassOf(type));
avatar image
0

Answer by CodeMasterMike · Jan 03, 2013 at 06:30 AM

When I retrieve all methods from a single script, I use reflection to get a list of all methods:

 Assembly []referencedAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
 for(int i = 0; i < referencedAssemblies.Length; ++i)
 {
     System.Type type = referencedAssemblies[i].GetType( scriptNameString );
     
     if( type != null )
     {    // I want all the declared methods from the specific class.
         System.Reflection.MethodInfo []methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
     }
 }

Maybe you can use some similar way to get out all classes from a single script.

Good luck!

Comment
Add comment · Show 3 · Share
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 Ian Smithers · Jan 03, 2013 at 06:36 AM 0
Share

Thanks for the post, I realized my question title could have been misleading so I edited it. For clarification, I need to get a list of all the scripts in the project, that match a certain type, at edit-time. So lets say I have 100 scripts, and 25 of them all derive from $$anonymous$$yCustomClass, I want to let the user choose one of these from a custom editor UI. Currently I can only get Unity assets (such as $$anonymous$$eshes or Shaders) or all assets, as in my code snippet. Hopefully that clears it up, thanks again, cheers!

avatar image CodeMasterMike · Jan 03, 2013 at 06:41 AM 0
Share

Ah, okey that makes it a little clearer.

You can get all scripts (which are monobehavior type scripts) by this function:

 Component []objectCompoentList = currentGameObject.GetComponents(typeof($$anonymous$$onoBehaviour));

$$anonymous$$aybe you can sort out those who aren't derived from the $$anonymous$$yCustomClass somehow.

avatar image Ian Smithers · Jan 03, 2013 at 06:45 AM 0
Share

That will get scripts from a selected GameObject, but I am attempting to get the scripts in the project, the actual raw script assets themselves, similar to how they appear in the project view - except I wish to filter them and then display a filtered list of them in the custom editor.

avatar image
0

Answer by glitchers · Jul 15, 2016 at 09:54 AM

Unity has made Object. FindObjectsOfTypeIncludingAssets obsolete and recommends you use Resources. FindObjectsOfTypeAll but this will not find all assets.

I have written a small piece of code that you can use in Editor only that takes a generic type and will return all objects in your project regardless of if they have been loaded yet.

 public static List<T> FindAssetsByType<T>() where T : UnityEngine.Object
 {
     List<T> assets = new List<T>();

     string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(T)));

     for( int i = 0; i < guids.Length; i++ )
     {
         string assetPath = AssetDatabase.GUIDToAssetPath( guids[i] );
         T asset = AssetDatabase.LoadAssetAtPath<T>( assetPath );

         if( asset != null )
         {
             assets.Add(asset);
         }
     }
     return assets;
 }

Comment
Add comment · Share
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

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

12 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

Related Questions

How to instantiate multiple sprites without creating animation? 1 Answer

Is there a way to live-update script-controlled UI formatting in the editor? 1 Answer

UI Button and Color Tint Transition issue 0 Answers

GUI Editior Script not working in ( Unity 2019.x ) 0 Answers

ShaderGraph-like EditorWindow 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges