MENU閉じる

HEXA BLOG

デザイン

HEXA BLOGデザイン2022.8.10

TA と リギング

こちらに記事を書くのはこれで11回目となります。
テクニカルアーティスト Ritaro です。

TAにとって開発上の問題点を解くのに技術的な引き出しを色々持っておくことが必要、
について・・また少し紹介したいと思います。

今回からは、アニメーション周りの対応 についてです。

元々、キャラクターを動かすのに必要な技術的なサポートを
多く扱って来た事もあって モーションTA でもありますが、
平たく言うと ”動くものなんでも” を対応するになります。

この ”動くものなんでも” とは、
例えば UnrealEngine5 の対応 と一言で言い表している内容は、
キャラクターを動かす SkeletalMesh や Animation Montage、CharactorBluePrint からはじまり、FBX、Alembic などのデータ系 やPivotPainter や VertexAnimationTexture などシェーダー系で動かせるもの、映像を作成したり書き出したり出来る Sequencer の対応まで、もの凄く幅広く ”動くものなんでも”  対応になりますので、対応するノウハウも 本当に多岐 にわたります。

その中でも、”今回は UnrealEngine5 のキャラクターの Joint を Mayaで扱いたい
場合の対応を取り上げたいと思います。

では、さっそく・・

ちょっと具体的な、面白い対処法、でもあったら『おお、使えるかも』
・・って思うようなものをまたご紹介していきましょう。

1)「UnrealEngine5 の Joint を Maya で扱いたい」

7月末から8月頭にかけて行われた ダイキン工業さん主催の 2022年度の CG Channel Week

blog_20220810_01

にて「ゲーム開発者視点による、Rig制作ツール mGear 4.0系の新機能紹介

blog_20220810_02
と題したオンラインセミナーの
【Part3】mGear のUE5対応について/EPIC Mannequine template Y-Up

blog_20220810_03
というパートで UnrealEngine5 と mGearのリグ との連携を解説しました。
その中で ジョイントの回転値 ジョイントの方向値 に切り替えるスクリプト
を紹介しました。
今回はこのあたりの話をします。

そのオンラインセミナーでも述べたように、
UnrealEngine5 では、サンプルキャラクターとして、所謂マネキンさん(Manequine)は、
従来より少し小柄なキャラクターデータ SKM_Quinn が用意されています。

blog_20220810_04
この SKM_Quinn では従来のマネキンさんより ジョイント数が多く なっていまして、
手の甲にある骨(中手骨;Meta骨)などの ジョイントが追加されています。
blog_20220810_05
いずれの Manequineキャラクターの ジョイントを
FBX形式で書き出してMayaに持って来ますと、
ジョイントの回転値に値が入っている状態でMayaに表示されます。

blog_20220810_06
UnrealEngine5内にあるキャラクターが既にこのSkeletonに
アニメーションが設定されていてそれを利用したい、
またはこのジョイントにキャラクターセットアップ(SkinBind)
されたデータにMayaからアニメーションを作成したい場合、
Maya側の対応として発生する作業として再度SkinBindすることが予想されますが、
出来れば避けたい作業です。

そこで、この部分の対応として紹介したのが、
Maya上でスクリプトを使ってJointの回転値をジョイントの方向値に入れ替える  だったのです。

blog_20220810_07
ちなみに、ジョイントの回転値(例えば Z=0.Y=30,Z=0)のFBXと
ジョイントの方向値(例えば Z=0.Y=30,Z=0)のFBXは
UnrealEngine5にインポートすると どちらも同じ回転値のボーン表示になります。

では、スクリプトの解説ですが、実は何てこと無いんです。
キャラクターデータを階層選択してジョイントだけのリストを作成し、

joint_list = []

for node in selected_object:
    if cmds.objectType( node ) == 'joint':
        joint_list.append(node)

そのジョイントの数分だけ
cmds.getAttr( .rotateX、.rotateY、.rotateZ)
で回転値を取得して
cmds.setAttr( .jointOrientX、.jointOrientY、.jointOrientZ)
でジョイントの方向値に得た回転値を代入する、

for o_joint in joint_list:
    o_joint_r_x = cmds.getAttr(o_joint + ".rotateX")
    if o_joint_r_x > -0.000999 and o_joint_r_x < 0.000999:
        pass
    else:
        cmds.setAttr(o_joint + ".jointOrientX", o_joint_r_x)
        cmds.setAttr(o_joint + ".rotateX",0)

だけだったのです。
知ってしまえば凄いことを行っているわけではありません。

でも、たったこれだけのスクリプトでも
GUI化してメニューとしてボタンを押せば実行出来るように用意してあげれば
アニメーターがワークフローに取り入れてもらえやすくなると思います。
しかも SkinBind の作業はなくなります。

今回は ジョイントの 回転値(rotate)  を  ジョイントの方向値(jointOrient)
にするスクリプトでしたが、逆も簡単ですね。

blog_20220810_20

といったところで、今回はここまで。

また次回も、アニメーション周り について紹介が出来たらと思っております。

ではでは。

*–
Ritaro

Rotation > Orientation   サンプルスクリプト

import maya.cmds as cmds
import maya.mel as mel 


def do_rotation_to_orient(*args): 
    if not cmds.ls( sl=True ): 
        cmds.confirmDialog( title='ERROR', message='Select Joint !_! ') 
        sys.exit()

    o_selected = cmds.ls(sl=True)[0] 
    mel.eval('string $o_selected = "%s"' % o_selected) 
    top_obj = mel.eval('string $robj = `rootOf( $o_selected )`;' ) 
    cmds.select(top_obj,r=True) 
    cmds.select(hierarchy=True) 
    selected_object = cmds.ls(sl=True) 
    cmds.select( clear=True ) 

    joint_list = [] 

    for node in selected_object: 
        if cmds.objectType( node ) == 'joint': 
            joint_list.append(node) 

    for o_joint in joint_list: 
        o_joint_r_x = cmds.getAttr(o_joint + ".rotateX") 
        if o_joint_r_x > -0.000999 and o_joint_r_x < 0.000999:
            pass
        else: 
            cmds.setAttr(o_joint + ".jointOrientX", o_joint_r_x)  
            cmds.setAttr(o_joint + ".rotateX",0)  
        o_joint_r_y = cmds.getAttr(o_joint + ".rotateY")  
        if o_joint_r_y > -0.000999 and o_joint_r_y < 0.000999: 
            pass
        else: 
            cmds.setAttr(o_joint + ".jointOrientY", o_joint_r_y)  
            cmds.setAttr(o_joint + ".rotateY",0)  
        o_joint_r_z = cmds.getAttr(o_joint + ".rotateZ")  
        if o_joint_r_z > -0.000999 and o_joint_r_z < 0.000999: 
            pass 
        else: 
            cmds.setAttr(o_joint + ".jointOrientZ", o_joint_r_z) 
            cmds.setAttr(o_joint + ".rotateZ",0) 

do_rotation_to_orient() 

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE