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

Node3D not selectable in Godot 4 for AnimationTree Root Motion Track (but Spatial was in 3) #75843

Closed
vaner-org opened this issue Apr 9, 2023 · 7 comments

Comments

@vaner-org
Copy link

vaner-org commented Apr 9, 2023

Godot version

4.0.2

System information

Arch Linux, Xorg, Gnome 43

Issue description

The root node in my character exported with Auto-Rig Pro inside Blender contains a "root" Spatial/Node3D node, which is the intended track for root motion. However, Godot 4 doesn't allow me to select it, only the deformation bones contained within Skeleton3D.

Godot 3 LTS
Screenshot from 2023-04-09 08-59-40

Godot 4
Screenshot from 2023-04-09 08-58-35 ``

Steps to reproduce

  1. Open minimal reproduction project in Godot 3 LTS
  2. Open the "char" scene
  3. Click AnimationTree, then in Inspector > Root Motion > Track, select the "root" Spatial node at the top of the hierarchy.
  4. See that everything works as intended.
  5. Now, open the project in Godot 4.
  6. Try to repeat Step 3.

As you can see, it isn't possible. The only way to get around this is to use the project converter in 4's import dialog, and make sure to never touch the Track's setting again.

Minimal reproduction project

root_motion_3.zip

@TokageItLab
Copy link
Member

Your project is not working correctly in 3.x to begin with. If the root motion is working properly, the RootMotionView should scroll.

What you say you did in Godot 3.x by selecting the root node is in fact just disabling the SpatialNode's animation.

The root motion must be included in the bones of the Skeleton, whether 3.x or 4.0.

@TokageItLab TokageItLab closed this as not planned Won't fix, can't repro, duplicate, stale Apr 9, 2023
@vaner-org
Copy link
Author

vaner-org commented Apr 9, 2023

The root motion view does scroll if you carry out step 3, like I said in my instructions. I submitted the project to show in step 3 is not possible in Godot 4. Please don't dismiss this so quickly, I've dedicated months of my life to working in Godot and this completely breaks functionality in 4.

Everyone that uses Auto RIg Pro's root motion export deals with this!

@TokageItLab
Copy link
Member

TokageItLab commented Apr 9, 2023

The root motion view does scroll if you carry out step 3, like I said in my instructions.

I tried your project with 3.5.2, but first of all this is not available. It appears that the RootMotionView assignment for the project was broken. Yeah, it works for now, sorry.

Also, and this is unfortunate and we can only apologize for this, but there is little animation compatibility for 3D between Godot3 and Godot4, and conversion is not easy (see also Animation data rework for 4.0 / Godot 4.0 sets sail: All aboard for new horizons), so if you are considering a 3D project, we recommend that you recreate it in Godot4.

But I don't think it should be enabled in the first place, since from a retargeting standpoint it can't handle animations that are outside of the skeleton. Also, the 3D track for Skeleton and the 3D track for Node are not compatible in some aspects.

You should probably rethink your AutoRig pro settings. Perhaps there is a setting somewhere to include that movement in the bone.

@vaner-org
Copy link
Author

vaner-org commented Apr 9, 2023

Auto Rig Pro bakes the "c-traj" (trajectory) controller bone's animation into the root node as part of a "Root motion" check mark in the settings, which cannot be configured, and is at parity with expected workflows for both Unreal Engine and Unity. However, what it does allow is including the c-traj bone in the export, which is what I did and tried again, with the root motion check mark disabled.

This bone exports forward as Y, and therefore doesn't affect the RootMotionView until "Zero Y" is unchecked, upon which it moves a forward moving character upwards. I've attached the project with the updated model below, if you'd like to see for yourself.

root_motion_3_zeroY.zip

This person is facing the same issue from 18 days ago, here:
https://gamedev.stackexchange.com/questions/204975/godot-root-motion-is-calculated-incorrectly

If the solution is as simple as adding the equivalent of a "+Y Forward" to the c-traj bone for export, I'll contact the developer of Auto Rig Pro and ask that he add a special preset for Godot 4.

@TokageItLab
Copy link
Member

TokageItLab commented Apr 9, 2023

At least if you use retargeting, it will be converted to the axis on the appearance, but if you don't use retargeting, you need to care about the axis direction of the bone. See also #75228.

