6161#include " scene/main/window.h"
6262#include " servers/audio/audio_stream.h"
6363
64- constexpr double FPS_DECIMAL = 1 ;
64+ constexpr double FPS_DECIMAL = 1.0 ;
6565constexpr double SECOND_DECIMAL = 0.0001 ;
66+ constexpr double FACTOR = 0.0625 ;
6667
6768void AnimationTrackKeyEdit::_bind_methods () {
6869 ClassDB::bind_method (D_METHOD (" _update_obj" ), &AnimationTrackKeyEdit::_update_obj);
@@ -1799,7 +1800,7 @@ void AnimationTimelineEdit::update_values() {
17991800 }
18001801
18011802 editing = true ;
1802- if (use_fps && animation->get_step () > 0 ) {
1803+ if (use_fps && animation->get_step () > 0.0 ) {
18031804 length->set_value (animation->get_length () / animation->get_step ());
18041805 length->set_step (FPS_DECIMAL);
18051806 length->set_tooltip_text (TTR (" Animation length (frames)" ));
@@ -5016,7 +5017,6 @@ void AnimationTrackEditor::_snap_mode_changed(int p_mode) {
50165017 key_edit->set_use_fps (use_fps);
50175018 }
50185019 marker_edit->set_use_fps (use_fps);
5019- step->set_step (use_fps ? FPS_DECIMAL : SECOND_DECIMAL);
50205020 _update_step_spinbox ();
50215021}
50225022
@@ -5027,12 +5027,10 @@ void AnimationTrackEditor::_update_step_spinbox() {
50275027 step->set_block_signals (true );
50285028
50295029 if (timeline->is_using_fps ()) {
5030- if (animation->get_step () == 0 ) {
5031- step->set_value (0 );
5030+ if (animation->get_step () == 0.0 ) {
5031+ step->set_value (0.0 );
50325032 } else {
5033- // The value stored within tscn cannot restored the original FPS due to lack of precision,
5034- // so the value should be limited to integer.
5035- step->set_value (Math::round (1.0 / animation->get_step ()));
5033+ step->set_value (1.0 / animation->get_step ());
50365034 }
50375035
50385036 } else {
@@ -5146,7 +5144,9 @@ void AnimationTrackEditor::_update_step(double p_new_step) {
51465144
51475145 EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton ();
51485146 undo_redo->create_action (TTR (" Change Animation Step" ));
5149- float step_value = p_new_step;
5147+ // To ensure that the conversion results are consistent between serialization and load, the value is snapped with 0.0625 to be a rational number.
5148+ // step_value must also be less than or equal to 1000 to ensure that no error accumulates due to interactions with retrieving values from inner range.
5149+ double step_value = MIN (1000.0 , Math::snapped (p_new_step, FACTOR));
51505150 if (timeline->is_using_fps ()) {
51515151 if (step_value != 0.0 ) {
51525152 step_value = 1.0 / step_value;
@@ -6363,8 +6363,8 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) {
63636363 return ;
63646364 }
63656365 float anim_step = animation->get_step ();
6366- if (anim_step == 0 ) {
6367- anim_step = 1 ;
6366+ if (anim_step == 0.0 ) {
6367+ anim_step = 1.0 ;
63686368 }
63696369 if (p_from_mouse_event && Input::get_singleton ()->is_key_pressed (Key::SHIFT)) {
63706370 // Use more precise snapping when holding Shift.
@@ -6374,8 +6374,8 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) {
63746374
63756375 float pos = timeline->get_play_position ();
63766376 pos = Math::snapped (pos - anim_step, anim_step);
6377- if (pos < 0 ) {
6378- pos = 0 ;
6377+ if (pos < 0.0 ) {
6378+ pos = 0.0 ;
63796379 }
63806380 set_anim_pos (pos);
63816381 _timeline_changed (pos, false );
@@ -6386,8 +6386,8 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event, bool p_timeli
63866386 return ;
63876387 }
63886388 float anim_step = animation->get_step ();
6389- if (anim_step == 0 ) {
6390- anim_step = 1 ;
6389+ if (anim_step == 0.0 ) {
6390+ anim_step = 1.0 ;
63916391 }
63926392 if (p_from_mouse_event && Input::get_singleton ()->is_key_pressed (Key::SHIFT)) {
63936393 // Use more precise snapping when holding Shift.
0 commit comments