Demigiant / dotween

A Unity C# animation engine. HOTween v2
http://dotween.demigiant.com
Other
2.33k stars 348 forks source link

Warning: SendMessage cannot be called during Awake, CheckConsistency, or OnValidate #539

Closed rhys-vdw closed 2 years ago

rhys-vdw commented 2 years ago

Getting an interesting warning when creating a tween in OnValidate.

The stack trace seems to have absolute paths baked in (presumably from @Demigiant's computer). However the weird thing is that the DOTweenComponent doesn't seem to be calling SendMessage from that line.

SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
UnityEngine.GameObject:AddComponent<DG.Tweening.Core.DOTweenComponent> ()
DG.Tweening.Core.DOTweenComponent:Create () (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/Core/DOTweenComponent.cs:262)
DG.Tweening.DOTween:Init (DG.Tweening.Core.DOTweenSettings,System.Nullable`1<bool>,System.Nullable`1<bool>,System.Nullable`1<DG.Tweening.LogBehaviour>) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/DOTween.cs:205)
DG.Tweening.DOTween:AutoInit () (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/DOTween.cs:194)
DG.Tweening.DOTween:InitCheck () (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/DOTween.cs:1075)
DG.Tweening.DOTween:ApplyTo<UnityEngine.Vector3, UnityEngine.Vector3[], DG.Tweening.Plugins.Options.Vector3ArrayOptions> (DG.Tweening.Core.DOGetter`1<UnityEngine.Vector3>,DG.Tweening.Core.DOSetter`1<UnityEngine.Vector3>,UnityEngine.Vector3[],single,DG.Tweening.Plugins.Core.ABSTweenPlugin`3<UnityEngine.Vector3, UnityEngine.Vector3[], DG.Tweening.Plugins.Options.Vector3ArrayOptions>) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/DOTween.cs:1083)
DG.Tweening.DOTween:ToArray (DG.Tweening.Core.DOGetter`1<UnityEngine.Vector3>,DG.Tweening.Core.DOSetter`1<UnityEngine.Vector3>,UnityEngine.Vector3[],single[]) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/DOTween.cs:680)
DG.Tweening.DOTween:Punch (DG.Tweening.Core.DOGetter`1<UnityEngine.Vector3>,DG.Tweening.Core.DOSetter`1<UnityEngine.Vector3>,UnityEngine.Vector3,single,int,single) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/DOTween.cs:563)
DG.Tweening.ShortcutExtensions:DOPunchPosition (UnityEngine.Transform,UnityEngine.Vector3,single,int,single,bool) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/ShortcutExtensions.cs:710)
EffortStar.Chaingun:InitializeTweens () (at Assets/_Game/Scripts/Chaingun.cs:68)
EffortStar.Chaingun:OnValidate () (at Assets/_Game/Scripts/Chaingun.cs:105)
Demigiant commented 2 years ago

That is very weird because DOTween contains zero SendMessage calls. But, you can't create a tween normally in the editor, outside of play-mode, unless you use the corresponding editor methods, so maybe that's what's causing issues even if the error message is wrong.

rhys-vdw commented 2 years ago

@Demigiant yeah it's an odd one. FYI I'm only doing it during play mode:

    void Awake() {
      InitializeTweens();
    }

    void OnValidate() {
      if (Application.isPlaying) {
        InitializeTweens();
      }
    }

    void InitializeTweens() {
      if (_punchTween != null) _shakeTween.Kill();
      _punchTween = _punchPivot.DOPunchPosition(
        _firePunchStrength,
        _firePunchDuration,
        _firePunchVibrato,
        _firePunchElasticity
      ).SetAutoKill(false).Pause();
      if (_shakeTween != null) _shakeTween.Kill();
      _shakeTween = _shakePivot
        .DOShakeRotation(_shake) // (my extension method, but nothing special)
        .SetLoops(-1)
        .SetAutoKill(false)
        .Pause();
    }
Demigiant commented 2 years ago

But OnValidate is editor-only, so it will be called during play-mode but exclusively in the editor (and at a time when runtime code is necessarily ready to be run). I would recommend using only Awake.

On Thu, Dec 16, 2021, 15:51 Rhys van der Waerden @.***> wrote:

