Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor Gives me errors each time I exit playmode #119

Closed
gravitate-dev opened this issue May 21, 2021 · 7 comments
Closed

Editor Gives me errors each time I exit playmode #119

gravitate-dev opened this issue May 21, 2021 · 7 comments
Labels
Bug Something isn't working Solved A solution is available here (but may not yet be included in the latest release)

Comments

@gravitate-dev
Copy link

gravitate-dev commented May 21, 2021

Environment

  • Animancer Version Number: Animancer pro v6.1
  • Animancer Pro or Lite: pro
  • Unity Version: 2019.4.15f1
  • Platform: Windows

Description

NullReferenceException: Object reference not set to an instance of an object
Animancer.AnimancerPlayable.GetKey (UnityEngine.AnimationClip clip) (at Assets/Plugins/Animancer/Internal/Core/AnimancerPlayable.cs:523)
Animancer.AnimancerPlayable+StateDictionary.GetOrCreate (UnityEngine.AnimationClip clip, System.Boolean allowSetClip) (at Assets/Plugins/Animancer/Internal/Core/AnimancerPlayable.StateDictionary.cs:232)
Animancer.AnimancerPlayable.Play (UnityEngine.AnimationClip clip) (at Assets/Plugins/Animancer/Internal/Core/AnimancerPlayable.cs:535)
Animancer.AnimancerUtilities+<>c__DisplayClass21_0.b__0 () (at Assets/Plugins/Animancer/Internal/Core/AnimancerUtilities.cs:397)
UnityEditor.EditorApplication.Internal_CallDelayFunctions () (at :0)

A clear and concise description of what the bug is.

Reproduction

Steps to reproduce the bug:

  1. Create an animator and animation for a spriterenderer
  2. add an animancer component
  3. Idk what I did but something
  4. ???
  5. See the error in the Console.

http://prntscr.com/138bsuj
image

image

image

image

using Animancer;
using UnityEngine;

public class SelectionArrow : MonoBehaviour
{
    public HybridAnimancerComponent animancer;
    public SpriteRenderer spriteRenderer;

    public void OnSelected()
    {
        spriteRenderer.enabled = true;
        AnimancerState state = animancer.Play("SelectionActive", -1, 0f);
    }

    public void AnimationEventHideArrow()
    {
        spriteRenderer.enabled = false;
    }
}
@gravitate-dev gravitate-dev added the Bug Something isn't working label May 21, 2021
@KybernetikGames
Copy link
Owner

That's very strange. For AnimancerPlayable.GetKey to throw a NullReferenceException, its Component must be null. But the only place the Component is set is the SetOutput method which the AnimancerComponent passes this into so it should never be null (and it has to actually be null, not just destroyed because it would actually still work if it was only destroyed).

See if you can figure out how to reliably replicate the issue, because I don't think I'll be able to fix it properly unless I can replicate it.

@KybernetikGames KybernetikGames added the Need More Info Further information is requested from the poster label May 21, 2021
@gravitate-dev
Copy link
Author

gravitate-dev commented May 22, 2021

image
Component is null!

I am able to reproduce it by changing any .cs file and when the code recompiles it hits the breakpoint.

Here is a print out of this, inside that breakpoint

"AnimancerPlayable (Sprite (Animancer))"
    base: "AnimancerPlayable (Sprite (Animancer))"
    Animancer.IPlayableWrapper.ChildCount: 1
    Animancer.IPlayableWrapper.Parent: null
    Animancer.IPlayableWrapper.Playable: {UnityEngine.Playables.Playable}
    ApplyAnimatorIK: false
    ApplyFootIK: false
    CommandCount: 0
    Component: null
    Disposables: Count = 0
    FrameID: 0
    Graph: {UnityEngine.Playables.PlayableGraph}
    IsGraphPlaying: true
    IsValid: true
    KeepChildrenConnected: false
    Layers: {Animancer.AnimancerPlayable.LayerList}
    SkipFirstFade: false
    Speed: 1
    States: {Animancer.AnimancerPlayable.StateDictionary}
    System.Collections.IEnumerator.Current: null
    UpdateMode: DSPClock
    _ApplyAnimatorIK: false
    _ApplyFootIK: false
    _DirtyNodes: {Animancer.Key.KeyedList<Animancer.AnimancerNode>}
    _Disposables: Count = 0
    _Graph: {UnityEngine.Playables.PlayableGraph}
    _IsGraphPlaying: true
    _KeepChildrenConnected: false
    _LateUpdate: {Animancer.AnimancerPlayable.LateUpdate}
    _LayerMixer: {UnityEngine.Playables.Playable}
    _RootPlayable: {UnityEngine.Playables.Playable}
    _SkipFirstFade: false
    _Updatables: {Animancer.Key.KeyedList<Animancer.IUpdatable>}

Currently I monkey patched it by changing the code to

OLD: AnimancerPlayable.cs

public object GetKey(AnimationClip clip) => Component.GetKey(clip);

NEW: AnimancerPlayable.cs

public object GetKey(AnimationClip clip) {
            if (Component==null)
                return clip;
            return Component.GetKey(clip);
        }

@KybernetikGames
Copy link
Owner

return clip would be better since that's what the base AnimancerComponent does, but the Component is still null meaning there must be a bug somewhere else that's not initialising the system properly.

To debug it we'd need a Debug.Log in SetOutput to log its parameters, which would be pretty annoying if you have to leave it there indefinitely since we don't know how to actually replicate the issue.

@gravitate-dev
Copy link
Author

gravitate-dev commented May 22, 2021

I updated my post to use the return clip.
This is the bugged gameobject

image

I found the error, You are returning early if its a prefab and thus Component is not set. This needs to be changed where Component is still set.

image

@KybernetikGames
Copy link
Owner

You can't play animations on a prefab since it's not in the scene. That should actually throw an exception instead of returning.

@KybernetikGames
Copy link
Owner

In AnimancerPlayable.SetOutput I've changed it to:

if (UnityEditor.EditorUtility.IsPersistent(animator))
    throw new ArgumentException(
        $"The specified {nameof(Animator)} component is a prefab which means it cannot play animations.",
        nameof(animator));

And in AnimancerUtilities.EditModePlay I've changed the nested ShouldPlay method to:

if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode ||
    animancer == null ||
    animancer.Animator == null ||
    clip == null ||
    UnityEditor.EditorUtility.IsPersistent(animancer.Animator))
    return false;

@KybernetikGames KybernetikGames added Solved A solution is available here (but may not yet be included in the latest release) and removed Need More Info Further information is requested from the poster labels May 22, 2021
@KybernetikGames
Copy link
Owner

Animancer v7.0 is now available with this fix in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Solved A solution is available here (but may not yet be included in the latest release)
Projects
None yet
Development

No branches or pull requests

2 participants