• 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
4
Question by ckfinite · Oct 16, 2010 at 02:22 AM · namespaceassembly

Editor assembly

I am working on a editor class that needs access to another of my classes that is in another namespace. However, this throws an error that the referenced class does not exist. In addition, when I used reflection to look through the assembly, I found none of the other classes I have made.

Do the editor classes get assembled in a different place than the rest of the scripts?

Comment
Add comment · Show 5
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 fireDude67 · Jun 21, 2011 at 04:46 AM 0
Share

Um, you shouldn't be using namespaces. Do you mean System.Reflection?

avatar image ckfinite · Jun 21, 2011 at 11:52 AM 0
Share

Well, this is an ancient problem that I don't need fixed. The reason I use namespaces for most of my more complicated stuff is I do a lot of work with the $$anonymous$$S CLR. It's fine as long as you don't see them from within Unity, just scripts.

The editor scripts are compiled into a different assembly than the runtime scripts, which answers my question.

avatar image kenlane22 · Apr 13, 2012 at 06:57 AM 0
Share

Interesting. I am working to find a list of $$anonymous$$onoBehavior's subclasses in an EditorWindow. This code seems to grab the Editor assembly (not surprising) rather than the player's assembly. In your code travels, did you ever come across a way to reference the assembly containing all the $$anonymous$$onoBehaviors? Here's my code in an EditorWindow that grabs from the wrong assembly right now.

 public class TypePickerEditorWindow : EditorWindow 
 {
     List<string> typeNames = new List<string>();
     List<Type>   typeTypes = new List<Type>();
     void Awake()
     {
         // List all C# class Types that are subclasses of $$anonymous$$onoBehavior
         Assembly asm = Assembly.GetExecutingAssembly(); // Wrong assembly!!
         foreach( Type type in asm.GetTypes() )
         {
             if ( type.IsSubclassOf( typeof($$anonymous$$onoBehaviour) ) )
             {
                 typeNames.Add( ""+ type );
                 typeTypes.Add( type );
             }
         }
     }
 
 }

  Any thoughts, guesses, advice?
avatar image ckfinite · Apr 13, 2012 at 10:36 AM 0
Share

The easiest way to get around this is to do Assembly.GetAssembly(SomeClassInRuntime.class);

avatar image meat5000 ♦ · Feb 09, 2015 at 01:22 PM 0
Share

Namespaces are now supported by Unity3D.

2 Replies

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

Answer by Bunny83 · Apr 13, 2012 at 12:18 PM

Unity compiles your scripts into several Assemblies. One first-pass, one "second pass" (normal) and one editor assembly for each language! That means in the worst case you have 9 assemblies (when you use all 3 languages, each one has scripts in the Asset folder, Standard Assets folder and editor folder).

This little script gives you all loaded assemblies:

 // C#
 System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
 foreach (var A in assemblies)
 {
     Debug.Log(A.FullName);
 }

In my test project it returns those:

 System.Runtime.Serialization
 System.Xml
 Boo.Lang
 UnityScript.Lang
 I18N.West
 I18N
 StrumpyShaderEditor
 PluginBase
 Ionic.Zip
 ClassLibrary1
 ICSharpCode.SharpZipLib
 99aa27bda4361f14daa122d8422328a8    // those are my script assemblies
 6dac0c9e57c785f48af23cab4b6a9065    //
 e5fb0309aa8d3f343b2426d5b5cbb406    // I have used C# and UnityScript 
 89151c5adb8fb004db23eed2920f5f0b    // so there are 6 assemblies ;)
 0ffeb8055303a1e42bd4fe4f136bb35d    //
 1998a47c8bf283646903c1fefb57955f    //
 System.Core
 Mono.Cecil
 System
 UnityEditor
 UnityEngine
 mscorlib

Unity have to do this so other languages can use an assembly from another language. However to use an assembly it has to be compiled first. That's why we have a first pass and a second pass assembly. The first-pass assemblies can't use each other. They are compiled at the same time so they can't reference each other.

The second-pass assemblies are compiled next so they can use all first-pass assemblies, but not other second-pass assemblies. That's why you have to put scripts that should be accessible from another language in a first-pass folder (Standard Assets, plugins).

Editor assemblies, which are only build and used in the editor, are compiled last so they can use all previous assemblies.

