トップページ > 記事閲覧
アニメーションについて
名前:アライス 日時: 2018/05/12 21:58

サンプルプログラム 3Dアクション基本を元にプログラムを組んでいるのですが、アニメーション がうまく動きませんどうしたらいいでしょうか。 ご教授お願いいたします。 とりあえずキャラクターの向きとかは考えずアニメだけ動かそうとしているのですが、走りモーションの走り出し?で止まったまま移動してしまいます。 以下プログラムになります。 #include <math.h> #include "DxLib.h" void Input_Process( void ) ; void Player_PlayAnim( int PlayAnim ) ; void Player_AnimProcess( void ) ; struct PADINPUT { int NowInput ; // 現在の入力 int EdgeInput ; // 現在のフレームで押されたボタンのみビットが立っている入力値 } ; //プレイヤーの構造体 struct Player{ int Model; int AnimIndex; int AttachIndex; int move; int Jump; VECTOR Position; float TotalTime; float PlayTime; float AnimBledRate; int PlayAnim1; float AnimPlayCount1; int PlayAnim2; float AnimPlayCount2; float AnimBlendRate; int State; }; //ステージの構造体 struct Stage{ int Model; }; //カメラの構造体 struct Camera{ VECTOR Eye; VECTOR Target; float AngleH; float AngleV; }; Player pl; Camera ca; Stage st; PADINPUT inp; // 入力処理 void Input_Process( void ) { int Old ; // ひとつ前のフレームの入力を変数にとっておく Old = inp.NowInput ; // 現在の入力状態を取得 inp.NowInput = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; // 今のフレームで新たに押されたボタンのビットだけ立っている値を EdgeInput に代入する inp.EdgeInput = inp.NowInput & ~Old ; } void Player_PlayAnim( int PlayAnim ) { // 再生中のモーション2が有効だったらデタッチする if( pl.PlayAnim2 != -1 ) { MV1DetachAnim(pl.Model, pl.PlayAnim2 ) ; pl.PlayAnim2 = -1 ; } // 今まで再生中のモーション1だったものの情報を2に移動する pl.PlayAnim2 = pl.PlayAnim1 ; pl.AnimPlayCount2 = pl.AnimPlayCount1 ; // 新たに指定のモーションをモデルにアタッチして、アタッチ番号を保存する pl.PlayAnim1 = MV1AttachAnim( pl.Model, PlayAnim,-1,FALSE ) ; pl.AnimPlayCount1 = 0.0f ; // ブレンド率は再生中のモーション2が有効ではない場合は1.0f( 再生中のモーション1が100%の状態 )にする pl.AnimBlendRate = pl.PlayAnim2 == -1 ? 1.0f : 0.0f ; } // プレイヤーのアニメーション処理 void Player_AnimProcess( void ) { float AnimTotalTime ; // 再生しているアニメーションの総時間 // ブレンド率が1以下の場合は1に近づける if( pl.AnimBlendRate < 1.0f ) { pl.AnimBlendRate += 0.1f ; if( pl.AnimBlendRate > 1.0f ) { pl.AnimBlendRate = 1.0f ; } } // 再生しているアニメーション1の処理 if( pl.PlayAnim1 != -1 ) { // アニメーションの総時間を取得 AnimTotalTime = MV1GetAttachAnimTotalTime( pl.Model, pl.PlayAnim1 ) ; // 再生時間を進める pl.AnimPlayCount1 += 1.0f ; // 再生時間が総時間に到達していたら再生時間をループさせる if( pl.AnimPlayCount1 >= AnimTotalTime ) { pl.AnimPlayCount1 = fmod( pl.AnimPlayCount1, AnimTotalTime ) ; } // 変更した再生時間をモデルに反映させる MV1SetAttachAnimTime( pl.Model, pl.PlayAnim1, pl.AnimPlayCount1 ) ; // アニメーション1のモデルに対する反映率をセット MV1SetAttachAnimBlendRate( pl.Model, pl.PlayAnim1, pl.AnimBlendRate ) ; } // 再生しているアニメーション2の処理 if( pl.PlayAnim2 != -1 ) { // アニメーションの総時間を取得 AnimTotalTime = MV1GetAttachAnimTotalTime( pl.Model, pl.PlayAnim2 ) ; // 再生時間を進める pl.AnimPlayCount2 += 1.0f ; // 再生時間が総時間に到達していたら再生時間をループさせる if( pl.AnimPlayCount2 > AnimTotalTime ) { pl.AnimPlayCount2 = fmod( pl.AnimPlayCount2, AnimTotalTime ) ; } // 変更した再生時間をモデルに反映させる MV1SetAttachAnimTime( pl.Model, pl.PlayAnim2, pl.AnimPlayCount2 ) ; // アニメーション2のモデルに対する反映率をセット MV1SetAttachAnimBlendRate( pl.Model, pl.PlayAnim2, 1.0f - pl.AnimBlendRate ) ; } } int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) { // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // ライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; //プレイヤーの初期化 pl.Position = VGet(0.0f,0.0f,0.0f); pl.Model = MV1LoadModel("Lat式ミク/DxChara.x"); pl.move = 0; MV1SetPosition(pl.Model,pl.Position); MV1DrawModel(pl.Model); pl.PlayAnim1 = -1; pl.PlayAnim2 = -1; pl.State = 0; //ステージの初期化 st.Model = MV1LoadModel("Lat式ミク/ColTestStage.mqo"); //カメラの初期化 MATRIX RotZ, RotY; ca.AngleH = DX_PI_F / 2 * 3; ca.AngleV = 0.0f; //アニメーション初期化 Player_PlayAnim(4); //ESCAPEキーが押されるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { ClearDrawScreen(); Input_Process() ; pl.move = 0; //カメラの処理 if(CheckHitKey(KEY_INPUT_LEFT) == 1) { ca.AngleH -= 0.1f; if(ca.AngleH < -DX_PI_F) ca.AngleH -= DX_TWO_PI_F; } if(CheckHitKey(KEY_INPUT_RIGHT) == 1) { ca.AngleH += 0.1f; if(ca.AngleH > DX_PI_F) ca.AngleH += DX_TWO_PI_F; } if(CheckHitKey(KEY_INPUT_UP) == 1) { ca.AngleV -= 0.1f; if(ca.AngleV < -DX_PI_F / 2 + 0.1f) ca.AngleV = -DX_PI_F / 2 + 0.1f; } if(CheckHitKey(KEY_INPUT_DOWN) == 1) { ca.AngleV += 0.1f; if(ca.AngleV > DX_PI_F / 2 - 0.1f) ca.AngleV = DX_PI_F / 2 - 0.1f; } //キャラの移動 if(CheckHitKey(KEY_INPUT_A) == 1) { pl.Position.x += 20.0f; pl.move = 1; } if(CheckHitKey(KEY_INPUT_S) == 1) { pl.Position.x -= 20.0f; pl.move = 1; } if(CheckHitKey(KEY_INPUT_W) == 1) { pl.Position.z -= 20.0f; pl.move = 1; } if(CheckHitKey(KEY_INPUT_SPACE) == 1 && pl.Jump != 1 && pl.Jump != 2) { pl.Jump = 1; } if(pl.Jump == 1) { if(pl.Position.y <= 8.0f) { if(pl.Position.y >= 8.0f) { pl.Jump = 2; } pl.Position.y += 1.0f; } } if(pl.Jump == 2) { pl.Position.y -= 0.8f; if(pl.Position.y <= 0.0f) { pl.Position.y = 0.0f; pl.Jump = 0; } } if(pl.move) { if(pl.State == 0) { Player_PlayAnim(1); pl.State = 1; } } else { if(pl.State == 1) { Player_PlayAnim(4); pl.State = 0; } } //アニメーション処理 // プレイヤーに新たなアニメーションを再生する Player_AnimProcess() ; /*if(pl.move == 1) { MV1DetachAnim(pl.Model,pl.AttachIndex); pl.AttachIndex = MV1AttachAnim(pl.Model,1,-1,FALSE); pl.TotalTime = MV1GetAttachAnimTotalTime(pl.Model,pl.AttachIndex); } if(pl.move == 0) { MV1DetachAnim(pl.Model,pl.AttachIndex); pl.AttachIndex = MV1AttachAnim(pl.Model,4,-1,FALSE); pl.TotalTime = MV1GetAttachAnimTotalTime(pl.Model,pl.AttachIndex); } if(pl.Jump == 1 || pl.Jump == 2) { MV1DetachAnim(pl.Model,pl.AttachIndex); pl.AttachIndex = MV1AttachAnim(pl.Model,5,-1,FALSE); pl.TotalTime = MV1GetAttachAnimTotalTime(pl.Model,pl.AttachIndex); } MV1SetAttachAnimTime(pl.Model,pl.AttachIndex,pl.PlayTime);*/ /*ca.Target = VAdd(pl.Position,VGet(0.0f,400.0f,0.0f )); // 水平方向の回転はY軸回転 RotY = MGetRotY( ca.AngleH ); // 垂直方向の回転はZ軸回転 ) RotZ = MGetRotZ( ca.AngleV ); ca.Eye = VAdd(VTransform(VTransform(VGet(-1600.0f,0.0f,0.0f), RotZ), RotY),ca.Target); SetCameraPositionAndTarget_UpVecY(ca.Eye, ca.Target); MV1SetPosition(pl.Model,pl.Position); MV1DrawModel(pl.Model); MV1DrawModel(st.Model); ScreenFlip(); } //ライブラリの後始末 DxLib_End(); //ソフトの終了 return 0; }
メンテ

