1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-12 13:20:55 +00:00

Changed NodeOneShot fading so that it does not depend on input delta

This commit is contained in:
Silc Lizard (Tokage) Renew
2025-01-19 17:30:40 +09:00
parent 1b4ed4c038
commit b4ac896c66
2 changed files with 16 additions and 10 deletions

View File

@@ -74,14 +74,14 @@
</member> </member>
<member name="fadein_time" type="float" setter="set_fadein_time" getter="get_fadein_time" default="0.0"> <member name="fadein_time" type="float" setter="set_fadein_time" getter="get_fadein_time" default="0.0">
The fade-in duration. For example, setting this to [code]1.0[/code] for a 5 second length animation will produce a cross-fade that starts at 0 second and ends at 1 second during the animation. The fade-in duration. For example, setting this to [code]1.0[/code] for a 5 second length animation will produce a cross-fade that starts at 0 second and ends at 1 second during the animation.
[b]Note:[/b] [AnimationNodeOneShot] transitions the current state after the end of the fading. When [AnimationNodeOutput] is considered as the most upstream, so the [member fadein_time] is scaled depending on the downstream delta. For example, if this value is set to [code]1.0[/code] and a [AnimationNodeTimeScale] with a value of [code]2.0[/code] is chained downstream, the actual processing time will be 0.5 second. [b]Note:[/b] [AnimationNodeOneShot] transitions the current state after the fading has finished.
</member> </member>
<member name="fadeout_curve" type="Curve" setter="set_fadeout_curve" getter="get_fadeout_curve"> <member name="fadeout_curve" type="Curve" setter="set_fadeout_curve" getter="get_fadeout_curve">
Determines how cross-fading between animations is eased. If empty, the transition will be linear. Should be a unit [Curve]. Determines how cross-fading between animations is eased. If empty, the transition will be linear. Should be a unit [Curve].
</member> </member>
<member name="fadeout_time" type="float" setter="set_fadeout_time" getter="get_fadeout_time" default="0.0"> <member name="fadeout_time" type="float" setter="set_fadeout_time" getter="get_fadeout_time" default="0.0">
The fade-out duration. For example, setting this to [code]1.0[/code] for a 5 second length animation will produce a cross-fade that starts at 4 second and ends at 5 second during the animation. The fade-out duration. For example, setting this to [code]1.0[/code] for a 5 second length animation will produce a cross-fade that starts at 4 second and ends at 5 second during the animation.
[b]Note:[/b] [AnimationNodeOneShot] transitions the current state after the end of the fading. When [AnimationNodeOutput] is considered as the most upstream, so the [member fadeout_time] is scaled depending on the downstream delta. For example, if this value is set to [code]1.0[/code] and an [AnimationNodeTimeScale] with a value of [code]2.0[/code] is chained downstream, the actual processing time will be 0.5 second. [b]Note:[/b] [AnimationNodeOneShot] transitions the current state after the fading has finished.
</member> </member>
<member name="mix_mode" type="int" setter="set_mix_mode" getter="get_mix_mode" enum="AnimationNodeOneShot.MixMode" default="0"> <member name="mix_mode" type="int" setter="set_mix_mode" getter="get_mix_mode" enum="AnimationNodeOneShot.MixMode" default="0">
The blend type. The blend type.

View File

@@ -670,12 +670,19 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:
NodeTimeInfo os_nti = blend_input(1, pi, FILTER_PASS, true, p_test_only); // Blend values must be more than CMP_EPSILON to process discrete keys in edge. NodeTimeInfo os_nti = blend_input(1, pi, FILTER_PASS, true, p_test_only); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
if (Animation::is_less_or_equal_approx(cur_fade_in_remaining, 0) && !do_start && !is_fading_out && Animation::is_less_or_equal_approx(os_nti.get_remain(break_loop_at_end), fade_out)) { if (Animation::is_less_or_equal_approx(cur_fade_in_remaining, 0) && !do_start && !is_fading_out) {
// Predict time scale by difference of delta times to estimate input animation's remain time in self time scale.
// TODO: Time scale should be included into NodeTimeInfo for Godot 5.0.
double abs_os_delta = Math::abs(os_nti.delta);
double tscl = Math::is_zero_approx(abs_delta) || Math::is_zero_approx(abs_os_delta) || Math::is_equal_approx(abs_delta, abs_os_delta) ? 1.0 : (abs_delta / abs_os_delta);
double os_rem = os_nti.get_remain(break_loop_at_end) * tscl;
if (Animation::is_less_or_equal_approx(os_rem, fade_out)) {
is_fading_out = true; is_fading_out = true;
cur_fade_out_remaining = os_nti.get_remain(break_loop_at_end); cur_fade_out_remaining = os_rem;
cur_fade_in_remaining = 0; cur_fade_in_remaining = 0;
set_parameter(internal_active, false); set_parameter(internal_active, false);
} }
}
if (!p_seek) { if (!p_seek) {
if (Animation::is_less_or_equal_approx(os_nti.get_remain(break_loop_at_end), 0) || (is_fading_out && Animation::is_less_or_equal_approx(cur_fade_out_remaining, 0))) { if (Animation::is_less_or_equal_approx(os_nti.get_remain(break_loop_at_end), 0) || (is_fading_out && Animation::is_less_or_equal_approx(cur_fade_out_remaining, 0))) {
@@ -686,11 +693,10 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:
set_parameter(time_to_restart, restart_sec); set_parameter(time_to_restart, restart_sec);
} }
} }
double d = Math::abs(os_nti.delta);
if (!do_start) { if (!do_start) {
cur_fade_in_remaining = MAX(0, cur_fade_in_remaining - d); // Don't consider seeked delta by restart. cur_fade_in_remaining = MAX(0, cur_fade_in_remaining - abs_delta); // Don't consider seeked delta by restart.
} }
cur_fade_out_remaining = MAX(0, cur_fade_out_remaining - d); cur_fade_out_remaining = MAX(0, cur_fade_out_remaining - abs_delta);
} }
set_parameter(fade_in_remaining, cur_fade_in_remaining); set_parameter(fade_in_remaining, cur_fade_in_remaining);