Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by instruct9r · Nov 23, 2015 at 07:38 PM · scripting problemscript.listpublicmonoscript

Get Public Methods from MonoScript

Hi guys.

Is there a way to get all of the custom public Methods (functions), that are in a certain MonoScript? (NOT MonoBehaviour)

Lets say i have a EditorWindow and a field, where i can assign certain MonoScript...So i want to get a list of, only the Public Methods, that i have declared, not all possible methods...

thanks

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

4 Replies

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

Answer by AngryTilde · Nov 24, 2015 at 02:01 PM

Ok that makes much more sense then, hmm...

Then you're looking for GetClass() not GetType(), MonoScripts are just representations of the script assets not the actual classes. Change that and it should give you the public methods.

Comment
Add comment · Show 4 · 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 instruct9r · Nov 24, 2015 at 02:09 PM 0
Share

I just found out that this returns the Type of the Class, that is in the $$anonymous$$onoScript... Exactly what i was looking for...

Thanks for all the help.. So if anyone needs to get the Declared Public $$anonymous$$ethods from Selected $$anonymous$$onoScript:

 var selObj = Selection.activeObject;
 $$anonymous$$onoScript monoScr = selObj as $$anonymous$$onoScript;
 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
 
 $$anonymous$$ethodInfo[] mono$$anonymous$$ethods= monoScr.GetClass().Get$$anonymous$$ethods (flags );

Thanks a lot for the help.. :)

avatar image instruct9r instruct9r · Nov 24, 2015 at 04:31 PM 0
Share

ok One last thing, since we're on that page, to finalize the stuff..

How can i call that Class's $$anonymous$$ethods..

As i understand there are 2 ways

1: To make an instance of the Class. Woud that means, that every time i press the button, it will make new instance. If yes, then that's bad idea i guess..

But if i try:

 var theClass = Activator.CreateInstance(myType) ;    // Create instance of the class

This works, but i can't call the $$anonymous$$ethod, from it.

 theClass.$$anonymous$$ethodOne();

returns

does not contain definition for '$$anonymous$$ethodOne'

2: I can reference the Class.

How woud i do that?

Since i allready have the Class i thought, that i can just call it like:

 myType.$$anonymous$$ethodOne();

but that doesn't work...

thanks

avatar image AngryTilde instruct9r · Nov 25, 2015 at 12:04 AM 0
Share

You'll need to use Invoke ins$$anonymous$$d of calling it directly

So in your case it would look like this:

 $$anonymous$$ono$$anonymous$$ethods[i].Invoke(Activator.CreateInstance(myType), null);

Check out the $$anonymous$$ethodBase.Invoke Documentation from $$anonymous$$icrosoft to see how it works.

If you don't want to create a new object each time you'll have to use static methods rather then non-statics as it needs a target (if it's static you can use a null target), or I guess you could pool them... Since it's just for the editor it should be fine either way, garbage collection shouldn't be an issue since it's only a single instance at any one time.

EDIT: Whoops Shoulda scrolled down, saw this was answered.

Show more comments
avatar image
1

Answer by fafase · Nov 23, 2015 at 08:18 PM

Using reflection you can do that:

      MethodInfo[] methodInfos = obj.GetType().GetMethods();

obj is a reference to whatever type.

Comment
Add comment · Show 5 · 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 instruct9r · Nov 23, 2015 at 09:54 PM 0
Share

I have a script that have 2 methods

     public void $$anonymous$$ethodOne()
     {
 
     }
 
     public void $$anonymous$$ethodTwo()
     {
     
     }

I select that script from the Project Window and then i execute that piece of code:

 Object selection = Selection.activeObject;
 $$anonymous$$ethodInfo[] methods = selection.GetType().Get$$anonymous$$ethods();
 
 for (int i = 0; i < methods.Length; i++)
         {
             Debug.Log(methods[i].Name);
         }

And i get a lot of stuff returned, but the 2 public methods that i have declared are not in that list.

If i use Flags like this:

 BindingFlags flags = BindingFlags.Public;

and then call the Get$$anonymous$$ethods like:

 $$anonymous$$ethodInfo[] methods = selection.GetType().Get$$anonymous$$ethods(flags);

I don't get absolutely anything.

So i am playing with this few hours allready and can't figure out, how i can get only these 2 public methods, that i have declared in the Selected script...

Thanks for the help :)

avatar image fafase instruct9r · Nov 24, 2015 at 05:32 AM 0
Share

They should be there among all other inherited methods. Because a type contains all of the above types, then it becomes a bit cumbersome to only get the bottom type.

