0 votes

Hello, everyone! I'm experimenting with art and animation styles in Godot and am trying to achieve a result similar to Arc System Works' Guilty Gear Xrd where the models are animated frame-by-frame rather than interpolated over time.

Example:
https://youtu.be/yhGjCzxJV3E?t=2036

I'm very close, but there's one problem: any type of 3D model with animations imported into Godot is automatically set to "linear" interpolation instead of "nearest." In Blender, if I animate a model using constant interpolation for the keyframes, I get the desired result, but Godot will still import and set all 3D transformation tracks to linear and the effect is lost.

The obvious solution is to manually set the tracks to nearest, but a completed character model can have dozens if not hundreds of bones, so doing all of that manually for every character for every animation can be a nightmare, especially if I wind up updating a model or an animation and everything gets reset.

I found some solutions on my own, but they still require some work; I believe that there ought to be an option somewhere that will simply set all 3D transformation tracks to nearest with a click of a button, but I can't seem to find it anywhere. If anyone knows how to do so or where I can make a request for such a feature, I would greatly appreciate it. Thank you in advance!

in Engine by (23 points)

1 Answer

+2 votes
Best answer

I struggled a bit to find the solution, but here it is:

Briefly explained:
What you want to do is access the AnimationPlayer's Animations. Then you want to access the respective Animations' tracks and alter the INTERPOLATION_MODE property of each track. You can do this during runtime or, better yet, create a script that works from within the editor, without running the game. I am going to explain the latter.

Detailed Instructions

1) Go to the Script workspace (near the 3D workspace on the top)

2) Create a new script resource (File--> New Script)

3) Write the following code in the newly created script:

tool     # makes script run from within the editor
extends EditorScript    # gives you access to editor functions



func _run():   # this is the main function
    var selection = get_editor_interface().get_selection() * the selected node. In your case, select the AnimationPlayer
    selection = selection.get_selected_nodes()  # get the actual AnimationPlayer node
    if selection.size()!=1 and not selection is AnimationPlayer: # if the wrong node is selected, do nothing
        return
    else:
        interpolation_change(selection) # run the funstion in question



func interpolation_change(selection):
    var anim_track_1 = selection[0].get_animation("default") # get the Animation that you are interested in (change "default" to your Animation's name)
    var count  = anim_track_1.get_track_count() # get number of tracks (bones in your case)
    print(count)
    for i in count:

        anim_track_1.track_set_interpolation_type(i, 1) # change interpolation mode for every track
        print(anim_track_1.track_get_interpolation_type(i))

4) Go to File-->Run. You should see the Interpolation mode change from linear to nearest.

How it works:

This script iterates through the tracks of your Animation and it changes the INTERPOLATION_MODE for each of them to 0 (nearest).

Check the doc fro more info here:
https://docs.godotengine.org/en/3.1/classes/class_animation.html#class-animation-method-track-get-interpolation-type

For more info on EditorScript, namely scripts that run from the editor, check this out:
https://www.youtube.com/watch?v=IsZjUFA30WQ

If this helps you, please mark the answer as best.

by (1,832 points)
selected by

That did it! Awesome work! This is much faster than every other solution I came up with. I hope that in the future there can just be a simple menu selection that will accomplish this rather than writing a script, but this is fantastic nonetheless. Thank you again!

---Edit!---
Here's a video showing the script in action. The ball on the left is what happens when a frame-by-frame animation is imported from Blender to Godot. The ball on the right is what it's supposed to look like and what happens when the script is run.
https://www.youtube.com/watch?v=qb_8bl4NvuI&feature=youtu.be

I am glad that it worked and I'd be happy to see what beautiful art you create with it :)

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.

Categories