チュートリアル / プラグインを作ってみよう!ゲーム開発のためのツール製作講座
第7回:Softimage編 アニメーション、スキニング、シェイプ、カスタムパラメータの取得

  • ゲーム
  • コラム
  • スクリプト・API
  • チュートリアル
  • 上級者
  • 中級者
ここまででスキニングとシェイプの情報が取得できました。ここからは残る最後の要素であるカスタムパラメータについて説明していきます。カスタムパラメータはゲーム開発でDCCツールを使う上で避けては通れない大変重要な要素です。

一般的なゲーム開発用のコンテンツパイプラインでは「ゲーム特有のパラメータ」の設定が必要になります。このパラメータを設定する方法は大きく分けて2つあります。
●ゲームエンジン上で設定する方法
●DCCツール上で設定する方法

最初の「ゲームエンジン上で設定する方法」ではDCCツールとは別のゲームエンジン上でデータを読み込んでそちらでパラメータを設定します。大規模なゲーム開発や、ミドルウェアを使用した開発でよく使われます。こちら方法はDCCツールに一切依存しないというメリットがありますが、当然エディタとして使えるゲームエンジンが必要になります。

一方の「DCCツール上で設定する方法」はDCCツールの機能を使ってゲーム用のパラメータを追加します。既存のDCCツールに対してパラメータを追加することになるので、DCCツール側の仕様に激しく依存します。またDCCツールによって実現方法が異なってくるので、ツールごとに個別の対応が必要になってしまいます。ツール間のデータコンバートのときも問題なるでしょう。とはいえDCCツールだけでパラメータの設定を完結できるので、ゲームエンジンが存在しない開発環境や比較的小規模なゲーム開発においては便利な方法です。今回のエクスポーターでは後者の「DCCツール上で設定する方法」を想定しています。

Softimage上でパラメータを設定する方法はいくつかありますが、以下の2つがよく使われていると思います。
●名前に埋め込む方法
●カスタムパラメータを使う方法

「名前に埋め込む方法」ではユーザーが定義したいパラメータをノードやマテリアルの「名前」に文字列として追加します。この方法は設定されているパラメータが見た目ですぐにわかるというメリットがありますが、パラメータが増えてくると名前が長くなってしまうデメリットがあります。またパラメータのアニメーションができません。この「名前に埋め込む方法」は古いやり方ですが、ツール間のデータコンバートでデータが失われにくいという隠れた長所があります。

「カスタムパラメータによる方法」ではSoftimageのカスタムパラメータという機能を使ってユーザー定義のパラメータを設定します。カスタムパラメータは任意の個数追加できるので「名前に埋め込む方法」よりも便利です。ただ残念なことにSoftimageには複数のカスタムパラメータの値を一括で編集する機能がありません。ゲーム用のパラメータは一度にまとめて変更したいことが多いので、この点は対応が必要です。別のプラグインとして、一括変換用のツールを用意すると便利でしょう。今回のエクスポーターではこの「カスタムパラメータによる方法」を採用しています。

カスタムパラメータはSoftimage上でユーザーが任意に追加することのできる変数のことです。カスタムパラメータには任意の型が使用できます。またノード、マテリアル、テクスチャ、イメージソース(画像ファイル)などに追加することができます。ここからはSoftimageのカスタムパラメータについて少し説明してから、プログラムから取得する方法を紹介します。


カスタムパラメータは「カスタムパラメータセット」と「カスタムパラメータ」から構成されます。カスタムパラメータが一つの変数に相当し、複数のカスタムパラメータを格納するための入れ物がカスタムパラメータセットです(下の画像)。


ではSoftimage上で実際にカスタムパラメータを追加してみましょう。キューブを一つ作って、メニューの「パラメータ>新規カスタムパラメータセット」を選ぶとキューブの下にカスタムパラメータセットが作られます(下の画像)。


今度は作成したカスタムパラメータセットを選択して、メニューの「パラメータ>新規カスタムパラメータ」を選びます。新規カスタムパラメータのダイアログ(下の画像)が開くので、名前や型を設定してOKボタンを押します。カスタムパラメータセットを開くと、先ほど設定したカスタムパラメータが追加されていることがわかります。カスタムパラメータセットには複数のカスタムパラメータを追加することができます。


今回はノードに追加しましたが、マテリアル、テクスチャ、画像ファイル(イメージソース)にも同様に追加することができます。


このようにカスタムパラメータはSoftimageのインターフェースから作成することができますが、毎回手動で設定するのは大変です。ゲーム開発の現場ではスクリプトを使って自動的に設定することが多いと思います。サンプルのオプション設定の部分はPythonスクリプトからカスタムパラメータ(カスタムプロパティ)を作成しています。興味のある方はソースコードを参照してください。カスタムパラメータセットは同じ場所に複数追加できますが、この場合自動的にリネームされてしまいます。スクリプトでカスタムパラメータを設定するときはこの重複に注意してください。

カスタムパラメータが追加できたので、今度はこの値をエクスポーターから取得してみましょう。最初はノードからカスタムパラメータセットを取得します。カスタムパラメータセットはPropertyの一種として格納されており、ClassIDがsiCustomPropertyIDとなっています。各クラスからClassIDがsiCustomPropertyIDとなっているPropertyを取り出して情報を取得します。
SceneItem::GetProperties()関数を使うとプロパティ一覧をCRefArrayクラスとして取得できます。

CRefArray properties = sceneItem.GetProperties();
for( int i=0; i<properties.GetCount(); i++ ) {
        Property prop = properties[ i ];
        if( prop.GetClassID() == siCustomPropertyID ) {       
                /* カスタムパラメータセットの情報を取得 */
        }
}

