From 7b18ad7d9825ec425375f6e46d031cfc79660453 Mon Sep 17 00:00:00 2001 From: Silc Renew Date: Wed, 8 Feb 2023 06:57:00 +0900 Subject: Add root motion accumulator to fix broken RootMotionView --- doc/classes/AnimationTree.xml | 84 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-) (limited to 'doc') diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index 98256f0a38..ed98f47f58 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -33,7 +33,7 @@ - Retrieve the motion of position with the [member root_motion_track] as a [Vector3] that can be used elsewhere. + Retrieve the motion delta of position with the [member root_motion_track] as a [Vector3] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_POSITION_3D], returns [code]Vector3(0, 0, 0)[/code]. See also [member root_motion_track] and [RootMotionView]. The most basic example is applying position to [CharacterBody3D]: @@ -50,12 +50,46 @@ move_and_slide() [/gdscript] [/codeblocks] + By using this in combination with [method get_root_motion_position_accumulator], you can apply the root motion position more correctly to account for the rotation of the node. + [codeblocks] + [gdscript] + func _process(delta): + if Input.is_action_just_pressed("animate"): + state_machine.travel("Animate") + set_quaternion(get_quaternion() * animation_tree.get_root_motion_rotation()) + var velocity: Vector3 = (animation_tree.get_root_motion_rotation_accumulator().inverse() * get_quaternion()) * animation_tree.get_root_motion_position() / delta + set_velocity(velocity) + move_and_slide() + [/gdscript] + [/codeblocks] + + + + + + Retrieve the blended value of the position tracks with the [member root_motion_track] as a [Vector3] that can be used elsewhere. + This is useful in cases where you want to respect the initial key values of the animation. + For example, if an animation with only one key [code]Vector3(0, 0, 0)[/code] is played in the previous frame and then an animation with only one key [code]Vector3(1, 0, 1)[/code] is played in the next frame, the difference can be calculated as follows: + [codeblocks] + [gdscript] + var prev_root_motion_position_accumulator: Vector3 + + func _process(delta): + if Input.is_action_just_pressed("animate"): + state_machine.travel("Animate") + var current_root_motion_position_accumulator: Vector3 = animation_tree.get_root_motion_position_accumulator() + var difference: Vector3 = current_root_motion_position_accumulator - prev_root_motion_position_accumulator + prev_root_motion_position_accumulator = current_root_motion_position_accumulator + transform.origin += difference + [/gdscript] + [/codeblocks] + However, if the animation loops, an unintended discrete change may occur, so this is only useful for some simple use cases. - Retrieve the motion of rotation with the [member root_motion_track] as a [Quaternion] that can be used elsewhere. + Retrieve the motion delta of rotation with the [member root_motion_track] as a [Quaternion] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_ROTATION_3D], returns [code]Quaternion(0, 0, 0, 1)[/code]. See also [member root_motion_track] and [RootMotionView]. The most basic example is applying rotation to [CharacterBody3D]: @@ -69,10 +103,33 @@ [/codeblocks] + + + + Retrieve the blended value of the rotation tracks with the [member root_motion_track] as a [Quaternion] that can be used elsewhere. + This is necessary to apply the root motion position correctly, taking rotation into account. See also [method get_root_motion_position]. + Also, this is useful in cases where you want to respect the initial key values of the animation. + For example, if an animation with only one key [code]Quaternion(0, 0, 0, 1)[/code] is played in the previous frame and then an animation with only one key [code]Quaternion(0, 0.707, 0, 0.707)[/code] is played in the next frame, the difference can be calculated as follows: + [codeblocks] + [gdscript] + var prev_root_motion_rotation_accumulator: Quaternion + + func _process(delta): + if Input.is_action_just_pressed("animate"): + state_machine.travel("Animate") + var current_root_motion_rotation_accumulator: Quaternion = animation_tree.get_root_motion_Quaternion_accumulator() + var difference: Quaternion = prev_root_motion_rotation_accumulator.inverse() * current_root_motion_rotation_accumulator + prev_root_motion_rotation_accumulator = current_root_motion_rotation_accumulator + transform.basis *= difference + [/gdscript] + [/codeblocks] + However, if the animation loops, an unintended discrete change may occur, so this is only useful for some simple use cases. + + - Retrieve the motion of scale with the [member root_motion_track] as a [Vector3] that can be used elsewhere. + Retrieve the motion delta of scale with the [member root_motion_track] as a [Vector3] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_SCALE_3D], returns [code]Vector3(0, 0, 0)[/code]. See also [member root_motion_track] and [RootMotionView]. The most basic example is applying scale to [CharacterBody3D]: @@ -92,6 +149,27 @@ [/codeblocks] + + + + Retrieve the blended value of the scale tracks with the [member root_motion_track] as a [Vector3] that can be used elsewhere. + For example, if an animation with only one key [code]Vector3(1, 1, 1)[/code] is played in the previous frame and then an animation with only one key [code]Vector3(2, 2, 2)[/code] is played in the next frame, the difference can be calculated as follows: + [codeblocks] + [gdscript] + var prev_root_motion_scale_accumulator: Vector3 + + func _process(delta): + if Input.is_action_just_pressed("animate"): + state_machine.travel("Animate") + var current_root_motion_scale_accumulator: Vector3 = animation_tree.get_root_motion_scale_accumulator() + var difference: Vector3 = current_root_motion_scale_accumulator - prev_root_motion_scale_accumulator + prev_root_motion_scale_accumulator = current_root_motion_scale_accumulator + transform.basis = transform.basis.scaled(difference) + [/gdscript] + [/codeblocks] + However, if the animation loops, an unintended discrete change may occur, so this is only useful for some simple use cases. + + -- cgit v1.2.3