Search Unity

"SendMessage cannot be called during Awake, CheckConsistency, or OnValidate" - can we suppress?

Discussion in 'Editor & General Support' started by Dreamback, Jun 22, 2018.

  1. Dreamback

    Dreamback

    Joined:
    Jul 29, 2016
    Posts:
    220
    Since we updated to a newer version of Unity, we've been getting this warning spammed to the console (and our log) hundreds of times. We are never calling SendMessage, and we are only running the code causing this warning when Application.isPlaying is false. Our OnValidate is calling transform.Find, Resources.Load, GetComponent, and setting MeshRenderer.sharedMaterial, so maybe one of those is calling SendMessage in the background (likely setting sharedMaterial if I were to guess).

    Regardless, it works just fine, probably because we are doing this only in the editor while the game isn't running, so we need a way to suppress the warning.
     
  2. Orion

    Orion

    Joined:
    Mar 31, 2008
    Posts:
    261
    Same here. The project is too large to actually find out where it's being called from and the warning does not include a stack trace. Should this maybe be added to Unity's issue tracker?
     
  3. owen_proto

    owen_proto

    Joined:
    Mar 18, 2018
    Posts:
    120
    I'm getting the same thing and it seems it's being triggered by a call to GetComponent<MeshFilter>().
     
  4. Orion

    Orion

    Joined:
    Mar 31, 2008
    Posts:
    261
    I found the culprit in my case. Apparently transform.SetParent(...) triggers this as well.
    I use OnValidate to make sure some objects are set up correctly, including hierarchy stuff. Apparently that's not allowed anymore.
     
  5. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    The console also spams this when scrubbing the Size value in the inspector of a scrollbar UI component.
    Bit of a regression [if was fixed] since used to happen long ago too.
     
  6. MadWallker

    MadWallker

    Joined:
    Jan 17, 2017
    Posts:
    1
    Still not fixed, changing the slider value on Unity 2018.3.5f1 still gives the warning
     
  7. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    This is spammed if you say set RectTransform.sizeDelta in response to OnValidate (n old thread said it would be removed)
    Because how else can you easily have an editor script modify a RectTransform in the editor in response to inspector changes?

    2018.3.12 - fix in LTS at least?!

    Code (CSharp):
    1. //dumb code fix to kill warning
    2. [ExecuteInEditMode]
    3. public class ClassThatModifiesRT : Monobehaviour
    4. {
    5.     bool resize = false;
    6.  
    7.     private void OnValidate()
    8.     {
    9.         resize = true;
    10.     }
    11.  
    12.     private void LateUpdate()
    13.     {
    14.         if (resize)
    15.         {
    16.             Resize();
    17.             resize = false;
    18.         }
    19.     }
     
    Last edited: Apr 17, 2019
    AshBacchus likes this.
  8. superjayman

    superjayman

    Joined:
    May 31, 2013
    Posts:
    185
    SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    UnityEngine.Object:Instantiate(GameObject, Vector3, Quaternion)

    WTH..SAME ERROR IN UNITY 2018.3.5!!!!!!!!!!!!!!!!!!!!!!!! has this been fixed???
     
  9. mat108

    mat108

    Joined:
    Aug 24, 2018
    Posts:
    131
    I am getting this issue too

    "SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    UnityEngine.UI.AspectRatioFitter:OnValidate()"

    I'm too new to even know what's going on but it seems to be causing all kinds of issues. No clue what's causing it, I'm not editing any sliders nor am I sending any messages.
     
  10. cxode

    cxode

    Joined:
    Jun 7, 2017
    Posts:
    268
    Still getting this in 2019.1 when I try to call RectTransform.SetSizeWithCurrentAnchors in OnValidate(). I would really appreciate a fix as this fills up my console with thousands of warnings.
     
    MilenaRocha likes this.
  11. Aeroxima

    Aeroxima

    Joined:
    Jul 19, 2016
    Posts:
    15
    Getting this spammed just from Instantiate, but it seems to be working? I have no idea if I'm doing something wrong. Just want it to update how many pieces are in a collection when the size is changed in inspector, so other stuff doesn't break.

    SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    UnityEngine.Object:Instantiate(GameObject)

    upload_2019-12-9_17-28-36.png

    The line triggering it:
        pieces.Add(Instantiate(coin));


    Unity 2019.2.11f1
     
    MilenaRocha likes this.
  12. cxode

    cxode

    Joined:
    Jun 7, 2017
    Posts:
    268
    Oh yes, this thread exists. The way I ended up fixing it is I made my own console that replaces the Unity console, and my replacement console ignores these messages.

    Ridiculously over-engineered, but it works.
     
  13. Dahku

    Dahku

    Joined:
    Jan 30, 2013
    Posts:
    15
    Old thread, but I thought I'd share my findings on this for anyone interested now or later.

    We've used OnValidate very extensively in our project for all manner of lightweight editor utilities. Upon updating from 2017 to 2019 our project exploded with this message, so I sent in a bug report to Unity. Their reply:

    In my response I noted that:
    - The documentation doesn't say that (still true as of this post date).
    - The warning message is very confusing as to what the actual "problem" is.
    - The suggested workaround is very cumbersome for something that still works.
    - The complaints and multiple bug reports speak for what a terrible regression this "by design" choice is.

    Their response:
    I gave another argument for the value of OnValidate as we've been using it, then shared the exact Unity version we migrated from (2017.2.3f1) and thanked them for their attention to the issue.

    Been over a month with no followup, so I'm guessing OnValidate as we've known and loved it is officially dead, "by design".


    We've just been tolerating the console spam as it's quite a job to change everything in our project, but following someone's suggestion from elsewhere, I've found what appears to be a viable solution:

    1. Rename the OnValidate() method to _OnValidate().
    2. Paste this right above it: void OnValidate() { UnityEditor.EditorApplication.delayCall += _OnValidate; }
    3. Wrap the methods in #if UNITY_EDITOR / #endif (I've always done this anyway for clarity and to make certain it gets stripped when compiling).
    4. Depending on the nature of the code, Unity may log a MissingReferenceException when running the game. Adding if (this == null) return; to the start of the _OnValidate() method should fix it.

    I was worried this might cause problems if EditorApplication.delayCall is already in the OnValidate method, but the first test works fine. Haven't implemented this across the entire project yet but it looks promising and is easy, clean-ish and doesn't drag Update() into things.


    Update: Ran into a few more complications when working the above method deeper into our project. Edited the steps accordingly, and will update again if anything else crops up.

    Update 2: A couple of our heavier tools that dealt with major changes to serialized fields broke with this method and required some tweaking, so that's something to be aware of. Good idea to test in and out of play mode after making this change.

    Update 3: Still getting along fine with "UnityEditor.EditorApplication.delayCall" in our projects, but @nareshbishtasus kindly pointed out that "UnityEditor.EditorApplication.update" also works. It might work better depending on your timing needs, but a quick test seemed to indicate it may also run more often than delayCall (which may bog down the editor more). Good option to be aware of at any rate.
     
    Last edited: Mar 3, 2021
    bsunity_6, jjbish, Guest_EG and 27 others like this.
  14. cxode

    cxode

    Joined:
    Jun 7, 2017
    Posts:
    268
    Thank you for sharing your findings, @Dahku .

    I think this is the straw that broke the camel's back. Unity has so consistently made decisions that make my life worse, and since the license prohibits editing the source code, there's nothing I can do about them. My studio will be using Godot for our next project.
     
    Last edited: Apr 15, 2020
  15. cxode

    cxode

    Joined:
    Jun 7, 2017
    Posts:
    268
    I poked around some more. Apparently, as of October 2016, the warning was intentionally removed. Why it was re-added in 2018, I have no idea.
     
    bobbaluba and Dahku like this.
  16. marcelo_augusto

    marcelo_augusto

    Joined:
    Nov 18, 2018
    Posts:
    12
    I found a better explanation of the motivation here:
    upload_2020-6-26_8-47-15.png
     
    ChromazoneX likes this.
  17. Dreamback

    Dreamback

    Joined:
    Jul 29, 2016
    Posts:
    220
    This problem is still happening in Unity 2019.4 LTS, we are literally getting thousands of warnings spammed to our console and log that we can do nothing about. So we really need a way to suppress the warning. Note, we aren't directly calling SendMessage, we are doing tag = "SpawnPoint"; so it must be part of the tag property or the tag's equals operator function.

    What we are doing, there are a number of scriptable spawn points throughout our map; while level designing we can see them all, click on one and change an enum in the inspector to set what type of thing spawns there. The OnValidate function automatically sets the GameObject's tag based on that enum, then changes the material so we can easily see by looking at the map what is spawning where (we can set these spawn point objects invisible before making builds).
     
    Last edited: Jul 8, 2020
    wlwl2 likes this.
  18. michaelday008

    michaelday008

    Joined:
    Mar 29, 2019
    Posts:
    135
    Code (CSharp):
    1. SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    2. UnityEngine.UI.Slider:OnValidate()
    3.  
    I just updated to Unity 2019.4.3f1 and I see this message when I load a scene that has a UI slider in it.

    It seems to be the Unity Slider itself that is doing this, and not any of my code.

    The problem occurs in com.unity.ugui\Runtime\Core\Slider.cs. I get the message 27 times even though there is only a single slider in the scene.

    The funny part is there is a block of code later in the file that seems to think it solved the issue, even though it didn't.
    Code (CSharp):
    1. /// <summary>
    2.         /// Update the rect based on the delayed update visuals.
    3.         /// Got around issue of calling sendMessage from onValidate.
    4.         /// </summary>
    5.         protected virtual void Update()
    6.         {
    7.             if (m_DelayedUpdateVisuals)
    8.             {
    9.                 m_DelayedUpdateVisuals = false;
    10.                 Set(m_Value, false);
    11.                 UpdateVisuals();
    12.             }
    13.         }
    That's because the actual problem is this code:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2.         protected override void OnValidate()
    3.         {
    4.             base.OnValidate();
    5.  
    6.             if (wholeNumbers)
    7.             {
    8.                 m_MinValue = Mathf.Round(m_MinValue);
    9.                 m_MaxValue = Mathf.Round(m_MaxValue);
    10.             }
    11.  
    12.             //Onvalidate is called before OnEnabled. We need to make sure not to touch any other objects before OnEnable is run.
    13.             if (IsActive())
    14.             {
    15.                 UpdateCachedReferences();
    16.                 // Update rects in next update since other things might affect them even if value didn't change.
    17.                 m_DelayedUpdateVisuals = true;
    18.             }
    19.  
    20.             if (!UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && !Application.isPlaying)
    21.                 CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
    22.         }
    23.  
    24. #endif // if UNITY_EDITOR
     
    emredesu and ThePhenomena like this.
  19. ihgyug

    ihgyug

    Joined:
    Aug 5, 2017
    Posts:
    194
    Yeah, this is quite silly, same on Unity 2019.4.
    I am marking game objects with the EditorOnly tag based on a chosen platform, and I am doing this both in OnValidate() and on a pre-build script, and the change of tag in validate sadly triggers the warning.
     
  20. littledwarf

    littledwarf

    Joined:
    Dec 26, 2016
    Posts:
    11
    The ones that we have most on our LTS (2019.4.4f1) are the following:

    Code (CSharp):
    1. SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    2. UnityEditor.PrefabUtility:IsPartOfPrefabAsset(Object)
    3. UnityEngine.UI.Toggle:OnValidate() (at C:\Program Files\Unity\Hub\Editor\2019.4.4f1\Editor\Data\Resources\PackageManager\BuiltInPackages\com.unity.ugui\Runtime\UI\Core\Toggle.cs:120)
    4.  
    Code (CSharp):
    1. SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    2. UnityEditor.EditorUtility:Internal_InstantiateRemoveAllNonAnimationComponentsSingle_Injected(Object, Vector3&, Quaternion&)
    3. UnityEditor.EditorUtility:Internal_InstantiateRemoveAllNonAnimationComponentsSingle(Object, Vector3, Quaternion)
    4. UnityEditor.EditorUtility:InstantiateRemoveAllNonAnimationComponents(Object, Vector3, Quaternion)
    5. UnityEditor.EditorUtility:InstantiateForAnimatorPreview(Object)
    6. UnityEditor.PreviewData:UpdateGameObject(Object)
    7. UnityEditor.PreviewData:.ctor(Object)
    8. UnityEditor.GameObjectInspector:GetPreviewData()
    9. UnityEditor.GameObjectInspector:RenderStaticPreview(String, Object[], Int32, Int32)
    10. UnityEditor.AssetPreviewUpdater:CreatePreviewForAsset(Object, Object[], String)
    11.  
     
  21. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
    In my case, it's also link to Unity's own code. It seems to be the code for a UI.Toggle.
     
    ikriz and cxode like this.
  22. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    Got it on 2019.4.10 (and on 2020.1.6) as multiple:
    SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    UnityEngine.UI.Slider:OnValidate()

    Happens on exiting play mode.

    UPD:
    It is in file: Unity\Editor\Data\Resources\PackageManager\BuiltInPackages\com.unity.ugui\Runtime\UI\Core\Slider.cs

    In OnValidate()

    On line:
    Code (CSharp):
    1. if (!UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && !Application.isPlaying)
    Workaround I've made may be not stable but I think the worst thing is delayed update of slider in editor. It is
    1. Comment it in 'OnValidate()'
    2. Insert them in 'UpdadeVisuals()'
    as
    Code (CSharp):
    1.     #if UNITY_EDITOR
    2.         if (!UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && !Application.isPlaying)
    3.            CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
    4.     #endif // if UNITY_EDITOR
    5.  
    I guess for Toggle it will be something similar.

    UPD: Have this erros also on Unity 2020.1.6
     
    Last edited: Sep 26, 2020
  23. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    In 2018.4.26 I also get that error when calling the following in OnValidate:

    Code (CSharp):
    1. if ((particleCameraShakeSource = GetComponent<CinemachineImpulseSource>()) == false) {
    2.     particleCameraShakeSource = gameObject.AddComponent<CinemachineImpulseSource>();
    3. }
     
  24. i-am-developer-9

    i-am-developer-9

    Joined:
    Jul 29, 2020
    Posts:
    5
    I am not using or even I don't know using OnValidate(). I am just changing value of a Slider in unity editor. It is still giving many errors written this
    SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr)

    I frustrated with this. I am using Unity 2018.4.25 f1 LTS
     
  25. ikriz

    ikriz

    Joined:
    Dec 3, 2009
    Posts:
    98
    Also now getting spammed with this error message from the UI from Toggle.cs (Unity 2019.4.12f1 LTS)
     
    Last edited: Jan 5, 2021
  26. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    We get spammed thousands of these when building bundles which totally pollutes our bundle build output. It's 98% of the log.

    GUIUtility.ProcessEvent()"
    "Warning","SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    UnityEditor.BuildPipeline:BuildAssetBundles(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTarget)","SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
    UnityEditor.BuildPipeline:BuildAssetBundles(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTarget)","<>c__DisplayClass23_0.<BuildBundles>b__0() Assets/Editor/Build/BundleBuild.cs:846
     
  27. nareshbishtasus

    nareshbishtasus

    Joined:
    Jun 11, 2018
    Posts:
    36
    It also works with - UnityEditor.EditorApplication.update instead of UnityEditor.EditorApplication.delayCall which delays the calls to the function.
     
    Dahku likes this.
  28. gooby429

    gooby429

    Joined:
    Aug 13, 2019
    Posts:
    135
    Neither of these solutions work for me (2019 LTS). I'm just trying to set the sprite of the spriteRenderer in OnValidate
     
  29. Dahku

    Dahku

    Joined:
    Jan 30, 2013
    Posts:
    15
    Hey @stefancelojevic, not sure what your exact needs are, but maybe this will help if you're still having trouble.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SpriteOnValidate : MonoBehaviour {
    4.  
    5.     [SerializeField, HideInInspector] SpriteRenderer sprRend;
    6.  
    7.     public bool on;
    8.     public Sprite sprOn;
    9.     public Sprite sprOff;
    10.  
    11.     #if UNITY_EDITOR
    12.         void OnValidate() { UnityEditor.EditorApplication.delayCall += _OnValidate; }
    13.         void _OnValidate() {
    14.             if (this == null) return;
    15.             if (sprRend == null) sprRend = GetComponent<SpriteRenderer>();
    16.             sprRend.sprite = (on) ? sprOn : sprOff;
    17.         }
    18.     #endif
    19. }
     
    Last edited: Mar 3, 2021
  30. amisner2k

    amisner2k

    Joined:
    Jan 9, 2017
    Posts:
    43
    I have logic that simply wants to activate and deactivate certain game objects depending on whether a value was changed in the inspector. The workaround Unity provided works but it's certainly not ideal and it's unfortunate they couldn't keep the initial behavior of OnValidate() intact.

    Here's what I do in my MonoBehaviour and I get no warnings from it:

    Code (CSharp):
    1. private void Update() {
    2.     if (dirty) {
    3.         Show(currentScreen);
    4.         dirty = false;
    5.     }
    6. }
    7.  
    8. private bool dirty;
    9. private void OnValidate() {
    10.     dirty = true;
    11. }
     
  31. gooby429

    gooby429

    Joined:
    Aug 13, 2019
    Posts:
    135
    Nope that didn't work for me. I get that annoying SendMessage warning no matter what. But at least I have had no real issues associated with the error since my last post, so I've just gotten used to ignoring it.
     
  32. mibragg

    mibragg

    Joined:
    Apr 10, 2015
    Posts:
    3
    Hi all,

    I have had this warning spamming my console forever and decided to do something about it.
    I am using Unity 2019.4.3f1

    After reading the posts above - here is what solved it for me - in my case.
    Thanks for the discussion all.

    NOTES:
    --------
    I have been using the Radial Layout Group asset as inserted below (RadialLayout.cs)
    1 - Numerous test game objects in my project which have the RadialLayout component on them are currently disabled in my heirarchy.
    2 - Note that OnValidate() is overriden in this script.
    Inside of this override, after calling base.OnValidate() the next line of code calls calculateRadial().

    3 - This line of code in CalculateRadial() causes the warning (line 81?)
    child.anchorMin = child.anchorMax = child.pivot = new Vector2(0.5f, 0.5f);

    Why? Because of the New constructor? Does that send a message?
    I don't know but it does not matter for this fix.
    - knowing why perhaps may lead to others getting rid of this warning in other cases.
    --------

    SUMMARY
    --------
    My fix was to add a 2 lines of code at the top of calculateRadial().

    //===*** add these 2 lines to fix annoying spammed warning
    if (this == null) return;
    if (!this.gameObject.activeSelf) return;
    //===

    So, in this case, the warning seems to be caused by the component's game object being inactive when the call to OnValidate() is executed.
    --------

    Live long and prosper...

    Code (CSharp):
    1.  
    2.  
    3. /// Credit Danny Goodayle
    4. /// Sourced from - http://www.justapixel.co.uk/radial-layouts-nice-and-simple-in-unity3ds-ui-system/
    5. /// Updated by ddreaper - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
    6. /*
    7. Radial Layout Group by Just a Pixel (Danny Goodayle) - http://www.justapixel.co.uk
    8. Copyright (c) 2015
    9. Permission is hereby granted, free of charge, to any person obtaining a copy
    10. of this software and associated documentation files (the "Software"), to deal
    11. in the Software without restriction, including without limitation the rights
    12. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    13. copies of the Software, and to permit persons to whom the Software is
    14. furnished to do so, subject to the following conditions:
    15. The above copyright notice and this permission notice shall be included in
    16. all copies or substantial portions of the Software.
    17. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23. THE SOFTWARE.
    24. */
    25. namespace UnityEngine.UI.Extensions
    26. {
    27.     [AddComponentMenu("Layout/Extensions/Radial Layout")]
    28.     public class RadialLayout : LayoutGroup
    29.     {
    30.         public float fDistance;
    31.         [Range(0f, 360f)]
    32.         public float MinAngle, MaxAngle, StartAngle;
    33.         protected override void OnEnable() { base.OnEnable(); CalculateRadial(); }
    34.         public override void SetLayoutHorizontal()
    35.         {
    36.         }
    37.         public override void SetLayoutVertical()
    38.         {
    39.         }
    40.         public override void CalculateLayoutInputVertical()
    41.         {
    42.             CalculateRadial();
    43.         }
    44.         public override void CalculateLayoutInputHorizontal()
    45.         {
    46.             CalculateRadial();
    47.         }
    48. #if UNITY_EDITOR
    49.         protected override void OnValidate()
    50.         {
    51.             base.OnValidate();
    52.             CalculateRadial();
    53.         }
    54. #endif
    55.         void CalculateRadial()
    56.         {
    57.             //===*** add these 2 lines to fix annoying spammed warning
    58.             if (this == null) return;
    59.             if (!this.gameObject.activeSelf) return;
    60.             //===
    61.  
    62.             m_Tracker.Clear();
    63.             if (transform.childCount == 0)
    64.                 return;
    65.             float fOffsetAngle = ((MaxAngle - MinAngle)) / (transform.childCount);
    66.             float fAngle = StartAngle;
    67.             for (int i = 0; i < transform.childCount; i++)
    68.             {
    69.                 RectTransform child = (RectTransform)transform.GetChild(i);
    70.                 if (child != null)
    71.                 {
    72.                     //Adding the elements to the tracker stops the user from modifiying their positions via the editor.
    73.                     m_Tracker.Add(this, child,
    74.                     DrivenTransformProperties.Anchors |
    75.                     DrivenTransformProperties.AnchoredPosition |
    76.                     DrivenTransformProperties.Pivot);
    77.                     Vector3 vPos = new Vector3(Mathf.Cos(fAngle * Mathf.Deg2Rad), Mathf.Sin(fAngle * Mathf.Deg2Rad), 0);
    78.                     child.localPosition = vPos * fDistance;
    79.                     //Force objects to be center aligned, this can be changed however I'd suggest you keep all of the objects with the same anchor points.
    80.                     child.anchorMin = child.anchorMax = child.pivot = new Vector2(0.5f, 0.5f);
    81.                     fAngle += fOffsetAngle;
    82.                 }
    83.             }
    84.         }
    85.  
    86.  
    87.     }
    88.     }
    89.  
    90.  
    91.  
     
    Last edited: May 15, 2021
    Valastir and Immu like this.
  33. tealm

    tealm

    Joined:
    Feb 4, 2014
    Posts:
    108
    I see the same warnings in Unity LTS 2020.3.12f1, from changing a .sprite on a SpriteRenderer based on selected enum value passed through OnValidate().
     
  34. hyagogow

    hyagogow

    Joined:
    Apr 25, 2014
    Posts:
    26
    This solution worked fine for my Unity 2021.1:

    Code (CSharp):
    1. #if UNITY_EDITOR
    2.         private void OnValidate() => UnityEditor.EditorApplication.delayCall += _OnValidate;
    3.  
    4.         private void _OnValidate()
    5.         {
    6.             UnityEditor.EditorApplication.delayCall -= _OnValidate;
    7.             if(this == null) return;
    8.             UpdateYourSprite();
    9.         }
    10. #endif
     
  35. ZenTeapot

    ZenTeapot

    Joined:
    Oct 19, 2014
    Posts:
    65
    It's obscene that this is still an issue in unity. A deep rooted design problem in the object sequencing that broke the only method that's designed to monitor inspector edits. Now either go through the delayCall style with unseen issues or do the whole caching and monitoring changes business in update. What spectacular "by design" ingenuity.
     
    Neto_Kokku likes this.
  36. CyRaid

    CyRaid

    Joined:
    Mar 31, 2015
    Posts:
    134
    I'm not quite sure how to effectively use OnValidate then. It seems whenever I'd want to use it, I'm met with this issue. Why can't they just schedule the OnValidate on a UI thread or something similar? (if that's the case)
     
  37. Hi_ImTemmy

    Hi_ImTemmy

    Joined:
    Jul 8, 2015
    Posts:
    174
    I've started to get this when I load my project, however I'm getting no callstack so have no clue where it's coming from:



    Any clue how I can get more info on it?
     
  38. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    Basically, Unity forbids you from doing almost anything useful in OnValidate.
     
  39. cxode

    cxode

    Joined:
    Jun 7, 2017
    Posts:
    268
    The crazy thing is they don't actually forbid it. Everything works exactly as you would expect. You just also get these annoying warnings.
     
    emredesu likes this.
  40. ZenTeapot

    ZenTeapot

    Joined:
    Oct 19, 2014
    Posts:
    65
    It's funny that by my own experience this sort of thing only happens when I have a deep-rooted design issue that cannot be fixed in reasonabe amount of time or without breaking major API compatability. This is when I would scream "oh S***" silently and hope everybody just pretends the cumbersome workarounds are good enough.
     
  41. Hi_ImTemmy

    Hi_ImTemmy

    Joined:
    Jul 8, 2015
    Posts:
    174
    In my case OnValidate isn't being used in any scripts but the warnings are still coming up on project load.
     
  42. cxode

    cxode

    Joined:
    Jun 7, 2017
    Posts:
    268
    I finally implemented a proper solution for this. Here's the code:

    Code (CSharp):
    1.     /// <summary>
    2.     /// Sometimes, when you use Unity's built-in OnValidate, it will spam you with a very annoying warning message,
    3.     /// even though nothing has gone wrong. To avoid this, you can run your OnValidate code through this utility.
    4.     /// </summary>
    5.     public static class ValidationUtility
    6.     {
    7.         /// <summary>
    8.         /// Call this during OnValidate.
    9.         /// Runs <paramref name="onValidateAction"/> once, after all inspectors have been updated.
    10.         /// </summary>
    11.         public static void SafeOnValidate(Action onValidateAction)
    12.         {
    13. #if UNITY_EDITOR
    14.         UnityEditor.EditorApplication.delayCall += _OnValidate;
    15.  
    16.  
    17.         void _OnValidate()
    18.         {
    19.             UnityEditor.EditorApplication.delayCall -= _OnValidate;
    20.  
    21.             onValidateAction();
    22.         }
    23. #endif
    24.         }
    25.  
    26.         // For more details, see this forum thread: https://forum.unity.com/threads/sendmessage-cannot-be-called-during-awake-checkconsistency-or-onvalidate-can-we-suppress.537265/
    27.  
    Usage:

    Code (CSharp):
    1. private void OnValidate()
    2. {
    3.     ValidationUtility.SafeOnValidate(() =>
    4.     {
    5.         // Put your OnValidate code here
    6.     });
    7. }
    8.  
     
  43. diesoftgames

    diesoftgames

    Joined:
    Nov 27, 2018
    Posts:
    122
    Just a heads up, this didn't work out for me. It seems to lose a reference somehow in here, so in my case, the SpriteRenderer property I have set ends up with a NullReferenceException even though you can see the property is filled in the inspector. Not entirely sure why, but it's probably related to the underlying bug that is the reason for the warning in the first place maybe?
     
  44. diesoftgames

    diesoftgames

    Joined:
    Nov 27, 2018
    Posts:
    122
    For someone at Unity, how does one do something dead simple like: adjust a child SpriteRenderer.size as we adjust a property on the current behaviour (only needed at authoring time, no need to even run this at runtime, which is when the warning pops up, even if I check if that Application.isPlaying is false before doing so)?
     
  45. lemartialou

    lemartialou

    Joined:
    Jul 10, 2015
    Posts:
    16
    So I had this annoying problem while trying to modify my UI from a custom configuration component.
    This thread has been really helpful, here is my completed working solution, in a commented example :

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. // ------------------------------------------
    5. // Modifying other Components with OnValidate
    6. // ------------------------------------------
    7.  
    8. public class ModifyingOtherComponentsWithOnValidate : MonoBehaviour
    9. {
    10.     // Components we want to modify.
    11.     [SerializeField] private VerticalLayoutGroup layoutGroup;
    12.     [SerializeField] private RectTransform rectTransform;
    13.     [SerializeField] private Image image;
    14.  
    15.     // Inspector values we will use to modify those components.
    16.     [SerializeField] private int layoutLeftPadding;
    17.     [SerializeField] private Vector2 rectSize;
    18.     [SerializeField] private Sprite imageSprite;
    19.  
    20. #if UNITY_EDITOR
    21.  
    22.     // We can register to "update" or to "delayCall", both seem to work.
    23.     // In my experience "update" is much more responsive, I guess because it doesn't
    24.     // have to wait for the end of all inspectors updates (so I'm not sure why we should
    25.     // register to "delayCall" in this use case).
    26.  
    27.     private void OnValidate() => UnityEditor.EditorApplication.update += _OnValidate;
    28.     //private void OnValidate() => UnityEditor.EditorApplication.delayCall += _OnValidate;
    29.  
    30.     private void _OnValidate()
    31.     {
    32.         UnityEditor.EditorApplication.update -= _OnValidate;
    33.         //UnityEditor.EditorApplication.delayCall -= _OnValidate;
    34.  
    35.         // Important: this function could be called after the object has been destroyed
    36.         // (ex: during reinitialization when entering Play Mode, when saving it in a prefab...),
    37.         // so to prevent a potential ArgumentNullException, we check if "this" is null.
    38.         // Note: the components we want to modify could also be in this "destroyed" state
    39.         // and trigger an ArgumentNullException.
    40.  
    41.         // We also check if "this" is dirty, this is to prevent the scene to be marked
    42.         // as dirty as soon as we load it (because we will dirty some components in this function).
    43.  
    44.         if (this == null || !UnityEditor.EditorUtility.IsDirty(this)) return;
    45.  
    46.         // Now we can modify some components !
    47.  
    48.         layoutGroup.padding.left = layoutLeftPadding;
    49.         rectTransform.sizeDelta = rectSize;
    50.         image.sprite = imageSprite;
    51.  
    52.         // SetDirty won't always be necessary, but sometimes it will be needed (ex: LayerGroups).
    53.         // By precaution we call SetDirty on every component we modify.
    54.  
    55.         UnityEditor.EditorUtility.SetDirty(layoutGroup);
    56.         UnityEditor.EditorUtility.SetDirty(rectTransform);
    57.         UnityEditor.EditorUtility.SetDirty(image);
    58.  
    59.         // Special case : this is needed to update the layout of a LayoutGroup.
    60.         LayoutRebuilder.MarkLayoutForRebuild(layoutGroup.transform as RectTransform);
    61.     }
    62.  
    63. #endif
    64. }
    Short version :

    Code (CSharp):
    1. #if UNITY_EDITOR
    2.     private void OnValidate() => UnityEditor.EditorApplication.update += _OnValidate;
    3.     private void _OnValidate()
    4.     {
    5.         UnityEditor.EditorApplication.update -= _OnValidate;
    6.         if (this == null || !UnityEditor.EditorUtility.IsDirty(this)) return;
    7.  
    8.         //ModifyComponentsAndMarkThemAsDirty();
    9.     }
    10. #endif
    @diesoftgames you seem to be missing the null check angainst "this".

    Voilà, I hope this code is right, and I hope it can be useful to somebody else :)
     
  46. JorgeTuke3

    JorgeTuke3

    Joined:
    Mar 5, 2015
    Posts:
    1
    Hello there!
    I get into this issue too and I solved creating an Editor script, here is my solution:

    Code (CSharp):
    1. using UnityEditor;
    2.  
    3. [CustomEditor(typeof(MyScript))]
    4.     public class MyScriptEditor : Editor
    5.     {
    6.         public override void OnInspectorGUI()
    7.         {
    8.             EditorGUI.BeginChangeCheck();
    9.  
    10.             base.OnInspectorGUI();
    11.  
    12.             if (EditorGUI.EndChangeCheck())
    13.             {
    14.                 var script = target as MyScript;
    15.                 script.CustomOnValidate();
    16.             }
    17.         }
    18.     }
    PS. I've tried the OnValidate's callback solution but it took me to another error. Everytime when application was played, shows that transform's reference was destroyed.... weird.
    So this solution fits me well until now....

    I`m using the Unity 2021.3.5f1, and my problem was set the sprite's size in Editor time to create an elevator track.
     
    Last edited: Jul 17, 2022
    eisclimber, GGsparta and t_tutiya like this.
  47. GGsparta

    GGsparta

    Joined:
    Aug 25, 2017
    Posts:
    14
    Thank you @lemartialou for your way of doing it :D
    I wrote a general method to call, so that you don't have to rewrite it everytime. It is really similar to the way React Native is binding its data to its view.

    Code (CSharp):
    1. using System;
    2. using System.Linq;
    3. using UnityEditor;
    4.  
    5. public static class EditorTools
    6. {
    7.     /// <summary>
    8.     /// Execute code that edit/create scene objects in editor. Won't execute if there is no dirty object.
    9.     /// </summary>
    10.     /// <param name="code">Your 'editing' piece of code</param>
    11.     /// <param name="concernedObjects">Concerned components or scene objects. The ones that triggers changes and the ones that are being edited.</param>
    12.     public static void Execute(Action code, params UnityEngine.Object[] concernedObjects)
    13.     {
    14.         void NextUpdate()
    15.         {
    16.             EditorApplication.update -= NextUpdate;
    17.        
    18.        
    19.             if (concernedObjects.Any(c => !c))
    20.             {
    21.                 // One of your objects has been destroyed and I have nothing to do with it!
    22.                 // Why? Might be another edit or did you switched scene?
    23.                 return;
    24.             }
    25.        
    26.             if (concernedObjects.All(c => !EditorUtility.IsDirty(c)))
    27.             {
    28.                 // No edit detected : let's return to bed
    29.                 // Why? Might be the first call when loading a scene.
    30.                 return;
    31.             }
    32.  
    33.             code?.Invoke();
    34.        
    35.             foreach (UnityEngine.Object component in concernedObjects)
    36.                 EditorUtility.SetDirty(component);
    37.         }
    38.  
    39.         EditorApplication.update += NextUpdate;
    40.     }
    41. }
    Usage:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2.     private void OnValidate()
    3.     {
    4.         EditorTools.Execute(() =>
    5.         {
    6.             // edit or create components...
    7.             anotherComponent.randomVar = true;
    8.         }, this, anotherComponent);
    9.     }
    10. #endif
    Edit: If you prefer you can separate the array of concernedObjects to 2 different arrays: one for the edited objects and the other for the triggering/editing objects.
     
    Last edited: Aug 9, 2022
    rjcortes and lemartialou like this.
  48. curio124

    curio124

    Joined:
    Jun 14, 2022
    Posts:
    1
    You can use .delayCall callback that seems to be created exactly for this:

    Code (CSharp):
    1.  
    2. public void OnValidate()
    3.     {
    4.         EditorApplication.delayCall += () =>
    5.         {
    6.             //your code goes here
    7.         }
    8.     }
    9.  
     
    Last edited: Aug 24, 2022
    Itzeusmto, GGsparta, Nit_Ram and 3 others like this.
  49. LinesinRows

    LinesinRows

    Joined:
    Apr 23, 2019
    Posts:
    1
    My solution, I had this problem because my UI objects are not child at the Canvas.
     
  50. mat108

    mat108

    Joined:
    Aug 24, 2018
    Posts:
    131
    If you use EditorApplication.delayCall you need to add the editor namespace. If you add the editor namespace your project won't compile that script, making it so you'd have to remember every script where you implemented this and manually comment it out before compiling.

    It's not a viable solution for this reason.

    Nevermind, what I posted is completely wrong.

    Just type UnityEditor.EditorApplication.delayCall += () =>

    Nevermind, what I posted above is technically true but completely useless as a solution because now you get 'MissingReferenceException object has been destroyed but you are still trying to access it' errors. Unity gonna unity.

    Back to square 1: Console log spammed with sendmessage warnings. Love Unity!
     
    Last edited: Nov 2, 2022
    tnthotdog, Nit_Ram and sinedsem like this.