• 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
22
Question by shd 1 · Apr 22, 2011 at 01:56 PM · editorvariablecallback

Callback on variable change inside editor

Hello, I'm already using [ExecuteInEditMode] for my C# script, but i cannot find answer for my problem. How to react (inside editor without having to pushing play) on change of exposed (public) variable in real-time without constantly loop-checking (like OnGUI)?

The example would be: 1. I defined 'public type Varname' in my script. 2. Developer changed value of 'Varname' 3. I want to react on that change.

I had this ideas but none of them appeared to working in Unity editor: 1) Define 'public void Set_Varname(type Varname)'. 2) Define variable as 'public type Varname {set {callback_method();}}'

If there is no good way to be called only on variable change in unity editor, which event is called rarely enough to minimize CPU wasting, but every time that developer will change variable from editor?

I'm using C# but question is (i believe) really language agnostic, so You're free to choose answer in any language.

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
70
Best Answer

Answer by iomac · Oct 22, 2015 at 08:12 AM

Try MonoBehavior.OnValidate()

From the docs:

This function is called when the script is loaded or a value is changed in the inspector

In 2020 Unity, it works perfectly when in Editor-Play mode. So, in Editor, "Play" the app. While playing, if you change a value in the Inspector, OnValidate will be called.

And when you are just editing (ie, Play mode off), again, if you change a value in the Inspector, OnValidate will be called.

It also works perfectly if you open a prefab.

(In an actual build: OnValidate is never called for any reason at any time.)

Comment
Add comment · Show 8 · 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 elenzil · Nov 17, 2015 at 12:01 AM 3
Share

this is the correct answer. additionally, this is all you need. you do not also need ExecuteInEdit$$anonymous$$ode.

avatar image ThomLaurent · Jan 25, 2017 at 06:21 PM 2
Share

This function is very useful combined with [ExecuteInEdit$$anonymous$$ode] for updating static fields, for example :

 using UnityEngine;

 [ExecuteInEdit$$anonymous$$ode]
 public class Example : $$anonymous$$onoBehaviour
 {
     public static int Field { get; set; }
 
     [SerializeField]
     private int field; // Developer set value in the inspector, for testing purpose
 
     void Start()
     {
         if (!Application.isEditor)
             Field = 0; // Normal value, used for the final game
     }
 
     void OnValidate()
     {
         Field = field;
     }
 }
avatar image Fattie ThomLaurent · Sep 19, 2020 at 05:37 PM 0
Share

note that ExecuteInEdit$$anonymous$$ode has been REPLACED by [ExecuteAlways] ! thanks, Unity!

avatar image esillen · Jan 11, 2019 at 12:38 PM 0
Share

Be aware that OnValidate()only runs in editor mode. When you make a build, OnValidate will not run when the script loads.

avatar image Burkard esillen · Aug 07, 2019 at 10:51 PM 0
Share

Thanks a lot, @iomac !! I put the setting inside the Start function, so it works when playing too. Then, inside OnValidate, I put Start(); like this:

void OnValidate(){ Start(); }

(Y)

avatar image Bunny83 Burkard · Aug 08, 2019 at 12:12 AM 3
Share

That's a very bad idea. Never manually call other Unity callback functions like Start, Update, Awake ... Those have a well defined execution behaviour. When you call those functions manually you actually break this behaviour. For example Awake and Start are by definition only called once within the life-cycle of a component. When you call it manually it will actually be called more often. If you have functionality that needs to run in Start as well as in OnValidate, create a seperate method which you can call from both callbacks.

Show more comments
avatar image Fattie · Sep 19, 2020 at 05:37 PM 0
Share

An answer so handy, I sent 100 reward :)

avatar image
1

Answer by StephanK · Apr 22, 2011 at 02:16 PM

As Properties are not exposed to the Standard Editor you will need to write your own Inspector for the Component. To see how to do this look at the Editor class and the CustomEditor attribute.

Now you can write your own GUI inside OnInspectorGUI where you can access the property rather than the variable directly. However be aware, that only public variables get serialized by unity, so if you have a property for a private variable that variable won't get saved to the scene file. You can avoid that by combining the HideInInspector and SerializeField attributes.

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 shd 1 · Apr 22, 2011 at 06:15 PM 0
Share

It's not my perfect solution but from what I've searched it's currently the only one. Thanks.

avatar image
1

Answer by supernat · Jul 27, 2012 at 04:38 AM

It requires more variables, but the way I do this is to take advantage of the OnDrawGizmos method.

Create a duplicate set of private variables that will be used to track the public variables shown in the inspector (maybe just prepend them with the word prev). Then, in the OnDrawGizmos method, test for prevVarname != Varname and perform whatever function you need to perform when that variable changes.

Just make sure you update prevVarname after that, and also handle conditions where the user may select invalid values (like a 0 if Varname is going to be a divisor).

You may also want to wrap the OnDrawGizmos prevVarname tests in a nice little timer wrapper if you don't want a heavy resource intensive function to be called very often.

Also note that the editor sometimes gets behind, and things won't catch up until you click off the object or change another value, so it's not a perfect solution.

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 domiii · Jul 01, 2015 at 09:47 AM 0
Share

While that is great for primitive values, it does not quite work all that well with arrays or other complex objects (without having to add and debug a whole lot of code).

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

11 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

Related Questions

Custom Inspector - How to add functionality? 1 Answer

Custom Construct Arrays in the Editor - can I control the name of the element? 0 Answers

Declaring animations on a script in the editor 1 Answer

Changing Prefab Variables From Another Script In Editor 1 Answer

Class Reference in Editor not working 1 Answer

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