Manim 0.18.1: Updaters don't work with objects which have been added using LaggedStart()
Description of bug / unexpected behavior
When adding an object to a scene using LaggedStart() no updaters are recognized:
- not when using
.add_updater()before adding to the scene - not
always_redraw()objects - not when using
.add_updater()after adding to the scene
Expected behavior
well, updaters should be executed... Especially when added afterwards
How to reproduce the issue
Code for reproducing the problem
class laggingUpdater(Scene):
def construct(self):
vt = ValueTracker(0)
dot1a = Dot().shift(3*UP)
dot2a = Dot().shift(2*UP)
dot3a = always_redraw(lambda:
Dot().shift(1*UP+vt.get_value()*RIGHT)
)
dot1b = Dot().shift(1*DOWN)
dot2b = Dot().shift(2*DOWN)
dot3b = always_redraw(lambda:
Dot().shift(3*DOWN+vt.get_value()*RIGHT)
)
def updater(mobj):
mobj.set_x(vt.get_value())
dot1a.add_updater(updater)
dot1b.add_updater(updater)
self.play(
LaggedStart(
Create(dot1a),
Create(dot2a),
Create(dot3a)
)
)
self.play(
Create(dot1b),
Create(dot2b),
Create(dot3b)
)
dot2a.add_updater(updater)
dot2b.add_updater(updater)
self.wait()
self.play(vt.animate.set_value(7),run_time=4)
self.wait()
Additional media files
Rendered video
https://github.com/user-attachments/assets/4faf7933-f0b9-4786-ab69-8b66cba20420
System specifications
System Details
- OS: Windows 10
- RAM: enough
- Python version: 3.11.6
- Manim v0.18.1 PASTE HERE
</details>
## Additional comments
https://discord.com/channels/581738731934056449/1293588131999907851/1293588131999907851
The problem is caused by the fact that updating is suspended during the LaggedStart() animation, but it is not resumed automatically afterwards.
class laggingUpdater(Scene):
def construct(self):
vt = ValueTracker(0)
dot1a = Dot().shift(3*UP)
dot2a = Dot().shift(2*UP)
dot3a = always_redraw(lambda:
Dot().shift(1*UP+vt.get_value()*RIGHT)
)
dot1b = Dot().shift(1*DOWN)
dot2b = Dot().shift(2*DOWN)
dot3b = always_redraw(lambda:
Dot().shift(3*DOWN+vt.get_value()*RIGHT)
)
def updater(mobj):
mobj.set_x(vt.get_value())
dot1a.add_updater(updater)
dot1b.add_updater(updater)
self.play(
LaggedStart(
Create(dot1a),
Create(dot2a),
Create(dot3a)
)
)
self.play(
Create(dot1b),
Create(dot2b),
Create(dot3b)
)
dot2a.add_updater(updater)
dot2b.add_updater(updater)
dot1a.resume_updating()
dot2a.resume_updating()
dot3a.resume_updating()
self.wait()
self.play(vt.animate.set_value(7),run_time=4)
self.wait()
https://github.com/user-attachments/assets/866de534-dac7-4f17-9a77-575dd30e8ba3
A possible fix is to write at
composition.py,
class: AnimationGroup(Animation)
method: begin(self)
def begin(self) -> None:
if not self.animations:
raise ValueError(
f"Trying to play {self} without animations, this is not supported. "
"Please add at least one subanimation."
)
self.anim_group_time = 0.0
if self.suspend_mobject_updating:
self.group.suspend_updating()
for anim in self.animations:
anim.begin()
+ else:
+ for anim in self.animations:
+ anim.finish()
I'm actually not sure what's the semantics for else: , but according to what I've read, it's meant to be used as a cleanup which made sense for me in the context of this fix
Oh, I'd better look for this bug first than digging into why my old scenes stoped rendering... Solution was similar to @uwezi: mob.resume_updating() after LaggedStart.