大家好，歡迎來到本期藝術家的腳本的教程視頻
我的名字是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"，然後你就可以玩這個了
它幾乎可以實現你所期望的點擊圖標的功能
就這樣了
如果你有什麼問題，請留下評論
我們下期視頻再見