@Demigiant https://github.com/Demigiant yeah it's an odd one. FYI I'm only doing it at runtime:

void Awake() {
  InitializeTweens();
}

void OnValidate() {
  if (Application.isPlaying) {
    InitializeTweens();
  }
}

void InitializeTweens() {
  if (_punchTween != null) _shakeTween.Kill();
  _punchTween = _punchPivot.DOPunchPosition(
    _firePunchStrength,
    _firePunchDuration,
    _firePunchVibrato,
    _firePunchElasticity
  ).SetAutoKill(false).Pause();
  if (_shakeTween != null) _shakeTween.Kill();
  _shakeTween = _shakePivot
    .DOShakeRotation(_shake) // (my extension method, but nothing special)
    .SetLoops(-1)
    .SetAutoKill(false)
    .Pause();
}

— Reply to this email directly, view it on GitHub https://github.com/Demigiant/dotween/issues/539#issuecomment-995889050, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB7P6PJ3OKIJZR7VTEZ3HG3URH4IFANCNFSM5KAIXRYQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

Demigiant commented 2 years ago

Sorry I meant "not necessarily" ready to be run

On Thu, Dec 16, 2021, 16:28 Daniele Giardini @.***> wrote:

But OnValidate is editor-only, so it will be called during play-mode but exclusively in the editor (and at a time when runtime code is necessarily ready to be run). I would recommend using only Awake.

On Thu, Dec 16, 2021, 15:51 Rhys van der Waerden @.***> wrote:

@Demigiant https://github.com/Demigiant yeah it's an odd one. FYI I'm only doing it at runtime:

void Awake() {
  InitializeTweens();
}

void OnValidate() {
  if (Application.isPlaying) {
    InitializeTweens();
  }
}

void InitializeTweens() {
  if (_punchTween != null) _shakeTween.Kill();
  _punchTween = _punchPivot.DOPunchPosition(
    _firePunchStrength,
    _firePunchDuration,
    _firePunchVibrato,
    _firePunchElasticity
  ).SetAutoKill(false).Pause();
  if (_shakeTween != null) _shakeTween.Kill();
  _shakeTween = _shakePivot
    .DOShakeRotation(_shake) // (my extension method, but nothing special)
    .SetLoops(-1)
    .SetAutoKill(false)
    .Pause();
}

— Reply to this email directly, view it on GitHub https://github.com/Demigiant/dotween/issues/539#issuecomment-995889050, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB7P6PJ3OKIJZR7VTEZ3HG3URH4IFANCNFSM5KAIXRYQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

rhys-vdw commented 2 years ago

Ah yeah. Makes sense. It's so I can edit some configs with shake values and have them replace the cached tween. Thought maybe something would jump out at you.

It's just a warning that can be ignored in any case, obviously I'm not listening for whatever message it's sending. I could set a flag or something if it really bothered me. Happy for you to close the issue.

Demigiant commented 2 years ago

Closing it, but I added this to my todo list just in case :) (with low priority though)

cdanek commented 2 years ago

At the suggestion of the illustrious @rhys-vdw, adding a little bit of information here. I encountered this issue (SendMessage spam from Unity) when I was trying to do things with RectTransforms in OnValidate(). I neither understood nor cared about the messages, but they were resolved by delaying the updates by subscribing to UnityEditor.EditorApplication.delayCall and doing my layout management there. I'm not sure if DOTween does the same thing internally, but it might be a potential solution to eliminating this spam from users of DT.

My full solution:

    private bool _areInternalComponentsInitialized = false;

#if UNITY_EDITOR
    private void OnValidate()
    {
        UnityEditor.EditorApplication.delayCall += OnValidateCallback;
    }

    private void OnValidateCallback()
    {
        if (this == null)
        {
            UnityEditor.EditorApplication.delayCall -= OnValidateCallback;
            return; // MissingRefException if managed in the editor - uses the overloaded Unity == operator.
        }
        InitializeComponents();
        DoLayout();
    }
#endif

    private void DoLayout()
    {
        if (!_areInternalComponentsInitialized) InitializeComponents();
        ... rect transform modification...
    }

    private void InitializeComponents()
    {
        _areInternalComponentsInitialized = true;
        ... component initialization ...
    }