大家好，欢迎来到本期艺术家的脚本的教程视频
我的名字是Sybren
这一集的内容是关于Blenderer集合
这些是Blenderer 2.8中引入的，取代了编号的场景层和组
我没有象往常一样在Blenderer研究所录制
但我现在和你们很多人一样，都在家
因此，这段视频的脚本会比较少
我不会有任何幻灯片展示
我们将直接进入Blender，我将在那里展示一些东西
所以在这里的Outliner中你可以看到我们有一个scene collection
里面有一个Suzanne
就象一个对象一样
它有默认的集合，Collection 1
所以鉴于此，这里的这个东西叫做场景集合
我们来看看这个场景对象，看看能不能找到一个集合属性
这里我们有Suzanne
提醒一下，这里我们有方便变量
所以大写的C代表bpy.context，大写的D代表bpy.data
你不能在你自己的脚本中使用这些变量
但你可以在控制台中使用它们来解决问题
我们来看一下，输入C.scene.coll
然后按Tab键，你可以看到
它已经有一个collection属性了
我们可以得到它的名字，叫(主集合)master collection
因为它是主场景集合，它有一个属性叫objects
如果你把它转换为列表，只要按向上的箭头
然后输入list，并把前面的放在括号里
在那里你可以看到
有一个对象，Suzanne，就是这个
collection.objects给出所有直接链接到集合中的对象
看看当我们把Suzanne移到Collection 1中会发生什麽
它仍然是间接地在场景集合里面
因为它是在Collection 1里面
而Collection one是在场景集合里面
但是它已经不在"scene.collection.object"里面了
如果你想真的什麽都有，那就看"all_objects"
这就象一个神奇的视图，可以让你看到集合本身的一切
所以它包含了那个对象也包含的一切
但随后它也包含了集合里面的集合和集合里面的集合和
而你可以看到我们有Suzanne
所以像Blender集合中的很多东西都要有一个唯一的名字
因为它们是以数据的形式存储的
所以我们有"bpy.data"
或者在控制台中的D.collection
这就给了我们collection 1
它不包含场景主集合
但它包含了其他所有的集合
所以在这里
我们也可以得到D.collection['Collection 1'].objects"
并将其转换为列表，看看里面都有什麽
同样的，当然也有Suzanne在里面
所以这已经给了你一个方法
给定了一个集合的名称
就可以迭代该集合中的所有对象
所以，也许你想写一个输出器
输出一个特定集合中的所有对象
现在你知道如何访问它了
我的意思是迭代这些对象
让我们看看这是如何发生的，只是为了唤醒你们的记忆
假设我们有一段波希米亚狂想曲
在这个系列中有四首苏珊娜的作品
如果我们用list.collection.object， 那麽我们就会得到所有的四个
让我们看看在更复杂一点的代码中会是什麽样子
你基本上会用coll=D.collection['collection 1']
然后我可以输入for ob in coll.object:
print(f'08 name is:{ob.name}')
这是一个格式字符串
真的很有用
你可以在开头的引号前输入一个F
然后在大括号内，你可以写出像"ob.name"这样的表达式
而你在这里可以看到的是，它列出了所有对象的名字
所以，它用For循环来循环
循环到集合中的所有对象，然后对其做一些事情
这可能是调用一个导出器
也可能是设置一个材质
也可能是更改名称
当然也可能是你想做的任何事情
在我们的例子中，它只是打印出了名称
所以我们来看看从Python中创建一个集合
这也是通过data.collections来完成的
那麽D.collections
我们来看看，我们有什麽 new函数
所以我们输入new{
你可以看到你可以输入"name"
现在我们有了一个新的集合，叫做"demo"
你想使用这个集合，因为它是给你的
因为现在可以在bpy.data.collections(‘demo’) 找到它。
这种情况会发生在我们中的每个人身上
每个人都会有错别字，不用担心
鉴于demo这个名字，我们可以得到这个集合
而这是一个很大的陷井，你可能会陷入其中
因为你可能认为您刚刚创建的名为 DEMO 的集合名为 DEMO
我们再来看看当我们再做一次会发生什麽
完全一样的函数调用
只是告诉Blender给我做一个新的集合叫Demo
但是这一次，我们已经有一个叫Demo的集合了
正如我所说，集合必须有一个唯一的名字
那麽会发生什麽
它调用一个"Demo.001"，实际上是从Blender中使用的
但是现在我们要求Blender给这个集合起的名字
和当初给这个集合起的名字不一样
所以如果你现在使用bpy.data.collection['demo']
你会看到你得到的当然是demo，而不是"demo.001"
所以我想说的是
当你创建一个新的集合时，一定要给它分配一个名字
象这样
这样你就确定你的集合是正确的
之后你可以更改名称
比如"collections.name="sfa"，它就会有新的名称
在Outliner中你可能会注意到一件事
那就是，这个名字不在那里，就象集合还不存在一样
所以它存在于Blender文档中，它存在于内存中
但还没有链接到场景主集合
那我们怎麽做呢？
你去到主集合
然后输入"."并按tab键，就可以得到里面所有的东西的列表
你会注意到一件事，那就是这个叫做Children的属性
那包含了所有的Child集合
这就是所有被链接到这个集合中的集合
所以，我们来看看那里
在那里，你会发现一个叫Link的函数
在这个集合作为这个集合的子集，它有点隐晦
两次这个集合指的是不同的东西
但是我想你应该明白了吧
我们在Collection这个名字里有了我们的集合
所以在我按回车键的时候，你的眼睛要盯着Outliner
就有了
现在，它是场景集合的一部分
将对象链接到这个新的集合中
和将其他集合链接到这个新的集合是一样的
你用的是".children.link"，而不是用".object.link"
所以，让我们来看看
我们有了我们的集合
它有一个空的对象集
里面什麽也没有
我们可以使用"collection.object.link"来链接一个对象
就这样，我们可以把Suzanne.003添加到里面
让我们把这个放到一个有点象脚本的地方
所以我要在这里把窗口分开
改成文本编辑器，创建你的脚本
把它叫做move_stuff.py，总是以"bpy"开头
现在我们假设
我们想把一个集合里面的东西都搬到另一个集合里面去
所以我们必须有一个
coll_from=bpy.data.collection['collection 1']
然后我们有一个类似的东西
coll_to=bpy.data.collection['SFA']
所以现在我们有了两个集合
让我们对1进行循环
然后把所有找到的对象添加到另一个集合中
所以，for ob in coll_from.object:
coll_to.objects.Link(ob)
这样就已经把一个集合中的所有对象都链接到了另一个集合中
剩下的是要移动的，就是要从其他集合中解开链接
所以我们需要从"coll_from"中解开链接
但这也意味着要从"coll_from.objects"中删除这个对象
所以，这就意味着
通过解除链接，我们就改变了当前正在循环的那个东西
这不是一个好主意
你不应该这样做
在最好的情况下，它将是不可预测的
最坏的情况下
它会让Blender崩溃，你会失去数据
对此，最简单的解决办法，有很多
但最简单的办法就是记录你要解开链接的对象
所以说要解开链接的对象是一个空列表
而在这个列表中，我们要记录下我们以后要解绑的对象
所以我们可以说，to_unlink.append(ob)
而一旦这个For循环完成
我们就可以在这个上面解开循环，解开所有的东西
所以 for ob in to_unlink:
coll_from.objects.unlink(ob)
这样就可以了
我们来试一试
当然，我的脚本运行失败了
我们来看看控制台
如果我们看看从我启动Blender的终端
你可以看到它给了我一个运行时错误
对象Suzanne.003已经在集合SFA中
有道理
它不喜欢我们链接一个已经在里面的对象
基本上有两种方法可以避免你的脚本因为这样的错误而崩溃
一种是一开始就避免错误
另一种是在错误发生时处理错误
我认为在这种情况下
最简单的方法就是修正错误
确保我们的脚本在发生错误时继续运行
错误说的是第8行是问题所在
所以我们来看看第8行
所以第8行是代码中的这一行
它delinking了
当然，这当然会出错
你可以告诉 Python 试试这一行，看看会发生什麽
从字面上看，你说try
然后用一个冒号，就象我们看到的For循环
和"If"和其他的东西一样
在一个列中，你必须缩进其余的部分
这表明它需要尝试什麽
然后当我们看终端的时候
我们看到运行时的错误就在这里
这就是异常的类型
我就不细说了，至於这一切意味着什麽
只要知道你必须在这里输入就可以了
所以说，如果在这个try脚本中出现异常
这个类型的异常，那麽就在这里运行这段代码
而在我们的例子中，这就很好
当这个对象已经在集合中
这意味着我们很高兴
因为我们想把它链接到那里，它已经在那里了
所以一切都很好，所以我们可以让这个"pass"
也就是字面上的意思，只要在那里键入"pass"就可以了
这就告诉Python
这里不要做任何事情，不要理会这个错误
什麽都没有发生
当然，接下来的这一行还是很重要的
因为我们还是要处理这个，虽然对象移动了
链接出了问题，因为它已经在那里了
它仍然需要从原来的集合中解开链接
所以我们就可以继续往前走了
而这个应该就能解决我们的代码问题了
让我们试一试
就这样，所有的对象都已经搬到了SFA中
已经从Collection 1中拿走了
当然，我们还可以做相反的事情
我们可以说，把名字翻转一下，再运行一次脚本
然后它们又回到了开始的地方
所以，这就是你如何在Collection之间移动对象
最后我们还可以做一件事，这可能有点没用
但只是给大家做个演示
我们还可以删除我们移动的集合
那就是bpy.data.collections.remove(coll_from)
让我们再翻转一下
我们将所有的对象从collection 1中移动到SFA
然后一旦完成后，我们删除Collection 1
就这样，我们就这样做了
现在，Collection 1已经消失了
所有的对象都被再次移动了
这就是Python中的集合的工作方式
为了结束这一集，让我们再来看看 Outliner
有一些你可以设置的toggles，比如显示toggles
让我们来看一看
如果我想改变这个集合的窗口喧染
可以看到在用户首选项中的点和工具提示中可以激活
可以看到bpy.data.collection.SFA.hide_viewport
就是我们要切换的东西
下面我们来看看那里
我们取D.collections['SFA'].hide_
那里已经有了
Hide Render、Hide Select、Hide Viewport
你可以把它们设置为"True"
再设置为"False"，然后你就可以玩这个了
它几乎可以实现你所期望的点击图标的功能
就这样了
如果你有什麽问题，请留下评论
我们下期视频再见