• 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
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
cregox
Lohoris2
softrare
youblistermypaint
ikust
tezza2k1
lPVDl
Novack
SpinyPirate
kal9mondal
Pawciu
Velesey
ZOM585
Bunny83
Rallix
And 11 more...

People who like this

26 Show 0
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
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
SNS_Case
elenzil
druffzy
trojanfoe_
Spy-Shifty
VertexSoup
youblistermypaint
softrare
chrismarch
LuisOscar
v01pe_
kevc45
k1ljcore
Ereona
paskal007r
And 69 more...

People who like this

84 Show 9 · 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 ExecuteInEditMode.

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

This function is very useful combined with [ExecuteInEditMode] for updating static fields, for example :

 using UnityEngine;

 [ExecuteInEditMode]
 public class Example : MonoBehaviour
 {
     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 ExecuteInEditMode 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 paulygons · May 29, 2021 at 07:02 PM 0
Share

OnValidate will also cause console warnings if you try to make changes to some(?) scene object values (apparently). The warning can be confusing: "SendMessage cannot be called during Awake, CheckConsistency, or OnValidate"

https://forum.unity.com/threads/sendmessage-cannot-be-called-during-awake-checkconsistency-or-onvalidate-can-we-suppress.537265/

avatar image

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
cregox
omrip32
Ramlock

People who like this

1 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

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
Jamora
insominx
Harinezumi
pako
Ramlock

People who like this

1 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 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).

avatar image atr0phy · Jun 13, 2022 at 11:46 AM 0
Share

But why? Not sure I see the purpose of doing extra work to bypass built in functionality for no justifiable reason. That's akin to cramming your entire block of Start() logic into the Update() loop with a _isFirstRun bool.

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

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

When I Multi-select gameobjects and press 'delete' 'OnDestroy' func is not called? 0 Answers

Unity Editor - Class variable value contrain 4 Answers

How do I detect that MonoBehaviour is modified in the Editor? 2 Answers

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

Custom icons for files on Project Window 0 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