Page: 1 |

Re: アニメーションについて ( No.1 )
名前:newGene 日時:2018/05/12 22:30

もう1つの掲示板からの続きです。 @もう1つの掲示板バージョンからなぜか変更されている部分を元に戻す pl.AnimPlayCount1 += 1.0f ---> += 250.0f; pl.AnimPlayCount2 += 1.0f ---> += 250.0f; Aもう1つの掲示板にコメントした部分がまだ追加されていないので追加 while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { の下あたりに // ルートフレームのZ軸方向の移動パラメータを無効にする /// { MATRIX LocalMatrix; // ユーザー行列を解除する MV1ResetFrameUserLocalMatrix(pl.Model, 2); // 現在のルートフレームの行列を取得する LocalMatrix = MV1GetFrameLocalMatrix(pl.Model, 2); // Z軸方向の平行移動成分を無効にする LocalMatrix.m[3][2] = 0.0f; // ユーザー行列として平行移動成分を無効にした行列をルートフレームにセットする MV1SetFrameUserLocalMatrix(pl.Model, 2, LocalMatrix); } を追加 ClearDrawScreen(); Input_Process(); ... B下から20行目あたり、なぜかコメントになりかけていてビルドできないので修正  /*ca.Target = VAdd(pl.Position,VGet(0.0f,400.0f,0.0f ));  を  ca.Target = VAdd(pl.Position,VGet(0.0f,400.0f,0.0f ));
メンテ
Re: アニメーションについて ( No.2 )
名前:アライス 日時:2018/05/12 22:42

ご指摘いただきありがとうございます。 無事にアニメーションが動くようになりました。 今後はもう少し考えてプログラムを組もうと思います。
メンテ
Re: アニメーションについて ( No.3 )
名前:アライス 日時:2018/05/14 14:37

// ルートフレームのZ軸方向の移動パラメータを無効にする /// { MATRIX LocalMatrix; // ユーザー行列を解除する MV1ResetFrameUserLocalMatrix(pl.Model, 2); // 現在のルートフレームの行列を取得する LocalMatrix = MV1GetFrameLocalMatrix(pl.Model, 2); // Z軸方向の平行移動成分を無効にする LocalMatrix.m[3][2] = 0.0f; // ユーザー行列として平行移動成分を無効にした行列をルートフレームにセットする MV1SetFrameUserLocalMatrix(pl.Model, 2, LocalMatrix); } についてなのですが、具体的にはどういった処理をしているんでしょうか? 知識不足ですいません。どなたかご回答をお願いいたします。
メンテ
Re: アニメーションについて ( No.4 )
名前:newGene 日時:2018/05/14 19:12

まず、キャラ+アニメーションデータであるDxChara.xを確認してみましょう。 DxLib正式版を展開するとDxLib Model Viewerがありますので、それにドラッグ&ドロップします。 アニメーションをクリックし、アニメーション一覧のNo.1 Hashiri Countをクリックし、 再生速度を15000くらいにセットし、再生をスタートします。するとキャラが手前に走り出しますが、 しばらくすると元の位置に戻ってループします。 このように、このアニメーションデータは手足を振るだけでなく、実際に場所を移動します。 しかしプログラムを組むうえで、場所(座標)はプログラムで制御するので、移動はして欲しくない ということがあります。つまり、ルームランナー状態でいてほしいのです。 移動方向は奥行き(Z方向)なので、アニメーションでZ方向に移動させないように例の処理をしている、 ということになります。
メンテ
Re: アニメーションについて ( No.5 )
名前:アライス 日時:2018/05/15 12:25

返信ありがとうございます。 つまり、元のアニメーションではZ方向に移動しているものを 移動させずにモーションのみ描画しているということでしょうか。 あとDxLib正式版とあるのですがどちらでダウンロードしればよろしいのでしょうか。 質問ばかりですいません・・・
メンテ
Re: アニメーションについて ( No.6 )
名前:newGene 日時:2018/05/15 19:43

「DxLib正式版」と書きましたが、要はDXライブラリのダウンロードページにある 「DXライブラリ Windows版」のことです。(現在はVer. 3.19b) VC版で148MB ちなみになぜ正式版と書いたかというと、こっちの掲示板では、バグ修正や機能追加をした「Temp版(?)」が たまに貼り付けられますが、それにはツール類は(ほとんどの場合)含まれていないので、正式なダウンロード ページでダウンロードしてください、という意味です。 とはいえ「サンプルプログラム 3Dアクション基本」をビルドできているということはすでに(多少古くても) ダウンロード済だと思いますので、その中から Tool --> DxLibModelViewer を探してください。 アニメーションについてはその認識でOKです。(実際にあの部分を削ってビルド・実行し、キャラを 移動させてみると、わかってもらえると思います)
メンテ
Re: アニメーションについて ( No.7 )
名前:アライス(解決) 日時:2018/05/16 16:03

分かりやすい回答をしていただきありがとうございます。 少しずつではありますが、ゲームを完成まで作りたいと思います。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存