【maya python8限目】コーンをらせん状に配置して、先端をlocatorに向けよう!

mayapy08 python入門

こんにちは!ビーバー@ゲーム業界歴約20年 です。maya python初心者の方のために、カンタン・わかりやすい解説サイトを作っています。

maya pythonの学習情報って少ないですよね。自分が骨を折った経験をもとに、maya python基礎を最速で習得できる10回のチュートリアルを作ってみたので参考にしていただければ幸いです。

今回は、8回目。手作業でやると時間がかかってしまう「らせん状の配置」について、スクリプトから一発で行う方法を紹介します。スクリプトは一度書くと、何度でも使えるのでとても便利ですよ!

このチュートリアルでわかること
  • らせん状の配置をスクリプトから行う方法
  • setAttr, Duplicate, parent コマンドの使い方
  • 複数のオブジェクトにconstraintを一括でかける方法

>> はじめての方向けMayaPythonの勉強方法はこちら!

※当サイトで紹介する商品は、アフィリエイトプログラムを利用しています。

コーンをらせん状に配置して、先端をlocatorに向ける

画像のようなシーンを使って進めていきます。

  • 原点にlocator1
  • その子供にpCone1
  • Y=20にlocator2 を配置
mayapy08_01

このシーンでコーンをらせん状に配置し、コーンの先端がY=20のlocator2を向くようにします。
下記のスクリプトを実行。

cone = "pCone1"
for i in range(15):
    cmds.setAttr("locator1.ry",i*45)
    cone2 = cmds.duplicate(cone)
    cmds.parent(cone2,w=True)
    cone2 = cone2[0]
    cmds.setAttr(cone2+".ty",i*1)
    
meshes = cmds.ls(type="mesh")
conetranses = cmds.listRelatives(meshes,allParents=True)

for trans in conetranses:
    aimcon = cmds.aimConstraint("locator2",trans,offset=(0,0,-90))
    cmds.delete(aimcon)
mayapy08_02
スクリプトの実行結果
ピヨちゃん
ピヨちゃん

おお~!一発でらせん状に配置された!

ハムちゃん
ハムちゃん

今回はちょっとスクリプトが長いね。解説に入る前に、
どのようなアプローチでコーンのらせん状配置を実現するか考えてみよう

解説

何かのモデルやモーションを作る時と同じで、
最初にどのような作り方をするか段取りを考えたうえで、スクリプトを書いていきます。
今回は以下のような段取りにしました。

コーンを原点にあるlocator1の子供にする

  • locator1を45度回転
  • コーンをduplicate、ペアレント解除
  • コーンの位置を上へずらす(処理がすすむにつれ、より高い位置にずらしていく)
  • この処理を繰り返す


最後に、コーンをまとめてlocator2に aimコンストレインする

これらを12行のスクリプトにしています。

スクリプトの構造

スクリプトの挙動を1行ずつ確認していきましょう。

行数   スクリプト    処理内容                    
1行目cone = “pCone1”pCone1を変数coneに代入
2行目for i in range(15):以下の処理を15回繰り返す。
iには0~14が入る
3行目␣␣␣␣cmds.setAttr(“locator1.ry”,i*45)locator のtyの値にi*45を代入
4行目␣␣␣␣cone2 = cmds.duplicate(cone)pCone1を複製してcone2に代入
5行目␣␣␣␣cmds.parent(cone2,w=True)cone2のペアレントを解除
6行目␣␣␣␣cone2 = cone2[0]cone2がリスト型になっているので
要素を取り出してcone2に代入
7行目␣␣␣␣cmds.setAttr(cone2+”.ty”,i*1)cone2のtyの値にi*1を代入
8行目meshes = cmds.ls(type=”mesh”)メッシュを取得してmeshesに代入
9行目conetranses = cmds.listRelatives(meshes,allParents=True)meshesの親のtransformノードを取得、
conetransesに代入
10行目for trans in conetranses:conetransesの要素に対して以下を実行
11行目␣␣␣␣aimcon = cmds.aimConstraint(“locator2”,trans,offset=(0,0,-90))locator2の方向に向くように
aimコンストレインを実行
12行目␣␣␣␣cmds.delete(aimcon)コンストレインノードを削除
ハムちゃん
ハムちゃん

それでは詳しく処理を見ていこう!

4行目:pCone1を複製してcone2に代入

ピヨちゃん
ピヨちゃん

1~3行は限目の内容だから、4行目からで大丈夫だよ!

ハムちゃん
ハムちゃん

オッケ~!じゃあ質問です。
4行目は複製したコーンをcone2に代入しています、どうしてでしょう?

行数   スクリプト    処理内容                    
4行目cone2 = cmds.duplicate(cone)pCone1を複製してcone2に代入
ピヨちゃん
ピヨちゃん

