godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.47k stars 21.07k forks source link

AnimationTree in inherited scene does not work #40154

Open mechPenSketch opened 4 years ago

mechPenSketch commented 4 years ago

Godot version:

V3.2.2.stable.official (opened via steam)

OS/device including version:

GLES2. Have tried this on GLES3, too.

Issue description:

When I played my project that contains a scene that inherits from another scene which has an animation tree, that animation tree will not play any animation when called.

Specifically: An inherited scene's AnimationTree's parameter/state/playback seem to keep switching into a blank AnimationTreeStateMachine. This is visually shown by a reload icon appearing at that var, and as the result of the newly-created AnimationTreeStateMachine, the AnimationTree cannot change the animation state when called.

Steps to reproduce:

  1. Create new scene (let it be called Base)
  2. Add AnimationPlayer and AnimationTree and fill the appropriate details (such as adding a new AnimationTreeStateMachine to its Tree Root).
  3. Add another Node for the AnimationPlayer to interact with.
  4. Attach script to AnimationTree to call for its state change.
  5. Create New Inherited Scene from Base (let it be called Inherited)
  6. Add button to have AnimationTree change state when pressed.
  7. Play Scene (Inherited)

Minimal reproduction project:

inherited_animtree.zip

Note: There is no Main Scene; Base and/or Inherited have to opened from the FileSystem dock. Note2: I have added print statements in AnimationTree script to show that the function is called, but doesn't change state.

Calinou commented 4 years ago

Related to #34394?

mechPenSketch commented 4 years ago

^ I don't think so, as I'm dealing with 2D animation, while #34394 deals with 3D models. That said, I tried solutions provided there. So far, I have:

mechPenSketch commented 4 years ago

I've tested in what animation state the machine was in before and after it supposed to change state. Using print(state_machine.get_current_node()), I have it made the prints and it printed out nothing, implying that it isn't in any state.

[UPDATE] I might be calling the wrong function, as even when I called it in Base's _ready(), it returns blank. Am I getting the current animation state right? [UPDATE] It is.

mechPenSketch commented 4 years ago

I've just tested whether the problem lies within AnimationPlayer or AnimationTree. As the result, I recoded the change of animation to be directly called in the AnimationPlayer rather than the AnimationTree. The animation works.

For reference, attached below is another minimal reproduction project that excludes AnimationTree from the system: inherited_animplayer.zip

Another possibly noteworthy observation is in the print statements I've made. There's only one time it prints blank: when the Sprite is in Idle mode going to Moving. This happens as I did not set Idle to loop; when its animation finishes, it's no long in any animation state. Perhaps this happens in AnimationTree, too?

[UPDATE] No, it doesn't. Inherited still won't print what current state the AnimationTree is even though Idle is on the loop.

mechPenSketch commented 4 years ago

After doing more testing, I can conclude that the problem lies, specifically, within AnimationTree's playback. Not only state_machine.get_current_node() returns blank, state_machine.is_playing() returns false even when the current animation is Idle, but playing in a loop.

Okay, now I have reset Inherited's playback parameter and the buttons now works! Should I considered this problem solved, or let the developers know that AnimationPlayback should stay as the default parent every time the Base is edited/opened? I find it inconvenient to reset AnimationTree's state's playback every time I create a new scene from a template. [UPDATE] No to the former, because the AnimationTree's state's playback seem to revert to a blank settings after a while. [UPDATE 2] Saving playback does not help the one from Inherited from reverting to blank AnimationPlayback.

The correct diagnosis is: Everytime I create a new scene inherited from one with an AnimationTree, in its parameters, all its states' playback seem to be changed to a blank AnimationNodeStateMachinePlayback, so they had to be manually reset so that it would work properly on the inherited scene.

Na-r commented 4 years ago

I can second this, although I'm unable to find any workaround. When starting the scene, the State Machine is not null, but it is unable to start or travel to any node. Looking at the AnimationTree node during runtime reveals that the playback parameter is empty. Clearing and setting that parameter again in the editor or at runtime does not update the value. This happens even in the node's original scene (not an instantiated version.) image

Na-r commented 4 years ago

I was able to get it working by setting a timer to run the State Machine initialization code 0.5 seconds after the scene had been readied. Any earlier than 0.35~ seconds and it would not work. This is probably not the exact same bug as @mechPenSketch had, but I don't think it's different enough to warrant another report. I posted the exact code I needed below, including resetting the AnimationNodeStateMachinePlayback parameter.

func _on_Timer_timeout() -> void:
    animTree["parameters/playback"] = AnimationNodeStateMachinePlayback.new()
    stateMachine = animTree["parameters/playback"]
    stateMachine.start("Standing_Idle")