Animation

Tween

AnimationPlayer Node vs Tweens
  • AnimationPlayer takes KeyFrames and transitions between them using a manually editable Easing; it's unclear if predefined ones can be used via Script. Tweens does the same but allows for custom (non-predefined) Easing.

  • In summary: both interpolate values using an Easing curve, while AnimationPlayer  is easier and more intuitive, Tweens allows better control when the final value is unknown.

Animated Sprite

Importing animations from a .gltf / .glb file

Using the animations in an AnimationPlayer different from the one generated in the file
  • (Safe!)  Using a script on the Mesh to manage the internal AnimationPlayer :

    • Create a script on the Mesh that has a function for each desired animation.

    • Play the Mesh's animations by calling those functions inside the Entity's AnimationPlayer.

      • This causes some debugging inconveniences due to the visual loss of where the animation ends and what its "critical points" are.

      • If you want to loop animations, just call the Mesh function once and let the animation loop naturally inside the Mesh's AnimationPlayer.

    • Problem:

      • This causes a blending problem between animations because the AnimationTree  will not have information about what is being animated, causing the transition to be completely discrete.

      • As a consequence, transitions inside a BlendSpace2D are not done correctly if that BlendSpace2D's BlendMode  is set to continuous.

    • Solution:

      • You must set the BlendMode to Discrete for the BlendSpace2D so the called functions will work.

      • You can set a 'default_blend_time' on the mesh's AnimationPlayer so animations blend during the transition in the AnimationPlayer. This can be done via:

        • 'default_blend_time', affecting all animations.

        • 'set_blend_time', affecting two specified animations.

        • The Animation->Edit Transitions interface of the AnimationPlayer .

  • (Unsafe!)  Using Animation Libraries and handling the import:

    • >  Extract the animations to a separate file.

    • >  Create an Animation Library and put the animations inside.

    • ~Deal with the problem of a meaningless RootNode..

      • After attempts, I chose the only option that made sense: keep the RootNode in the Mesh while all other animations get a weird path.

      • Using the 'AnimationPlayerRefactor' Addon is very nice. It can solve the pathing problem, making it possible to keep the Root Node as the entity's CharacterBody.

        • However , re-importing the model breaks the model's animation pathing again because the old pathing is overwritten by the new pathing from the export.

        • Because of that, unfortunately, even with the addon this is still bad and unsafe.

Changing the animations that come with the file, using Godot
  • By default, animations cannot be edited in any way, this includes:

    • Trying to modify the AnimationPlayer of an Inherited Scene from the file.

    • Marking 'Editable Children' or 'Make Unique' on an instance of the Inherited Scene or an instance of the file.

  • (Unsafe)  Editing the original tracks of a file animation:

    • I choose not to do this, as it is strange and inconsistent .

    • >  Extract the animations to a separate file.

      • Godot uses this to save the new tracks that will be added.

    • >  Create an Animation Library and put the animations inside.

    • Mark 'Make Unique' on the Animation Library via one of these options:

      • Click 'Make Unique' in the Libraries tab of the AnimationMixer of the AnimationPlayer/AnimationTree.

      • Click the Disk icon on each animation and select 'Make Unique' inside the AnimationPlayer's 'Manage Animations' tab.

    • After doing the above steps, you will be able to:

      • Create new tracks.

      • Remove tracks.

      • Rename tracks.

    • Even after these steps, any re-import of the file or 'Export as .glTF / .glb' in Blender will reset the animations to the file version.

      • This indicates that the animations are still linked to the file. I find this odd considering the AniLibrary was made unique.

  • (Unsafe)  Adding new tracks to a file animation:

    • In the file import tab, enable 'Keep Custom Tracks' for animations you want to add new tracks to.

      • This causes the new  tracks to remain intact after re-import or 'Export as .glTF / .glb' in Blender. The original tracks coming from Blender will be reset.

      • Although this option works, it seems ~unsafe and 'prone to trouble'.

Utils
  • Extract the animation to a separate file:

    • The animation should be saved in a separate .res or .tres file using one of the options in the file's import tab:

    • 'Actions -> Set Animations Save Paths'.

    • 'Save to File' when clicking the animation.

    • Ensure the 'Loop Mode' is set correctly.

    • Be careful not to use 'Skip Import' on the AnimationPlayer, as this can interfere with re-importing animations when re-importing the file.

  • Create an Animation Library and put animations inside:

    • *This is a very stupid process due to Godot's poor implementation of Animation Libraries.

    • Create an AnimationPlayer.

    • Go to the AnimationPlayer's 'Manage Animations' tab and click 'New Library'.

    • After the AnimationLibrary is created, it must be saved to disk by clicking the Disk icon on the AnimationLibrary name in the AnimationPlayer's 'Manage Animations' tab.

      • Regardless of saving it as .tres  or .res  the Animation Library cannot be opened in the inspector for viewing. The only way to access and modify it is via the 'Manage Animations' tab of an AnimationPlayer.

AnimationMixer