If the solution is as simple as adding the equivalent of a "+Y Forward" to the c-traj bone for export, I'll contact the developer of Auto Rig Pro and ask that he add a special preset for Godot 4.

Yes, I suggest that.

@vaner-org
Copy link
Author

vaner-org commented Apr 9, 2023

Okay, but that person isn't using Auto Rig Pro, and they have the same problem, and their issue is still open while this one was closed and archived, and most likely visible only to you and me from now on.

Also, this is also an active bug that 4 has every time it's launched:

I tried your project with 3.5.2, but first of all this is not available. It appears that the RootMotionView assignment for the project was broken. Yeah, it works for now, sorry.

...you need to care about the axis direction of the bone

In many months of trying use Blender's default exporter alongside Godot I would have to set all my animations to move upwards when I wanted them to go forwards, which I can't be expected to do for 30+ animations! It's a little strange to tell every person using Root Motion from Blender that they have to retarget, the importer should have options for handling this.

I really don't understand what I'm supposed to be doing in Blender to get the root to cooperate with Godot. The Auto Rig Pro exporter was the only way I could have an actually usable root motion workflow, and it doesn't work with 4 anymore.

@ydeltastar
Copy link
Contributor

ydeltastar commented Dec 2, 2023

This issue makes working with root motion challenging in Godot because many root motion tools and assets export it as an object animation.

It works at runtime if you set root_motion_track to the root node by code. The problem is that we can't preview any root motion feature on the editor because you can't select it on the inspector.

As other engines do, the scene importer could have options to post-process the skeleton and animations to what Godot expects. I managed to get AutoRig Pro exports working with this import script. It creates a root bone, parent it to the base bones, and set the root animation track to point to it. Retargeting is probably still an issue since I didn't find a way to apply bonemaps by script but I did test yet.

@tool
extends EditorScenePostImport


func _post_import(scene):
   modify_skeleton(scene)
   modify_animation(scene)
   
   return scene

func modify_skeleton(scene:Node, add_root = true):
   var skeleton:Skeleton3D = scene.find_child("Skeleton3D") as Skeleton3D
   
   var new_skeleton = skeleton.duplicate() as Skeleton3D
   
   if add_root:
   	new_skeleton.clear_bones()
   	new_skeleton.add_bone("root")
   
   # Can't set a new bone as parent of previous bones
   # Need to rebuild whole skeleton so root is the first bone
   for idx in skeleton.get_bone_count():
   	var name = skeleton.get_bone_name(idx)
   	var enabled = skeleton.is_bone_enabled(idx)
   	var parent = skeleton.get_bone_parent(idx)
   	var pose = skeleton.get_bone_pose(idx)
   	var rest = skeleton.get_bone_rest(idx)
   	var pos = skeleton.get_bone_pose_position(idx)
   	var rot = skeleton.get_bone_pose_rotation(idx)
   	var scale = skeleton.get_bone_pose_scale(idx)
   	
   	new_skeleton.add_bone(name)
   	var new_idx = new_skeleton.get_bone_count()-1
   	new_skeleton.set_bone_enabled(new_idx, enabled)
   	new_skeleton.set_bone_rest(new_idx, rest)
   	new_skeleton.set_bone_pose_position(new_idx, pos)
   	new_skeleton.set_bone_pose_rotation(new_idx, rot)
   	new_skeleton.set_bone_pose_scale(new_idx, scale)
   	
   	new_skeleton.set_bone_parent(new_idx, parent+1)
   
   if add_root:
   	for idx in new_skeleton.get_parentless_bones():
   		new_skeleton.set_bone_parent(idx, 0)
   
   for idx in new_skeleton.get_bone_count():
   	new_skeleton.force_update_bone_child_transform(idx)

   skeleton.replace_by(new_skeleton)
   
   return scene

func modify_animation(scene:Node):
   var root:Node3D = scene.find_child("root")
   var animation_player:AnimationPlayer = scene.find_child("AnimationPlayer")
   
   for animation_name in animation_player.get_animation_list():
   	var animation:Animation = animation_player.get_animation(animation_name)
   	var root_track = animation.find_track("root", Animation.TYPE_POSITION_3D)
   	animation.track_set_path(root_track, "root/Skeleton3D:root")
   	animation.track_move_to(root_track, 0)
   
   return scene

Works great with these export options:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants