モーション

 形状モデル(.sig)のキャラクターには、複数のモーションをつけることが出来ます。
モーションというのはキャラクターが走ったりパンチしたり踊ったりするような、キャラクターに動作をつける機能のことです。
シューティング系やレース系ではこの機能がなくてもそれほど困りませんが、アクション系ゲームでは必須の機能です。
Easy3Dではhgimgよりもより細かなモーションの設定ができるようになっています。

 さて、ほんとうは前回hgimgでゲーム作ったときもモーション使わなかったから今回もモーションなしで行こう。と思っていたのですが、 以外に簡単に使えそうだというのが分かってきたので、せっかくだしあったらあったでカッコいいので使ってみようと思います。
まずは使ってみることからはじめることにします。データ作成に関しては今回はパスします。


モーションデータ

 モーションデータの作成には、モーションをつける形状データ(sig)が必要です。
メタセコイア等のソフトを使って作って下さい。この辺の説明は今回パスです。

 キャラクターの形状モデル(sigファイル)をRokDeBone2(おちゃっこさんのサイトで 配布されています)で読み込んでモーションを付けていきます。
作成したモーションデータのファイルはquaファイルとして出力されます。

 モーションの再生は、プログラム中で用意したsigファイルと作成したquaを読み込んで行ないます。 quaファイルにはモーションデータ(動きの情報)のみが入っており、形状データは入っていないので モーションデータ(qua)を読み込むには必ずsigファイルが必要になります。