AnimationPlayer

  • File and Resource:

    • Clicking 'Duplicate' in the animation tab duplicates the animation with a new name. Doing this will make the Animation have a path pointing to { scene_path .tscn: id }, regardless of whether the Animation was a SubResource of the Scene or if it had its own path { resource_path .tres}.

    • Clicking 'Copy' and 'Paste' performs exactly the same process as 'Duplicate', except that this time the animation name will be the 'Name' variable of the Resource.

    • Clicking 'Copy' and 'Paste as Reference' results differently from 'Duplicate', since both animations will have the same path. If the animation has a path like { scene_path .tscn: id } or { resource_path .tres}, its 'paste by reference' will have the same path (and ID) as the original. If you use this option, I found it complicated to unlink the pathing between the copy and the original, since resetting their paths still causes them to share the same path.

    • Saving the entire Scene  'AnimationPlayer' with a {.tscn} file will save all  animations inside the AnimationPlayer. In other words, this method differs from the usual 'Save Animations' method, since all animations can be saved inside a single file. However, animations may not work if you place the Scene inside a SceneTree with different paths. You will need to recalibrate the tracks' paths manually.

  • Tracks:

    • Interpolation and Easing:

      • Interpolation can be changed on the right side of the Track, between 'Nearest', 'Linear' and 'Cubic'.

      • Easing can be changed by selecting a frame on the Track and editing its easing.

        • You can right-click on the curve to select a preset.

    • Bezier Curves:

      • This Blender video helps visualize them: Blender: Understanding Bezier Curves and the Graph Editor

      • To create Bezier Curves in the AniPlayer, click '+ Add Track' and 'Bezier Curve'.

      • To edit the Curve, select the 'Toggle between bezier curve editor and track editor' icon at the bottom right of the interface.

      • During editing, you can select a frame and change the Handle Type of the frame, as well as fine-tune the Handle position.

  • Tools:

    • When manipulating an animation in the AnimationPlayer, it is interesting to set the 'Snap Option' to 60 FPS (or the game's FrameRate), which results in a pseudo-frame-by-frame view of the animation.

    • The 'Onion Skin' tool enables viewing 'past and future' frames at the same time, allowing better visualization of the motion. This did not work well for 'Discrete' animations and low frame rate 2D animations.

      • The tools to the right of 'Onion Skin': 'Directions', 'Depth', 'Differences Only', 'Force White Modulate' and 'Include Gizmos (3D)', seem to be responsible for fine-tuning the 'Onion Skin' tool.

    • The 'Group Track by Node' tool at the bottom left of the Snap options groups tracks based on their origin. This allows moving tracks via the Inspector , which is great. Another way to get this functionality would be editing the .tres file with text editors, but that process is sometimes very unresponsive.

  • Behaviors:

    • Apparently, AniPlayer and AniTree can play simultaneously. For example, setting AnimationPlayer to AutoLoad will play it independently of whichever AniTree animation is active.

  • [old] Dissatisfactions:

    • (BUG) Disabling a track in an animation does absolutely nothing if the animation is started from an AniTree; the track still works anyway. Observed in Godot 3.5.1, but this has happened since ~Feb/2019.

    • (BUG) If using an AniPlayer as its OWN SCENE, making any change to an Animation or property of the AniPlayer will not be saved or applied in the game. There are many situations where nothing fixes this bug, and if you restart Godot, all changes are lost and reverted. I believe this bug is caused by transforming an AniPlayer into a scene, since all animations inside it have their 'property path' incorrect, which can cause problems saving the scene. Therefore: avoid using AniPlayer scenes, I suppose.

    • (Possible BUG) I changed settings of a {.tscn} file of an AniPlayer containing many animations, but there was a lot of inconsistency during the import of changes from VSCode to Godot, making it very frustrating to try to change this node this way. Note that ALL changes and import processes were done correctly. I tried resetting the scene, restarting the project and Godot, but there was still much frustration. In the end, if you want to make bulk changes in an AniPlayer, using the 'Copy Tracks' and 'Paste Tracks' tool may be one of the least frustrating solutions.

  • Notes: (2023-02-18) About the Player's AniPlayer animations:

    • All AniPlayer animations have their BlendMode set to Discrete.

    • Most animations use the Linear Curve, while some sprite animations use the Cubic Curve.

    • All animations use the Loop Wrap setting, that is, the default setting.

    • Only some animations have loop enabled, for example: Poison effects, Regeneration and Run movement. Idle and Switch movement animations do not loop.

  • Cautions :

    • Never make the AnimationPlayer the 'parent' of something you want to have its position updated. The node does not have a Transform property, so any movement it perceives will not be passed to its children.

AnimationTree

  • File and Resource:

    • Saving the AniTree's 'Tree Root' Resource will save the entire 'Animation Tree' configuration of the node; it will not save the animations themselves, since they are stored only inside the corresponding AnimationPlayer.

  • Transition Modes:

    • Switch Mode: from what I noticed, 'Immediate' transitions the animation as soon as a 'Travel' is requested. 'Sync' transitions the animation exactly like 'Immediate', but sends the 'Seek' property (animation frame) from the previous animation to the next one (the option behaved confusingly). 'AtEnd' transitions the animation when it finishes; however, it cannot exit loops without help from 'Auto_Advance'.

    • Auto_Advance: from what I noticed, when used with 'Immediate' this option makes the animation transition instantly to the next one. When used with 'AtEnd' the option makes the animation transition to the next as soon as the animation ends. "So what's the difference between 'Auto_Advance' and 'AtEnd'?" From what I observed, 'Auto_Advance' can force exiting looping animations, while 'AtEnd' alone cannot transition in that case.

  • Changing parameters:

    • If you want to change internal parameters of the AniTree's 'tree_root', it is important to use 'AniTree.tree_root' to access parameters inside the 'tree_root' AnimationBlendTree. If you want to access an AnimationNode inside the 'tree_root', you can use 'AniTree.tree_root.get_node(" animation_node_name ")'; 'tree_root' in this case is an AnimationNodeStateMachine.

    • If you want to change external parameters of the AniTree's 'tree_root', the process can be done via the AniTree itself without needing to access 'tree_root'. For this, the command 'aniTree.get(" parameter_path ")' stores a parameter value. However, '.get()' only creates a copy of the information in most cases, but when using an AnimationStateMachine together with AniTree.get("parameters/playback")', it is possible to change the AnimationStateMachinePlayback (I believe this works because 'playback' is a resource by itself). Therefore, in general, you will need to use 'aniTree.set(" parameter_path ", new_value )' to change a parameter's value; note that 'aniTree.get(" parameter_path ") = new_value ' will crash the game, as Godot sees this as an error.

  • Cautions :

    • Never make the AnimationTree the 'parent' of something you want to have its position updated. The node does not have a Transform property, so any movement it perceives will not be passed to its children.

AnimationTree: StateMachine
  • Observations:

    • The '.travel(..)' function acts like a 'queue', meaning the travel is only applied at the end of the frame. This implies that if several '.travel(..)' calls are made in sequence within the same frame, one will overwrite the other so that only the last one will actually travel.

  • Dissatisfactions:

    • The functions 'aniState.get_current_play_position()' and 'aniState.get_current_length()' interact strangely when using these commands to collect information that undergoes some kind of "Blend". From my experience, it is important to disable all Blends made in the BlendSpace2D of the StateMachine to avoid this behavior; although I don't know if that was the real cause of my dissatisfaction. I experimented changing the animation anchor point inside the BlendSpace2D and there was no difference. Therefore I believe the problem is related to the 'Blend Mode'.

    • (BUG) If using an AniPlayer as its OWN SCENE, updating a Transition in the StateMachine does not make the game update the changes. To make the change effective, you need to make a more significant update in the AniTree, for example: create a new Transition between Segments and delete that Transition; this will make the game update and apply the changes. There are many situations where nothing fixes this bug, and if you restart Godot, all changes are lost and reverted. The same problem occurs when using a Resource for the AniTree's 'Tree Root'. Strange.

  • Notes: (2023-02-18) About the Player AniTree's BlendSpaces2D:

    • I used 'Blendmode Interpolated' with 'Sync' enabled. Using these settings was the only combination that gave me the result I wanted: be able to change the BlendPosition while keeping the animation frame, without looping it.

      • After debugging these settings, I noticed there is no 'smooth transition' in the BlendPosition, so it can go from (-1,0) to (0,1) or from (0,1) to (1,0) in just 1 frame.

    • I always use 'PlayMode' on Travel, which makes the States play via a "path" instead of simply "teleporting".

  • Animation: Create an AnimationTree for a 3D character .

    • A 2D BlendSpace called IWR (Idle/Walk/Run) is used as Lobby.

  • Animation: Create a CharacterController and AnimationTree StateMachine .

AnimationTree: BlendTree
  • The 'Blend' effect contained in the nodes 'Blend2', 'Blend3' and 'OneShot' causes one animation OR the other to be played, but when switching to a second animation, the Blend effect remembers the position of the first animation so that when returning to the first one it continues from where it stopped.

  • The 'Add' effect contained in nodes 'Add2', 'Add3', and 'OneShot' allows multiple animations to play simultaneously, combining them in a 'Discrete' way (without mixing).

  • The 'OneShot' node has random issues of ending the animation 1 frame earlier than expected, which can cause problems if an action is assigned to the animation's last frame. This was the cause of the attack animations 'POW bug'. The workaround is to leave 1 empty frame at the end of the animation to avoid the issue affecting the expected outcome.

  • Changing blendtree parameters:

    • Scale and Transition:

    var aniDuracaoCooldown : String = 'parameters/DuracaoCooldown/scale'
    var aniTransicao : String = 'parameters/Transition/transition_request'
    aniTree.set(aniTransicao, 'Cooldown')
    aniTree.set(aniDuracaoCooldown, 1.0)
    
  • Animation: How to use AnimationTree BlendTree .

    • A 2D BlendSpace called IWR (Idle/Walk/Run) is used as Lobby.

  • AnimationTree: Using AniBlendTree filters to only play some animation tracks .

    • The tip is okay, nothing spectacular.