DXライブラリとC言語でゲーム制作。今回はシェイプキーの設定について。表情の変化をさせたい場合などに。
シェイプキーの設定をしたい
シェイプキーとはオブジェクトの形状を記憶する機能のこと。これを使うことで表情の変化などができるようになる。シェイプキーを利用する場合当然ながらBlenderなどの3Dモデリングソフトなどで作成する必要がある。
作成したシェイプキーを確認する場合はDxLibModelViewerを開き、「シェイプ」タブから確認する。No.*の横の名前が各シェイプキーの名前。有効率のバーを動かすことで変化を確認できる。
コード上でシェイプキーを設定する場合はまず MV1SearchShape() で設定したいシェイプキーの番号を取得する。
宣言:int MV1SearchShape(int MHandle, char *ShapeName);
引数:int MHandle モデルのハンドル
char *ShapeName 検索するシェイプキーの名前
戻り値:0以上 指定名のシェイプキーの番号
-2 指定名のシェイプキーが見つからなかった
-1 エラー発生
そして MV1SetShapeRate() で指定のシェイプキーの設定をする。
宣言:int MV1SetShapeRate(int MHandle, int ShapeIndex, float Rate);
引数:int MHandle モデルのハンドル
int ShapeIndex 有効率を設定するシェイプキーの番号
float Rate 適応率(0.0f~1.0f)
戻り値:0 成功
-1 エラー発生
シェイプキーによる形状変化は処理が重めなのでスマホ・低スペックのPC(ゲーミング向けではない通常のノートパソコン)の場合は注意。
実装
それでは実装。今回はプレイヤーモデルにある任意のシェイプキーの有効率を変化させてみる。
まずDefine.hにシェイプキーの有効率変化パターンの列挙体を追加する。
Define.h
//シェイプの有効率の変化パターン列挙体 typedef enum { SHAPE_NONE, //シェイプの有効率をデフォルト(0)にする SHAPE_PLAY, //シェイプの有効率を1.0fに近づける SHAPE_REVERSE, //シェイプの有効率を0.0fに近づける SHAPE_STOP //シェイプの有効率の更新を止める }ShapeChangeType; extern ShapeChangeType shapechangetype;
続いてPlayerの構造体にシェイプキー関連の変数を追加する。
Player.cpp
//プレイヤーの構造体 typedef struct { //以下を追加 float ShapeRate; //シェイプキーの有効率 int ShapeChangeMode; //シェイプキーの有効率変化タイプ }player_t;
追加した変数の初期化を書き加える。
//初期化 void Player_Initialize() { //中略 //シェイプキーの有効率初期化 player.ShapeRate = 0.0f; //シェイプキーの有効率変化パターンの初期化 player.ShapeChangeMode = SHAPE_NONE; }
そしてシェイプキーの設定をする関数を追加する。
//シェイプキーの設定 void Player_ShapeChange() { int ShapeIndex = -2; //指定のシェイプの番号をモデル中から検索する ShapeIndex = MV1SearchShape(player.ModelHandle, "(設定したいシェイプキーの名前)"); //指定のシェイプキーがあれば適応率を変更する if (ShapeIndex >= 0) { //適応率を変更 switch (player.ShapeChangeMode) { case SHAPE_NONE: player.ShapeRate = 0; break; case SHAPE_PLAY: player.ShapeRate += 0.1f; break; case SHAPE_REVERSE: player.ShapeRate -= 0.1f; break; case SHAPE_STOP: break; default: break; } //ShapePlayFlagの切り替え if (player.ShapeRate > 1.0f) { player.ShapeRate = 1.0f; player.ShapeChangeMode = SHAPE_REVERSE; } else if (player.ShapeRate < 0) { player.ShapeRate = 0; player.ShapeChangeMode = SHAPE_NONE; } //シェイプキーの適応率を設定 MV1SetShapeRate(player.ModelHandle, ShapeIndex, player.ShapeRate); } } //シェイプキーの更新 void Player_Shape() { //エンターキーが押されたらシェイプキーの設定開始 if (Input_GetKeyboardDown(KEY_INPUT_RETURN)) { player.ShapeChangeMode = SHAPE_PLAY; } if (player.ShapeChangeMode > SHAPE_NONE) Player_ShapeChange(); } //更新 void Player_Update() { //中略 //シェイプキーの設定をする関数を最後に追加 Player_Shape(); }
キーボードのEnterキーが押されたら指定のシェイプキーの有効率の設定を開始。0.0fから有効率を増やしていき、1.0fになったら今度は減少させ、0.0fになったら設定を終了する。
シェイプキーの番号の取得について、DxLibModelViewerを見れば番号はわかるのだがシェイプキーを追加するたびに番号がずれるためシェイプキーの名前から検索して取得する方がずれを気にしなくていいので楽。
最後にPlayer.hに今回追加した関数を加える。
Player.h
//以下を追加 void Player_ShapeChange(); void Player_Shape();