5行目以降でcone2に対して処理するから、、かな?

ハムちゃん
ハムちゃん

そうだね。4行目はfor文に入っていて、繰り返される処理なんだ。
pCone1は、合計15回duplicateされて、
複製されたコーンの名前は「pCone2~16」になるから、
名前が変わっても、以降の処理に対応できるように変数にしておくんだよ。

5行目:cone2のペアレントを解除

ここではcone2をペアレント解除して、ワールド直下にしています。

行数   スクリプト    処理内容                    
5行目cmds.parent(cone2,w=True)cone2のペアレントを解除

初出のコマンド parent() について見ていきましょう。

parent

その名の通り、ノード同士の親子付けを行うコマンドです。
()内の書き方を解説します。

cmds.parent(“子供にしたいオブジェクト”、”親になるオブジェクト”、フラグ=〇〇)

オブジェクト名は 文字列 で指定します。
例)cmds.parent( “locator1” , “pCube1” )

ハムちゃん
ハムちゃん

フラグ「w」は「world」の省略版、ワールドにペアレント化するフラグだよ。

6行目:リストの要素を取り出してcone2に代入

行数   スクリプト    処理内容                    
6行目cone2 = cone2[0]     cone2がリスト型になっているので
要素を取り出して改めてcone2に代入

ここではcone2[0]とすることで、リストから要素を取り出しています。

ピヨちゃん
ピヨちゃん

リストからの要素取り出しは、たしか5限目でやったなあ。。
ここはcone2のままじゃダメなの?

ハムちゃん
ハムちゃん

次の行でsetAttrを実行したいけど、
cone2はリスト型になってしまっているから、そのままでは実行できないんだよ。

ピヨちゃん
ピヨちゃん

次の行で処理ができるように、リストからあらかじめ取り出しておくんだね。

cone2の中身を確認してみましょう。
最初のシーンに対して、スクリプトの3~5行目のみを実行し、cone2をハイライト+実行します。

mayapy08_01
最初のシーン
scriptEditor
スクリプトの3~5行目のみを実行し、cone2をハイライト+実行

赤枠で示したように、[‘pCone2’]が返ってきました。[ ]に入っているので、リスト型になります。

cone2 = cone2[0] を実行してから、もう一度cone2を実行すると、、

scriptEditor

pCone2 と、[ ]が外れ、リストの中の要素を取り出すことができました。
次の行からは、この単体の要素に対して処理を行っていくのです。

7行目:cone2のtyの値にi*1を代入

行数   スクリプト    処理内容                    
7行目cmds.setAttr(cone2+”.ty”,i*1)   cone2のtyの値にi*1を代入
ピヨちゃん
ピヨちゃん

さっきのリストから取り出したコーンのtyに、setAttrで値を設定しているね。

ここも内容的には問題ないよ!

ハムちゃん
ハムちゃん

だいぶ慣れてきたね!
ちなみにここまでが2行目のfor文の処理だ。

for文で行っている処理はこの通りです。

  • locator1を45度ずつ回転
  • コーンをduplicate、ペアレント解除
  • コーンの位置を上へずらす(処理がすすむにつれ、より高い位置にずらしていく)
  • この処理を繰り返す

次の行からが、コーンをまとめてlocator2にaimコンストレインする処理になります。

8行目:メッシュを取得してmeshesに代入

行数   スクリプト    処理内容                    
8行目meshes = cmds.ls(type=”mesh”)メッシュを取得してmeshesに代入

ここではコーンを取得するために、typeフラグでメッシュのノードをシーンから探して、
変数meshesに代入しています。

ピヨちゃん
ピヨちゃん

lsコマンドのフラグの書き方はわかるんだけど、
mesh、みたいなノードのタイプ名ってどうやって調べるの?

ハムちゃん
ハムちゃん

lsコマンドのshowTypeフラグで調べることができるよ。

タイプ名の調べ方

cmds.ls(type=”○○”)のタイプ名(文字列)は、
lsコマンドのshowTypeフラグで調べることができます。

例えば、シーンのpCone2を選択して、下記のスクリプトを実行

print(cmds.ls(selection=True,showType=True))
scriptEditor

赤枠のように、[ノード名 , タイプ名] が返ってきます。

9行目:コーンのtransformノードを取得、conetransesに代入

行数   スクリプト    処理内容                    
9行目conetranses = cmds.listRelatives(meshes,allParents=True)meshesの親のtransformノードを取得、
conetransesに代入

meshesの中身はshapeノードのため、
その親のtransformノードを取得して変数conetransesに入れています。

ピヨちゃん
ピヨちゃん

