リジッドボディ同士がぶつかった時に、
火花が散るというアニメーションを作ってみましょう。
また今回のスクリプトを応用すれば、火花の代わりに衝突時に穴を開けたり、へこみを作ることもできるようになります。
最初のスクリプトの火花は小さくて見にくいかもしれません。
それはパーティクルのアトリビュートを適切に設定していないからです。
それらのアトリビュートの設定は練習問題で行ないます。
また、衝突した後、火花がずっと出続ける問題も練習問題で解決しましょう。
なお、今回のスクリプトはプロシージャが 2 つ含まれているので注意して作ってください。
global proc makeSpark1()
{
string $gra[] = `gravity -m 9.8`;
polySphere;
move 1 10 1;
rigidBody -active;
connectDynamic -f $gra[0];
polyPlane;
scale 20 1 20;
rotate 0 0 -45;
string $rb = `rigidBody -passive`;
expression -o $rb -s ("makeEmitter1(\"" + $rb + "\", contactCount)");
setAttr rigidSolver.contactData 1;
}
global proc makeEmitter1(string $rigidbody, int $contval)
{
if($contval > 0)
{
string $pp[] = `rigidBody -q -contactPosition $rigidbody`;
string $pos[];
tokenize $pp[0] $pos;
string $emi[] = `emitter -pos $pos[0] $pos[1] $pos[2]`;
string $pname[] = `particle`;
connectDynamic -em $emi[0];
setAttr ($pname[1] + ".particleRenderType") 6;
setAttr ($pname[1] + ".lifespanMode") 2;
setAttr ($pname[1] + ".lifespanRandom") 0.5;
setAttr ($pname[1] + ".lifespan") 5;
}
}
import maya.cmds
def makeSpark1():
gra = maya.cmds.gravity(m=9.8)
maya.cmds.polySphere()
maya.cmds.move(1, 10, 1)
maya.cmds.rigidBody(active=True)
maya.cmds.connectDynamic(f=gra[0])
maya.cmds.polyPlane()
maya.cmds.scale(20, 1, 20)
maya.cmds.rotate(0, 0, -45)
rb = maya.cmds.rigidBody(passive=True)
maya.cmds.expression(o=rb, s=('python("makeEmitter1(\'' + rb + '\', " + contactCount + ")")'))
maya.cmds.setAttr('rigidSolver.contactData', 1)
def makeEmitter1(rigidbody, contval):
if contval > 0:
pp = maya.cmds.rigidBody(rigidbody, q=True, contactPosition=True)
pos = pp[0].split()
emi = maya.cmds.emitter(pos=(pos[0], pos[1], pos[2]))
pname = maya.cmds.particle()
maya.cmds.connectDynamic(em=emi[0])
maya.cmds.setAttr((pname[1] + '.particleRenderType'), 6)
maya.cmds.setAttr((pname[1] + '.lifespanMode'), 2)
maya.cmds.setAttr((pname[1] + '.lifespanRandom'), 0.5)
maya.cmds.setAttr((pname[1] + '.lifespan'), 5)
(注意)
再度プレイバックする場合は衝突によって作られたパーティクルとエミッターを消去しておいてください。
import maya.cmds
def makeSpark1():
gra = maya.cmds.gravity(m=9.8)
maya.cmds.polySphere()
maya.cmds.move(1, 10, 1)
maya.cmds.rigidBody(active=True)
maya.cmds.connectDynamic(f=gra[0])
maya.cmds.polyPlane()
maya.cmds.scale(20, 1, 20)
maya.cmds.rotate(0, 0, -45)
rb = maya.cmds.rigidBody(passive=True)
maya.cmds.expression(o=rb, s=('python("makeEmitter1(\'' + rb + '\', " + contactCount + ")")'))
maya.cmds.setAttr('rigidSolver.contactData', 1)
def makeEmitter1(rigidbody, contval):
if contval > 0:
pp = maya.cmds.rigidBody(rigidbody, q=True, contactPosition=True)
pos = pp[0].split()
emi = maya.cmds.emitter(pos=(pos[0], pos[1], pos[2]))
pname = maya.cmds.particle()
maya.cmds.connectDynamic(em=emi[0])
maya.cmds.setAttr((pname[1] + '.particleRenderType'), 6)
maya.cmds.setAttr((pname[1] + '.lifespanMode'), 2)
maya.cmds.setAttr((pname[1] + '.lifespanRandom'), 0.5)
maya.cmds.setAttr((pname[1] + '.lifespan'), 5)
セレクトされたオブジェクトの名前を調べるには maya.cmds.ls(sl=True) 関数を使用します。
ここでは、maya.cmds.ls(sl=True) によって 2 つのオブジェクト名が返ります。
objs = maya.cmds.ls(sl=True)
と実行することによって
objs[0]
に最初にセレクトされたオブジェクト名、
objs[1]
に 2 番目にセレクトされたオブジェクト名が代入されます。
(maya.cmds.ls(sl=True) 関数は makeSpark2 関数の最初で実行してください)
後は、1 つ目の rigidbody 関数の直前で objs[0] を maya.cmds.select() 関数でセレクトし、
2 つ目の rigidbody() 関数の直前で objs[1] を同じように select() 関数でセレクトしておきます。
lineWidth, tailSize, tailFade はダイナミックアトリビュートなので
addAttr() 関数でパーティクル pname[1] にアトリビュートを追加してやる必要があります。
addAttr() 関数を使用する場合に必要なフラグは以下の通りです。
現在のフレーム番号を知るには、以下の関数を使用します。
maya.cmds.currentTime(q=True)
この関数を使用して衝突時のフレーム番号を調べ、
そのフレーム番号より何フレームか後にエミッターの rate アトリビュートを 0 にしてください。
そのためには、エミッターにエクスプレッションを設定して、
ぶつかった時のフレーム番号から何フレーム後かをチェックして、
アトリビュート(rate)を 0 にします。