To get a complete list of certain classes you have to crawl through all assemblies.
Here's a helper function that returns all types derived from a certain baseclass:

 public static System.Type[] GetAllSubTypes(System.Type aBaseClass)
 {
     var result = new System.Collections.Generic.List<System.Type>();
     System.Reflection.Assembly[] AS = System.AppDomain.CurrentDomain.GetAssemblies();
     foreach (var A in AS)
     {
         System.Type[] types = A.GetTypes();
         foreach (var T in types)
         {
             if (T.IsSubclassOf(aBaseClass))
                 result.Add(T);
         }
     }
     return result.ToArray();
 }
 
 void Start ()
 {
     foreach (var T in GetAllSubTypes(typeof(MonoBehaviour)))
     {
         Debug.Log(T.Name);
     }
 }

Final note: You can put your classes into namespaces without any problems. However Unity "extracts" classes that are derived from MonoBehaviour into the global namespace. That's why namespaces for MonoBehaviours become irrelevant. You can't have two MonoBehaviours (or Editor, EditorWindows, ...) with the same name, even when they are in different namespaces.

Comment
Add comment · Show 2 · 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 ckfinite · Apr 13, 2012 at 12:49 PM 0
Share

Thanks, I found this out when I was trying to answer the question originally.

On another note, Unity said that they are going to support namespaces in the future. Do you know if that was still happening? It would make life a lot easier.

avatar image Bunny83 · Apr 13, 2012 at 01:00 PM 0
Share

Yes i've heard about that too, but yet we don't have namespace support for scripts. I guess it's not that easy. Think about AddComponent and namespaces. All $$anonymous$$onoBehaviours get registrated in the AssetDatabase and they need a unique name. There's a lot that has to be modified and don't forget that they always want to keep the player compatible with old projects.

There's nothing worse than a software that can't open it's own files ;) (I just remember the old $$anonymous$$S Paint... you could open pcx file and save as pcx, but it can't open it's own created pcx file xD )

Of course namespaces would be nice since it's a very basic feature of the language itself, but i guess it will take some time...

avatar image
4

Answer by kenlane22 · Apr 20, 2012 at 03:54 AM

Thanks for the excellent and prompt responses. Below is the Editor class I created. It lets you pick from a list of all available Component classes and then lists the GameObjects that have the component you picked on them (with buttons to select and show 'F'-style in Scene).