You could either make an interface to only those two methods or you would have to get the base class and remove the methods that it contains.

What is the usage you need? $$anonymous$$aybe there is a better solution.

avatar image instruct9r fafase · Nov 24, 2015 at 11:52 AM 0
Share

You know, when you select a UI Button, you can add OnClick Event. And if you add an object there, you can pick the Class and then, which methods you wan to call.

alt text

I want to do something similar, but for $$anonymous$$onoScript. So i can have a GUI, that can input $$anonymous$$onoScript and it can expose all Public $$anonymous$$ethods (Only the declared ones).

I found out, that i can get, what i need if i use the name of the Class like this:

     void Get$$anonymous$$ethods()
   {
             BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
 
             Type myType = typeof(TestProperties);    // Store the Type
 
             $$anonymous$$ethodInfo[] method1 = myType.Get$$anonymous$$ethods (flags);
     
             foreach (var method in method1)
             {
                 Debug.Log(method.Name);
             }
     }

The Above method is called by a GUI Button. And it returns only "$$anonymous$$ethodOne" and "$$anonymous$$ethodTwo", from the TestProperties $$anonymous$$onoScript. But i use the actual name of the Class...

The problem here is that i want to select other scripts as well and have the code figure out, what is the myType.

I have found out, that if Ins$$anonymous$$d of the script above i use this:

 void Get$$anonymous$$ethods()
     {
         BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
 
         UnityEngine.Object selObj = Selection.activeObject;
         $$anonymous$$onoScript monoScr = selObj as $$anonymous$$onoScript;
 
         if (selObj.GetType() == typeof($$anonymous$$onoScript))
         {
         //    $$anonymous$$ethodInfo[] method1 = myType.Get$$anonymous$$ethods (flags);
             $$anonymous$$ethodInfo[] method1 = selObj.GetType().Get$$anonymous$$ethods();
 
             foreach (var method in method1)
             {
                 Debug.Log(method.Name);
             }
         }

It actually get's the $$anonymous$$onoScript Type and NOT "TestProperties" type. How can i make a type of TestProperties, from the selected script.

This is what it returns, when the "TestProperties" mono script is selected...

alt text

As you can see "$$anonymous$$ethodOne" and "$$anonymous$$ethodTwo" are not here at all...

methodsreturned.jpg (113.5 kB)
methodsonclick.jpg (169.3 kB)
Show more comments
avatar image
1

Answer by vexe · Nov 24, 2015 at 05:34 PM

@instruct9r Hey!

I'm not sure why can't you achieve what you want with just the type.GetMethods(flags) function, where flags = public | instance | declared only. That should give you the methods you need, if you want to get methods up the hierarchy, take out the declared only flag. Keep in mind public alone won't work, you need 'instance' flag along with it. If you want to get very specific methods, you could just annotate those methods with an attribute you create, and then go type.GetMethods(flags).Where(m => m.IsDefined(typeof(MyAttribute)).ToArray();

If you want to invoke a method on an instance created from CreateInstance, you need to get a MethodInfo reference and then use your object on its Invoke function. i.e.

 object theClass = Activator.CreateInstance(myType) ;
 MethodInfo theFunction = myType.GetMethod("TheFunction", flags);
 theFunction.Invoke(theClass, new object[] { arguments, if, any, ... });
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 instruct9r · Nov 24, 2015 at 06:22 PM 0
Share

Hi @vexe.

$$anonymous$$any thanks for answering..

Now i will explain (At least my logic), why GetType() doesn't return the $$anonymous$$ethods, that i have declared. I might be wrong though. THese are my first steps in the deep waters :)

That's the script that i am selecting..

 public class TestProperties : Editor
 {
     public void $$anonymous$$ethodOne()
     {
         Debug.Log("$$anonymous$$ethod One Called");
     }
 
     public void $$anonymous$$ethodTwo()
     {
     
     }
 }

If i say selObj.GetType().Get$$anonymous$$ethods, i think, that doesn't work, because the GetType is returning $$anonymous$$onoScript. And $$anonymous$$onoScript doesn't have my custom methods. What i needed to return a type of "TestProperties ", so i can get the actual $$anonymous$$ethods, that i have declared...

I suppose this is why it didn't worked, but it realy didn't. When i changed to GetClass().Get$$anonymous$$ethods(), and passed the correct BIndingFlags, it returned only the 2 public methods, that i have declared.

Now. If i use GetClass().Get$$anonymous$$ethods() - Without Flags it returns a lot more stuff, than the GetType().Get$$anonymous$$ethods(). So i suppose the Class have more methods, than the Type and they are a lot more...

............... 1:I have a question... What's the difference between Object and object? The second one i can use only if i use "using System"? Is it like a virtual object, that holds some data? If yes does that means i can use it also for holding the methods or it can hold only Classes??

2: If i use "using System;" why i can't declare an Object type? I have to use System.Object...

$$anonymous$$any thanks for the info, about how to call the $$anonymous$$ethods from the Class... This is insane..

Aaand the final code :)

 void Get$$anonymous$$ethods()
     {
         BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
 
         System.Object selObj = Selection.activeObject;
 
         if (selObj.GetType() == typeof($$anonymous$$onoScript))
         {
             $$anonymous$$onoScript monoScr = selObj as $$anonymous$$onoScript;    // Get the selObj as $$anonymous$$onoScript
             Type myType = monoScr.GetClass() ;            // Store the Type of the Class of the $$anonymous$$onoScript
 
             $$anonymous$$ethodInfo[] class$$anonymous$$ethods = myType.Get$$anonymous$$ethods (flags);    
         
             object theClass = Activator.CreateInstance(myType) ;                
             $$anonymous$$ethodInfo theFunction = myType.Get$$anonymous$$ethod(class$$anonymous$$ethods[0].Name.ToString());        
 
             theFunction.Invoke(theClass, new object[]{});
 
         }
 }



