利益相关本文作者与极坐标⋅XYZjizuobiao.xyz团队有关联。下面的结论是我们在 Manim Community 0.21.02026 年的最新版本上渲出画面、读像素颜色核对的代码都贴在文里结论请自行验证。self.bring_to_front(mob)调了之后物体还是被盖着基本都是同一个原因盖住它的那个东西z_index比它高。Manim 画一帧的时候先按z_index排数字相同的再按添加顺序排。bring_to_front改的只是添加顺序轮不到它说话。改法是给要置顶的物体一个更大的z_index比如mob.set_z_index(2)。Manim 是用 Python 代码做数学动画的开源引擎3Blue1Brown 的视频就是它做的。它没有图层面板重叠的物体谁在上面靠的是两样东西物体加进场景的先后和每个物体身上一个叫z_index的数字默认是 0。先复现两个重叠的方块蓝的设了z_index 1然后想把红的提到上面from manim import * class BringToFrontFails(Scene): def construct(self): red Square(side_length2, colorRED).set_fill(RED, 1).move_to([-0.5, 0, 0]) blue Square(side_length2, colorBLUE).set_fill(BLUE, 1).move_to([0.5, 0, 0]) blue.set_z_index(1) self.add(red, blue) self.bring_to_front(red) self.wait()渲出来两个方块重叠的地方是蓝色。我们把bring_to_front(red)连着调了三次还是蓝色。把blue.set_z_index(1)那一行删掉再跑重叠处就是红色了bring_to_front正常工作。bring_to_front 到底做了什么0.21.0 的源码里它的函数体只有两行def bring_to_front(self, *mobjects): self.add(*mobjects) return selfself.add对一个已经在场景里的物体会先把它从列表里拿掉再接到末尾。所以上面那段代码调完之后self.mobjects是[blue, red]红确实排到了最后。可是画的时候Manim 还要对这张表按z_index排一次序。我们把排完的结果打印出来print([(m.color, m.z_index) for m in self.get_mobject_family_members()]) # 红 0蓝 1红是 0蓝是 1蓝排在后面后画盖住红。不管红在self.mobjects里排第几这一步都会把它排回蓝的前面。bring_to_back是同样的道理它把物体挪到列表开头同样压不住一个z_index更低的东西。add_foreground_mobject我们也试了红用它加成前景物体蓝的z_index是 1重叠处还是蓝色。自己没设过 z_index也会碰到有些 Manim 自带的对象内部已经设了z_index。Graph是一个它的顶点是 0边是 -1这样边永远在顶点下面。副作用是场景里任何一个z_index为 0 的实心物体只要位置和边重叠都会把边盖住和谁先加进场景无关plate Rectangle(width6, height3, colorBLUE).set_fill(BLUE, 1) g Graph([1, 2], [(1, 2)], layout{1: [-2, 0, 0], 2: [2, 0, 0]}) self.add(plate, g) # 底板先加图后加 self.bring_to_front(g) # 再提一次渲出来两个顶点看得见中间那条边看不见被底板挡住了。底板是先加的图是后加的还bring_to_front了一次都没用因为边是 -1底板是 0。把底板降到 -2边就出来了plate.set_z_index(-2)碰到「明明后加的却被先加的盖住」先看一眼被盖的东西是不是哪个库对象的一部分。三种改法给要置顶的物体一个更大的数知道对手是几就比它大一点。不知道的话问场景要当前的最大值top max(m.z_index for m in self.get_mobject_family_members()) red.set_z_index(top 1)我们在一个z_index最大是 7 的场景里这样写红被设成 8到了最上面。把挡路的那个降下去像上面底板的例子该垫底的东西给负数比把别的东西一个个抬高省事。全部清零回到只看添加顺序接手一个到处是z_index的场景想先弄清楚画面时可以这样for m in self.get_mobject_family_members(): m.z_index 0清完之后bring_to_front(red)就管用了我们试过重叠处变回红色。还有一个开关self.camera.use_z_index False效果一样区别是它不改物体身上的数字。平时写场景我们的习惯是二选一要么全程不碰z_index只靠添加顺序和bring_to_front要么只要用了一处z_index后面调层次就都用它。顺带一个副作用别对组里的成员 bring_to_frontbring_to_front是重新add这在物体属于某个组的时候会改掉场景的结构。g VGroup(red, blue, green) self.add(g) print(self.mobjects) # [VGroup] self.bring_to_front(red) print(self.mobjects) # [Square(蓝), Square(绿), Square(红)]调之前场景列表里只有g一项。调之后g从列表里消失了换成了三个散着的方块。g这个对象还在里面还是三个成员但场景已经不把它当成一个整体记着。接下来self.remove(g)就不灵了。我们试了调完之后三个方块还在画面上self.mobjects一个没少。remove找的是列表里的g而列表里已经没有它。要把组里的一个成员提到上面用red.set_z_index(1)它不动场景列表。小结情况bring_to_front(mob)mob.set_z_index(n)场景里都没设过z_index管用管用挡住它的物体z_index更高没用设成更大的数就行被挡的是Graph的边这类自带负z_index的东西没用把挡路的降到更低物体是某个组的成员会把组在场景列表里拆散不影响场景列表之后又有新物体add或FadeIn进来新来的又到它上面不受影响最后一行我们也试了bring_to_front(red)之后self.play(FadeIn(green))绿在红上面。bring_to_front只是那一刻排到最后后面进场的照样排在它后头。z_index的完整规则包括组的z_index怎么传给成员、ReplacementTransform播完为什么会跳层、3D 场景里还管不管用在极坐标⋅XYZ 的这篇文章里写得更细配套视频在教程《布局下· 尺寸 / 包围 / 编组 / 深度 实战》的第四节。实测环境Manim Community 0.21.0 · 2026 年 10 月