また、モーションデータは特定の形状データ専用のものではなく、うまく作ればほかの形状データでも 流用できるようにもできるようです。この辺の調整はモーションデータと形状データ両方で調整が必要だと思いますが。
 モーションデータはquaファイルのほかにmotファイルも対応しているそうですが、何の形式かわかりません。 そのうち調べておきます。(とりあえず今回は使用しないので気にしない。(^_^;)


 さて、形状データの作成やモーションのつけ方はパスしましたが、この辺についてはすでに解説されているサイトがあります。
データ作成については既存の解説サイトをご利用ください。
とりあえず1つサイトをあげておきます。

tomoさんのサイト「3DCGゲームを作ろう!」(http://treasurehunt.cocolog-nifty.com/blog/)
blog形式でデータの作成からモーションまで掲載されています。ほかにも3DCGゲーム作成に関する情報が掲載されています。

 この他にもメタセコの解説サイトはたくさんありますし、Easy3Dのモーションに関するサイトもいくつかあります。
おちゃっこLAB(Easy3D公式サイト)のリンクをたどっていけばあるていど見つかると思います。探してみてください。


サンプル解説

モーションサンプル  今回は形状データ1つと複数のモーションデータを使用します。
使用するデータはEasy3Dのmediaファイル内にある次のファイルです。サンプルのasファイルと同じフォルダ内に dataフォルダを作成し、この中にコピーしておいてください。
・ni_parts_6_bone.sig
・ni_parts4_idling.qua
・ni_parts4_punch.qua
・ni_parts4_kick.qua
・ni_parts4_act1.qua
・ni_parts4_defense.qua
・ni_parts4_win.qua
・ni_parts4_final.qua

あとはサンプルをコピーして実行するだけです。
ファイルは格ゲーなサンプルで使われている猫妹のモデルデータとモーションデータです。


キー入力操作と対応するモーション内容は次の通り。
入力キーモーション
Zパンチの後に回転(途中から)
Xキック
C回転
Vしゃがんだ後に同じモーションを巻き戻して立ち上がる
B勝利のポーズ
Nノックアウト
ZとV以外は普通に再生してるだけなので、最初はX,C,B,Nのどれかに注目してください。なれたらZ,Vへ行きましょう。

なお、各アクション再生前・再生後は待機状態用に設定したモーションが実行されるようになっています。


データの準備

まずはいつものようにE3DSigLoadで形状データを読み込みます。
次にE3DAddMotionでモーションデータを読み込みます。

E3DAddMotion hsid, fname, mk3, maxframe

hsidに読み込むモーションを適用するモデルのidを指定します。さっきE3DSigLoadで読み込んだデータのidですね。
mkにはモーションデータのIDが返ります。今後はこのモーションを扱うときはこのIDを使用します。
maxframeには読み込んだモーションの最大フレーム番号が返ります。 フレーム番号は0から始まるので、総フレーム数-1になります。 (例えば総フレーム数3コマのモーションならフレーム番号ははじめから順に0,1,2となっている。このときmaxframeには2が返ります。)


モーションの設定

 モーションの再生方法をいろいろと指定できます。
今回はE3DSetMotionTypeでしゃがむ動作をしたあとに巻き戻し再生で 立ち上がる動作をさせています。
またE3DSetNextMotionFrameNoでパンチのモーションが終了後、 くるくる回転するモーション(途中から)が再生されるようにしています。
ほかにもいろいろできると思いますが、今回はこんなところです。
詳細はマニュアルを見てください。


説明不足

 このへんでモーションファイルに何が入っているかや、モーションファイルと形状データの関係を概念だけでも書いておくべきでしょう。
しかし…めんどくさいので省略です。あくまで資料作成が目的のコンテンツだし…。(←言い訳^_^;;)
ということなので説明不足な部分は習うより慣れろで習得してください。
どこか解説してくれてるサイトないかな…。


サンプル

 サンプルを置いているフォルダにdataフォルダを作成してください。
上で説明した猫妹のsigとquaファイルをdataフォルダにコピーしてください。


;
;	モーションの再生
;

#include "e3dhsp.as"

	;/////////////////
	;
	;	初期化
	;
	E3DInit
	mes "Now loading..."
	dim keybuf, 256

	;file のpath 用のバッファーの作成
	sdim mediadir, 2048
	mediadir = curdir + "\\data"
	sdim pathbuf, 2048


	;/////////////////
	;
	;	ライトの設定
	;
	E3DCreateLight lid1		;光源を作成
	lightdirx1 = 1		;平行光の向き
	lightdiry1 = -1
	lightdirz1 = 0
	lightr1 = 255	;平行光の色
	lightg1 = 255
	lightb1 = 255
	E3DSetDirectionalLight lid1, lightdirx1, lightdiry1, lightdirz1, lightr1, lightg1, lightb1	;光源を平行光源に設定

	;/////////////////
	;
	;	カメラの初期化
	;
	camposx = 0 : camposy = 2000 : camposz = 4200
	E3DSetCameraPos camposx, camposy, camposz	;カメラ座標を設定
	targetx = 0		;注視点座標
	targety = 1000
	targetz = 0
	upvecx = 0		;カメラの上方向のベクトル
	upvecy = 1
	upvecz = 0
	E3DSetCameraTarget targetx, targety, targetz, upvecx, upvecy, upvecz	;カメラの注視点を設定

	;/////////////////
	;
	;	形状データのロード
	;
	;猫妹データのロード
	pathbuf = mediadir + "\\ni_parts_6_bone.sig"
	E3DSigLoad pathbuf, hsid1


	;/////////////////
	;
	;	モーションデータのロード
	;
	pathbuf = mediadir + "\\ni_parts4_idling.qua"
	E3DAddMotion hsid1, pathbuf, mk1_idling, max1_idling
	pathbuf = mediadir + "\\ni_parts4_punch.qua"
	E3DAddMotion hsid1, pathbuf, mk1_punch, max1_punch
	pathbuf = mediadir + "\\ni_parts4_kick.qua"
	E3DAddMotion hsid1, pathbuf, mk1_kick, max1_kick
	pathbuf = mediadir + "\\ni_parts4_act1.qua"
	E3DAddMotion hsid1, pathbuf, mk1_act1, max1_act1
	pathbuf = mediadir + "\\ni_parts4_defense.qua"
	E3DAddMotion hsid1, pathbuf, mk1_defense, max1_defense
	pathbuf = mediadir + "\\ni_parts4_win.qua"
	E3DAddMotion hsid1, pathbuf, mk1_win, max1_win
	pathbuf = mediadir + "\\ni_parts4_final.qua"
	E3DAddMotion hsid1, pathbuf, mk1_final, max1_final

	E3DSetMotionType hsid1, mk1_defense, 4	;しゃがむ動作のあと巻き戻しで立ち上がる。
	E3DSetNextMotionFrameNo hsid1, mk1_punch, mk1_act1, 20	;パンチのあとに回転アクション

	E3DSetMotionKind hsid1, mk1_idling
	posx1 = 0 : posy1 = 0 : posz1 = 0
	degx1 = 0 : degy1 = 180 : degz1 = 0
	E3DSetPos hsid1, posx1, posy1, posz1
	E3DSetDir hsid1, degx1, degy1, degz1


;/////////////////
;
;	メインループ
;
*main
	E3DGetKeyboardState keybuf
	if keybuf.VK_ESCAPE = 1 : goto *bye ; [ESC]で終了

	gosub *MoveCamera	;カメラ移動
	gosub *PlayMotion	;モーションの再生

	E3DChkInView hsid1	;モデルが、視野内にあるか判定
	E3DBeginScene	;-----シーンスタート
		;バックバッファへの書き込み作業を行う
		E3DRender hsid1, 0, frameno1, 0
		E3DRender hsid1, 1, frameno1, 0
		E3DDrawText 20,20, 1, 255,255,255, "Hit 'Z'or 'X', 'C', 'V', 'B', 'N' key."
	E3DEndScene		;-----シーン終了
	E3DPresent		;バックバッファの内容を、プライマリバッファに転送。描画する。
	E3DWaitbyFPS 30 : await 0
goto *main


;/////////////////
;
;	終了処理
;
*bye
	E3DDestroyLight lid1	;ライトを破棄
	E3DBye
	end


;/////////////////
;
;	カメラ調整操作
;
*MoveCamera
	;注視点移動
	if keybuf.VK_LEFT = 1  : targetx += 20
	if keybuf.VK_RIGHT = 1 : targetx -= 20
	if keybuf.VK_UP = 1    : targety += 20
	if keybuf.VK_DOWN = 1  : targety -= 20
	;カメラ位置移動(接近と離れる)
	if keybuf.'Q' = 1 : camposz += 20
	if keybuf.'W' = 1 : camposz -= 20

	E3DSetCameraPos camposx, camposy, camposz	;カメラ座標を設定
	E3DSetCameraTarget targetx, targety, targetz, 0, 1, 0
	return


;/////////////////
;
;	モーションの再生
;
*PlayMotion
	E3DSetNewPose hsid1	;カレントのモーションを進ませる。

	frameno1 = stat		;次に再生するフレーム番号
	if keybuf.'Z' = 1 : E3DSetMotionKind hsid1, mk1_punch	;パンチ+回転アクション
	if keybuf.'X' = 1 : E3DSetMotionKind hsid1, mk1_kick	;キック
	if keybuf.'C' = 1 : E3DSetMotionKind hsid1, mk1_act1	;回転アクション
	if keybuf.'V' = 1 : E3DSetMotionKind hsid1, mk1_defense : fdef=1	;しゃがむ
	if keybuf.'B' = 1 : E3DSetMotionKind hsid1, mk1_win		;勝利のポーズ
	if keybuf.'N' = 1 : E3DSetMotionKind hsid1, mk1_final	;ノックアウト

	E3DGetMotionKind hsid1, curmk1	;カレントのモーション番号
	newmk1 = curmk1
	;各モーションの終了
;	if (curmk1 = mk1_punch)&(frameno1 >= max1_punch) : 	newmk1 = mk1_idling	この行はパンチのみのとき有効にする。
	if (curmk1 = mk1_kick)&(frameno1 >= max1_kick) : 	newmk1 = mk1_idling
	if (curmk1 = mk1_act1)&(frameno1 >= max1_act1) : 	newmk1 = mk1_idling
	if (curmk1 = mk1_defense)&(frameno1 >= max1_defense)&(fdef=1) : fdef = 0
	if (curmk1 = mk1_defense)&(frameno1 <= 0)&(fdef=0) : newmk1 = mk1_idling
	if (curmk1 = mk1_win)&(frameno1 >= max1_win) : 		newmk1 = mk1_idling
	if (curmk1 = mk1_final)&(frameno1 >= max1_final) : 	newmk1 = mk1_idling
	if newmk1 != curmk1 : E3DSetMotionKind hsid1, newmk1	;モーションを変更
	return





- HOME -

GHP(仮)