【教程】口型速切控制器(腳本分享)

相信很多動畫綁定師都有做過用控制器來控制 blendshape。在涉及到多個(gè)口型 blendshape 的時(shí)候,尤其是 AEIOU 這種同類口型時(shí),經(jīng)常就是其中一個(gè)拉到 1,另外幾個(gè)拉到 0,K 的數(shù)量多了就不免有些繁瑣。于是我想了個(gè)辦法用一個(gè)控制器來控制多個(gè)同類口型。?

首先確定一下最終效果:我想要中間的控制器回到圓心時(shí),所有的 blendshape 為 0,當(dāng)控制器從中心移動到某個(gè)字母上時(shí),那個(gè)字母對應(yīng)的 blendshape 為 1,其余為 0。當(dāng)控制器從一個(gè)字母移動到另一個(gè)字母時(shí),這兩個(gè) blendshape 之間也會混合。?

一個(gè)控制器控制多個(gè)BlendShape
我這里使用 blender 來實(shí)現(xiàn),并配合 python 來做一些批處理工作。后文我將用 blender 里的 shapekey 來稱呼 blendshape。?
?
?
前置知識:?
Blender 基礎(chǔ)知識?
驅(qū)動器使用經(jīng)驗(yàn)?
一點(diǎn)點(diǎn) Python 基礎(chǔ)?
向量和三角函數(shù)相關(guān)數(shù)學(xué)基礎(chǔ)?
?
?
1、準(zhǔn)備一個(gè)帶有 shapekey 的模型;?
?
2、創(chuàng)建控制器(可根據(jù)自己的情況自定義):?

1)創(chuàng)建一個(gè)圓環(huán)作為整個(gè)控制器的父級;?
2)創(chuàng)建一個(gè)任意形狀的物體作為主要控制器,并將其作為圓環(huán)的子級(無反向),置于圓環(huán)的原點(diǎn);?

3)創(chuàng)建一個(gè)名叫 DriverSources 的集合,將主要控制器添加到該集合中;(提示:在控制器的“物體”選項(xiàng)卡中的“集合”折疊欄中操作)?
4)根據(jù)實(shí)際情況創(chuàng)建多個(gè) 3D 文字物體,一一對應(yīng)要控制的 shapekey ,并作為圓環(huán)的子級(無反向),均勻排列到圓環(huán)上;?

5)創(chuàng)建一個(gè)名叫 DriverTargets 的集合,將所有 3D 文字添加到該集合中;?

3、編寫 Python 腳本:?
1)切換到 Scripting 界面,新建文本;?
2)復(fù)制我的提供的腳本添加到文本編輯器;?

3)在大綱視圖展開 shapekey 物體數(shù)據(jù)塊下的網(wǎng)格數(shù)據(jù)塊,查看 shapekey 數(shù)據(jù)塊的名稱,并將該名稱賦給腳本第 7 行的 shape_key 變量?


4)在左邊的控制臺輸入:?
targets = bpy.data.collections["DriverTargets"].objects?
for obj in targets:?
????print(obj.name)?
?
敲兩下回車運(yùn)行腳本,根據(jù)打印出來的結(jié)果(即 DriverTargets 集合里所有物體的名稱),在腳本第 8 行的數(shù)組里“按順序”一一填入對應(yīng)的 shapekey 名稱(不是物體名稱);?

5)點(diǎn)擊運(yùn)行腳本按鈕;?
至此應(yīng)該出效果了。?

?
import bpy # 引入Blender的Python模塊
import math # 引入數(shù)學(xué)模塊
import mathutils # 引入數(shù)學(xué)實(shí)用工具模塊
?
# 獲取DriverTargets和DriverSources集合下的物體列表
targets = bpy.data.collections["DriverTargets"].objects
sources = bpy.data.collections["DriverSources"].objects
# 獲取ShapeKey名稱和其所包含的KeyBlocks列表
shape_key = ""
key_blocks = []
?
# 自定義驅(qū)動器函數(shù)
def drive_shape(index):
??? d = min(sources[0].location.length / targets[index].location.length, 1.0)
??? a = sources[0].location.normalized()
??? b = targets[index].location.normalized()
??? angle = a.dot(b)
??? angle = min(max(angle,-1.0),1.0)
??? angle = math.asin(angle)/math.pi*2
??? angle = (angle-1.0)/4*len(targets)+1.0
??? angle = angle*d
??? return angle
?
# 將自定義函數(shù)添加到驅(qū)動器命名空間
bpy.app.driver_namespace["drive_shape"] = drive_shape
?
# 對于每個(gè)Key
for i in range(len(key_blocks)):
??? # 清除舊有的驅(qū)動器,并添加新的驅(qū)動器
??? bpy.data.shape_keys[shape_key].key_blocks[key_blocks[i]].driver_remove("value")
??? fc = bpy.data.shape_keys[shape_key].key_blocks[key_blocks[i]].driver_add("value")
???
??? # 添加變量
??? var1 = fc.driver.variables.new()
??? var1.name = "src_scale"
??? var1.type = "SINGLE_PROP"
??? var1.targets[0].id = sources[0]
??? var1.targets[0].data_path = "scale[0]"
???
??? # 書寫表達(dá)式
??? fc.driver.expression = "drive_shape(%d)" % i
【教程】口型速切控制器(腳本分享)的評論 (共 條)