[Updated 9/10/12 to base from Component (thnx, Bunny83 and mviuk for the guidance. I also alphabetized the list and nixed the checkboxes until I get around to making them cause selection.]

 using UnityEngine;
 using UnityEditor;
 using System.Collections.Generic;
 using System.Reflection;
 using System;
 using GSES;
 
 
 public class TypePickerEditorWindow : EditorWindow 
 {
     Vector2 scrollPos, scrollPos2;
     List<bool> checkBools = new List<bool>();
     string filter = "";
 
     class NameAndType
     {
         public NameAndType( string n, Type t ) { name = n; type = t; }
         public string name;
         public Type type;
     }
     
     List<NameAndType> typeList = new List<NameAndType>();    
     Type m_currType = null;
     
     void Awake()
     {
         
         // List all C# class Types that are subclasses of Component
         typeList.Clear();
         foreach( Type type in GetAllSubTypes( typeof(Component) ) )
         {
             typeList.Add( new NameAndType( type.Name, type ) );
         }
         typeList.Sort( delegate(NameAndType a, NameAndType b) { return a.name.CompareTo(b.name); });
     }
     
     public static System.Type[] GetAllSubTypes(System.Type aBaseClass)
     {
         var result = new System.Collections.Generic.List<System.Type>();
         System.Reflection.Assembly[] AS = System.AppDomain.CurrentDomain.GetAssemblies();
         foreach (var A in AS)
         {
             System.Type[] types = A.GetTypes();
             foreach (var T in types)
             {
                 if (T.IsSubclassOf(aBaseClass))
                     result.Add(T);
             }
         }
         return result.ToArray();
     }
     
     void OnGUI() 
     {
         GUILayout.Label( "Pick a Component type, then click buttons to select GameObjects." );
         GUILayout.BeginHorizontal();
         {
             GUILayout.BeginVertical();
             {
                 GUILayout.BeginHorizontal();
                 {
                     GUILayout.Label( "Filter:", GUILayout.Width(45) );
                     filter = GUILayout.TextField( filter );
                 }
                 GUILayout.EndHorizontal();
                 scrollPos2 = GUILayout.BeginScrollView( scrollPos2, GUILayout.Width(230)  );
                 {
                     int n = typeList.Count;
                     for( int i = 0; i < n; i++ )
                     {
                         string nm = typeList[i].name;
                         GUI.enabled = (m_currType != typeList[i].type); // disable selected one
                         if     ( 
                               ( nm.ToUpper().Contains( filter.ToUpper() ) ) // filtered list wont bother drawning the filtered
                             && 
                                  ( GUILayout.Button( nm ) )  // button pushed!
                             )
                         {
                             m_currType = typeList[i].type;
                             // And set up checkboxes to all false
                             UnityEngine.Object[] ueoList = FindSceneObjectsOfType( m_currType );
                             checkBools.Clear();
                             for (int j = 0; j< ueoList.Length; j++) 
                                 checkBools.Add( false );
                         }
                     }
                 }
                 GUILayout.EndScrollView();
             }
             GUILayout.EndVertical();
             
             GUILayout.BeginVertical();
             {
                 if ( m_currType == null)
                 {
                     GUILayout.Label( "Pick a type in the left column." );
                 }
                 else
                 {
                     GUILayout.Label( "All GameObjects with the class: "+ m_currType.Name );
                     scrollPos = GUILayout.BeginScrollView( scrollPos );
                     {
                         int i = 0;
                         UnityEngine.Object[] ueoList = FindSceneObjectsOfType( m_currType );
                         foreach( UnityEngine.Object o in ueoList )
                         {
                             GUILayout.BeginHorizontal();
                             {
                                 Component com = o as Component;
                                 if ( (com != null) && (com.gameObject != null) )
                                 { 
                                     //checkBools[i] = GUILayout.Toggle( checkBools[i],"", GUILayout.Width(20) );
                                     if (  GUILayout.Button( NameWithParent( com.gameObject ) )      )
                                     {
                                         Selection.activeGameObject = com.gameObject;
                                     }
                                     if (  GUILayout.Button( "Show", GUILayout.Width(50) )  )
                                     {
                                         GameObject g = Selection.activeGameObject;
                                         Selection.activeGameObject = com.gameObject;
                                         if (SceneView.lastActiveSceneView != null) SceneView.lastActiveSceneView.FrameSelected();
                                         Selection.activeGameObject = g;
                                     }
                                 }
                                 i++;
                             }    
                             GUILayout.EndHorizontal();
                         }
                     }
                     GUILayout.EndScrollView();
                 }
             }
             GUILayout.EndVertical();
         }
         GUILayout.EndHorizontal(); 
     }
     
     string NameWithParent( GameObject g )
     {
         return g.name;
         //string s;
         //if (g.transform.parent != null) return "~/"+ g.transform.parent.name +"/"+ g.name;
         //else                            return g.name;
     }
     
     [MenuItem ("Window/TypePickerEditorWindow")]
     [MenuItem ("GSE/TypePickerEditorWindow")]
     static public void Init() 
     {
         TypePickerEditorWindow editorWindow = GetWindow(typeof(TypePickerEditorWindow)) as TypePickerEditorWindow;
         editorWindow.autoRepaintOnSceneChange = true;
         editorWindow.Show();
     }
 }

Hope it comes in handy for someone.

-Ken =]

Comment
Add comment · Show 6 · 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 Bunny83 · Apr 20, 2012 at 09:28 AM 0
Share

Nice one. You might want to post it one the unifycommunity wiki as well

avatar image mviuk · Sep 10, 2012 at 01:19 PM 0
Share

Great script, you may want to do your sub stype checking on Behaviour ins$$anonymous$$d of $$anonymous$$onoBehaviour, that way you don't need to do camera manually and you get other behaviours too like Animation.

avatar image Bunny83 · Sep 10, 2012 at 01:42 PM 0
Share

Well, you can simply search for all "Components" ins$$anonymous$$d of $$anonymous$$onoBehaviour. This will include all components that can be attached to a gameobject including Transform, Colliders, Rigidbodiy, Renderers, ... which are not Behaviours.

avatar image kenlane22 · Sep 11, 2012 at 04:05 AM 0
Share

Thanks for the tips, Bunny83 & mviuk. I updated the script to base from Component and went ahead and alphabetized the list. Getting closer to truly useful. Next up, add checkboxes that multi-select in hierarchy and Select All/None buttons on the right column. Then off to the unify wiki with it. -$$anonymous$$en =]

avatar image DragonBorn007 · May 19, 2015 at 04:29 AM 0
Share

How can you find classes that do not use mono-behaviour?

Show more comments

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

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

7 People are following this question.

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

Related Questions

The type or namespace name could not be found. Are you missing a using directive or an assembly reference? 4 Answers

References and Namespaces 0 Answers

Why does System.IO assembly give linker errors in Unity 3 when they worked fine b4 2 Answers

namespace support in unity 1 Answer

Why does Boo not see namespaces from dlls? 1 Answer


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