親のtransformノードを取得しているのは、あとでaimコンストレインをかけたいからだね
親を取得するコマンドがlistRelativesかな?

ハムちゃん
ハムちゃん

そのとおり!

listReratives()

このコマンドでは、ノードの親や子を返してくれます。

cmds.listReratives(ノード名”,フラグ=〇〇)

「allParents」フラグは親を返すフラグです。

10行目:aimコンストレインを実行

行数   スクリプト    処理内容                    
10行目for trans in conetranses:     conetransesの要素に対して以下を実行
ピヨちゃん
ピヨちゃん

10行目は
listRerativesで取得した、複数のtransformノードに対して処理を行う、だね!

ハムちゃん
ハムちゃん

10行目も大丈夫だね。じゃあ11行目行ってみよう!

11行目:aimコンストレインを実行

行数   スクリプト    処理内容                    
11行目aimcon = cmds.aimConstraint(“locator2”,trans,offset=(0,0,-90))locator2の方向に向くように
aimコンストレインを実行

ここでは、conetranses のうちの一つの要素である trans
(中身はpCone*のトランスフォームノード)がlocator2の方向を向くように、
オフセット値を入れてaimコンストレインをかけています。

ピヨちゃん
ピヨちゃん

コマンドの名前はaimConstraint()、これは分かりやすいなあ

aimConstraint()

コマンド名の通り、エイムコンストレインを行うコマンドです。

cmds.listReratives(“コンストレインする側ノード名” , “される側ノード名” , フラグ=〇〇)

フラグはoffsetを指定しています。
フラグの書き方をヘルプで探すと、、引数タイプが[float, float, float]
これはどのように書けばよいのでしょうか?

mayaヘルプより
ハムちゃん
ハムちゃん

これはGUIからオプション設定するときの書き方と同じと考えると簡単だよ

aimConstraint_Option
ピヨちゃん
ピヨちゃん

そうか、赤枠のオフセット値と同じように書けばいいんだね!

あと、11行目では「コンストレイン実行」をaimconという変数に入れています。

aimcon = cmds.aimConstraint("locator2",trans,offset=(0,0,-90))

これはすなわち、コンストレインノードが「aimcon」に代入されているのです。

Outliner
ハムちゃん
ハムちゃん

コンストレインノードはこれだね!

12行目:コンストレインノードを削除

行数   スクリプト    処理内容                    
12行目cmds.delete(aimcon)      コンストレインノードを削除

「11行目で作成したコンストレインノード」を削除しています。

実行

ハムちゃん
ハムちゃん

それではドキドキの瞬間!スクリプトを実行しよう!

cone = "pCone1"
for i in range(15):
    cmds.setAttr("locator1.ry",i*45)
    cone2 = cmds.duplicate(cone)
    cmds.parent(cone2,w=True)
    cone2 = cone2[0]
    cmds.setAttr(cone2+".ty",i*1)
    
meshes = cmds.ls(type="mesh")
conetranses = cmds.listRelatives(meshes,allParents=True)

for trans in conetranses:
    aimcon = cmds.aimConstraint("locator2",trans,offset=(0,0,-90))
    cmds.delete(aimcon)
mayapy08_02
スクリプトの実行結果
ピヨちゃん
ピヨちゃん

できたよー!スクリプトの中身もちゃんとわかったよ!

まとめ

今回学習した内容のポイントをまとめます。

学習のポイント
  1. setAttr,Duplicate,parentなどを組み合わせて、オブジェクトを規則的に配置する
  2. リストから要素を抜き出して処理する
  3. ノードタイプは lsコマンドの showTypeフラグで調べることができる
  4. listRelativesコマンドを使って、親ノードを取得する
  5. aimConstraintコマンドで、方向コンストレインを設定する
ハムちゃん
ハムちゃん

ここまで勉強してきたことを組み合わせてみたよ!

次回は、作成したスクリプトをファイルに保存して、別のシーンから使ってみる、
という内容を解説します。お楽しみに!

maya python基礎

😊 MayaでPythonを学びたい方へ

「ツールを作ってみたいけど、何から始めたらいいんだろう?」そんな方のために、超初心者向けのチュートリアル全10回をまとめました👇
https://kimstation.com/maya-python-summary/

こんなことが、最短で身につきます👇

  • Pythonの知識ゼロから始められる
  • シンプルなUIつきのツールを自分で書けるようになる
  • Mayaコマンドの基礎や、ツールづくりの基本がわかる

「ツールづくりに挑戦したい」という方に向けて、必要最低限の知識だけをしぼってやさしくまとめてます😊ツールを自分で作れるようになると、すごく楽しいですよ~!

オススメの本。pythonが楽しく学べます☆

復習はこちら↓

コメント

タイトルとURLをコピーしました