Browse Source

Merge pull request #57372 from KoBeWi/tween_freeze()

Better handle infinite Tween loops
Rémi Verschelde 3 năm trước cách đây
mục cha
commit
cb3d308f96
2 tập tin đã thay đổi với 11 bổ sung1 xóa
  1. 1 1
      doc/classes/Tween.xml
  2. 10 0
      scene/animation/tween.cpp

+ 1 - 1
doc/classes/Tween.xml

@@ -146,7 +146,7 @@
 			<description>
 				Sets the number of times the tweening sequence will be repeated, i.e. [code]set_loops(2)[/code] will run the animation twice.
 				Calling this method without arguments will make the [Tween] run infinitely, until it is either killed by [method kill] or by freeing bound node, or all the animated objects have been freed (which makes further animation impossible).
-				[b]Warning:[/b] Make sure to always add some duration/delay when using infinite loops. 0-duration looped animations (e.g. single [CallbackTweener] with no delay) are equivalent to infinite [code]while[/code] loops and will freeze your game.
+				[b]Warning:[/b] Make sure to always add some duration/delay when using infinite loops. 0-duration looped animations (e.g. single [CallbackTweener] with no delay or [PropertyTweener] with invalid node) are equivalent to infinite [code]while[/code] loops and will freeze your game. If a [Tween]'s lifetime depends on some node, always use [method bind_node].
 			</description>
 		</method>
 		<method name="set_parallel">

+ 10 - 0
scene/animation/tween.cpp

@@ -283,6 +283,10 @@ bool Tween::step(float p_delta) {
 		float step_delta = rem_delta;
 		step_active = false;
 
+#ifdef DEBUG_ENABLED
+		float prev_delta = rem_delta;
+#endif
+
 		for (Ref<Tweener> &tweener : tweeners.write[current_step]) {
 			// Modified inside Tweener.step().
 			float temp_delta = rem_delta;
@@ -312,6 +316,12 @@ bool Tween::step(float p_delta) {
 				start_tweeners();
 			}
 		}
+
+#ifdef DEBUG_ENABLED
+		if (Math::is_equal_approx(rem_delta, prev_delta) && running && loops <= 0) {
+			ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info.");
+		}
+#endif
 	}
 
 	return true;