今回の実装ではすべてのカスタムパラメータセットを取得する実装になっていますが、一部のカスタムパラメータセットだけ取得したいこともあります。この場合は識別用のカスタムパラメータを仕込んでおくか、カスタムパラメータセットの名前で識別します。

ノードの次はマテリアルのカスタムパラメータセットを取得します。MaterialクラスはSceneItemの派生クラスではありませんが、Material::GetProperties()関数を持っているので、こちらを使います。

CRefArray properties = material.GetProperties();

今度はテクスチャのカスタムパラメータセットを取得します。TextureクラスはShaderクラスの派生クラスなので、Shader::GetProperties()から取得できます。

CRefArray properties = texture.GetProperties();

イメージソースのカスタムパラメータセットはImageClip2クラスを経由して取得します。ImageClip2::GetSource()でイメージソースに相当するSourceクラスが取得できるので、そのプロパティを取得します。

ImageClip2 imageClip;
...
Source source( imageClip.GetSource() );
CRefArray properties = source.GetProperties();

イメージソースは使用している画像ファイルと一対一対応しています。一方テクスチャはこのイメージソースを参照しているので、テクスチャの数はイメージソースの数より多くなることがあります。画像ファイル単位のパラメータはイメージソースに、テクスチャ単位のパラメータはテクスチャに設定するとよいでしょう。

ここまででカスタムパラメータセットのPropertyクラスが取得できたので、今度はその内部の格納されているカスタムパラメータの情報を取得します。カスタムパラメータからは表示用の名前とスクリプト用の名前の両方が取得できますが、今回はスクリプト用の名前を使います。

CParameterRefArray parameters = property.GetParameters();
for( int p=0; p<parameters.GetCount(); p++ ) {
        Parameter parameter = parameters[ p ];
        CString scriptName = parameter.GetScriptName();
                /* カスタムパラメータの情報を取得 */
}

カスタムパラメータセットに入っているカスタムパラメータは値の型がわからないので、最初にParameter::GetValueType()関数を使って型情報を取得します。GetValueType()関数の戻り値はCValue::DataTypeです。DataTypeには沢山の型があるので、すべてに対応するのは大変です。今回のエクスポーターではよく使いそうな型だけ対応しています。

●カラー:siColor4f:
●32ビット符号あり整数:siInt4:
●32ビット符号なし整数:siUInt4:
●実数(float):siFloat:
●倍精度実数(double):siDouble:
●ブール型:siBool
●文字列型:siString:

カスタムパラメータの型を調べた後で実際の値を取得します。型ごとの値の取得方法はサンプルのソースを参照してください。 
これでエクスポーターに必要なすべての要素が取得できました。最後にエクスポーター作成のコツについて補足したいと思います。

Softimageのプラグイン開発を行う場合、Softimage自体の操作方法を習得しておくと開発効率が大幅に上がります。そもそも基本的な操作を覚えておかないと自分が作成したプラグインのテストすら行えません。プラグインのテストのたびにアーティストにテストデータを作ってもらっていては時間の無駄です。エクスポーターを作るのならば以下の操作はできるようになっておきましょう。

●カメラの移動(基本的なショートカットを覚える)
●ポリゴンメッシュの作成
●マテリアルの設定(クラスターを使った複数マテリアルの割り当て含む)
●レンダーツリーを使った質感設定(環境マップ、法線マップ含む)
●UVの設定(複数のUV座標を別々のテクスチャに設定するなど)
●頂点カラーのペイント
●スキニングの設定(ウェイトの編集含む)
●シェイプの作成
●簡単なアニメーションの作成

エクスポーターを作ってリリースすると大量のバグ報告が上がってきます。実際のゲーム開発の現場では、小さいデータでテストしているときは起こらなかった不具合が次々に発生します。またアーティストはこちらの想像をはるかに超えたデータを作ってしまうことがあります。

エクスポーターの不具合が発見された場合は、該当するシーンのデータをもらって調べます。ツールに詳しいアーティストは問題が起こる最小限のシーンを用意してくれますが、大抵の場合はシーンを丸ごともらって調べることになります。

ここで大事になってくるのは原因の絞り込みです。シーンをもらったら最初に余計な要素をDCCツール上で削ります。問題が起こる最小限のシーンを用意してからデバッグ作業に入りましょう。DCCツール上で要素を削っていく場合、要素を半分ずつ削っていきます。1000個のノードが入っているシーンの場合は、最初の500の要素を削除してエクスポートして問題が起こるか調べます。問題が起こった場合は残りの500の要素に原因があるので、今度はこちらを半分の250に削ります。このように半分、半分と削っていくと原因を楽に突き止めることができます。

エクスポーターなどのコンテンツパイプラインのデバッグ作業では、問題を起こしている要素を特定できれば、その後の修正はすぐに終わります。最初から目を皿にしてデバッガとにらめっこするのではなく、DCCツール上での原因の絞り込みに大半の時間を使いましょう。

以上で「プラグインを作ってみよう! ゲーム開発のためのツール製作講座」Softimage編は終了です。大変申し訳ないのですが、こちらのコラムは今回で終了となります。本来はSoftimage編の後でMaya編が続く予定でしたが、私の個人的な都合で終了とさせていただきます。ここまでお読みいただいて大変ありがとうございました。


製品購入に関するお問い合わせ
オートデスク メディア&エンターテインメント 製品のご購入に関してご連絡を希望される場合は、こちらからお問い合わせください。