thanks again for the help...

avatar image vexe · Nov 24, 2015 at 09:29 PM 1
Share

'object' is short for 'System.Object' - which is the base class in C# where all other types inherit from either directly or indirectly. i.e. when you write:

 public class A {}
 public class B : A {}

A 'is a' 'System.Object', it implicitly inherits System.Object, as if you said:

 public class A : System.Object {}

B is also a 'System.Object' because it inherits from A which in turn inherits System.Object.

I would recommend you download ILSpy, it helps you view the code inside System and Unity's classes, very useful tool for learning. If you do that and inspect 'System.Object', you will see it has no data in it, it just has a bunch of functions like GetHashCode, GetType and ToString. But it's not actually empty, it has a type pointer to point to the type object, and a sync block index that is used when you do 'lock' on an object - This is pretty dumb imo, why would they put that in the root object and force all objects to carry this index? how often do we do 'lock'? not much, why not just have a special type of object that we could lock on and have the sync block index in it? - but whatever, $$anonymous$$$ people...

Now, Unity has its own base object class from which all of its other objects inherit ($$anonymous$$onoBehaviour, Component, Editor, ScriptableObject, Assets, etc) - It gets confusing because now you have System.Object, and UnityEngine.Object - those are different things. UnityEngine.Object is a System.Object (remember all objects in C# inherit System.Object)

If in a class you have using UnityEngine; and using System; and then you mention the type 'Object', it gets confused cause there's two 'Objects': System.Object and UnityEngine.Object

To avoid this, I personally prefer to add a using statement wherever I use UnityEngine.Object, it goes like:

 using UnityObject = UnityEngine.Object;

Which just creates an alias called 'UnityObject' - so now every time I want to use UnityEngine.Object I just use UnityObject, and every time I want to use System.Object I just use the shorthand lower case 'object'.

So that's why when you do reflection on types you get more methods than what you asked for, because all objects inherit System.Object so you get functions like GetType, GetHashCode, GetString, etc.

You cannot inherit directly from UnityEngine.Object, it's just how their API works. You can only inherit $$anonymous$$onoBehaviour, ScirptableObject, Editor and EditorWindow.

Hope that helps!

avatar image instruct9r vexe · Nov 24, 2015 at 10:29 PM 0
Share

Great explanation...

using UnityObject = UnityEngine.Object is awesome tip..

Will use that for sure.

$$anonymous$$any thanks for the info..

cheers

avatar image
0

Answer by romuloum_unity · Jul 11, 2020 at 08:11 AM

In Unity 2019/2020 you can use this to show methods from gameobject:

                 System.Reflection.MethodInfo[] method1 = this.GetType().GetMethods();
                 foreach (var method in method1)
                 {
                     Debug.Log(method.Name);
                 }
Comment
Add comment · Show 1 · 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 PixelFireXY · Sep 02, 2021 at 09:23 AM 0
Share

How can you show it in the inspector?

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.

Follow this Question

Answers Answers and Comments

35 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 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

How can I add/remove/destroy more or less objects at runtime ? 1 Answer

Image UI not enabling C# SOLVED 1 Answer

How can i sort a List ? 1 Answer

Scripts Interfering With Each Other 1 Answer

error CS0103: The name `collidedwith' does not exist in the current context 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