11 月 23 2008
PV3Dでレースゲーム制作 21 - 車のモーション
車のモデルをちゃんと作ります。直方体のままじゃあまりにも…なので。
今回はキャラクターとか乗り物に必要な、「パーツごとの動き」を追加してみました。
モデリング
モデリングは Lightwave 3D Modeler を使いました。
3Dオブジェクトを階層化
車モデルをそのまま1つの COLLADA で読み込むと、タイヤの回転とかが再現できません。
そこで、動かしたいパーツごとにモデルを分割して、ActionScript 側でインスタンスを再構成することで個別のモーションに対応させます。ちょうど Sprite を addChild で階層化して個別2Dアニメーションさせるのと同じようなやり方で、3Dオブジェクトも制御できちゃいます。
具体的にやりたいことは次のとおり。
- 荷重移動でカウルが動く
- 車の速度に応じてタイヤが回転する
- 操作に合わせて前輪が左右に動く
- 影は固定
- 車全体がセットで移動する
最低限これくらいやっとけば車っぽく見えるでしょう。テールランプがあってもよかったけど。
というわけでパーツ分割は、カウル・タイヤ・影の3つなりました。
これらを包括した DisplayObject3D を作り、車全体が一緒に移動できるようにします。さらに前輪は、回転しながら左右に動かないといけないので、ここも階層化する必要がありそうです。
*DisplayObject3D は Collada のスーパークラスです。
シーン : Scene3D
+-コース : Collada
+-車 : DisplayObject3D
+-カウル : Collada
+-前輪 : DisplayObject3D
+-タイヤ : Collada
+-前輪 : DisplayObject3D
+-タイヤ : Collada
+-後輪 : DisplayObject3D
+-タイヤ : Collada
+-タイヤ : Collada
+-影 : Collada
ソース。
//宣言---------------------------------------------------------------//
private var _scene:Scene3D;
private var _carObject:DisplayObject3D;
private var _cowl:Collada;
private var _tireFL:DisplayObject3D;
private var _tireFR:DisplayObject3D;
private var _tireR:DisplayObject3D;
private var _tire:Collada;
private var _shadow:Collada;
(略)
//カウル-------------------------------------------------------------//
//マテリアル
var cowlMaterials:Object = new Object();
cowlMaterials = {
tx_front_jpg:new BitmapMaterial(txCarBitmap1.bitmapData),
tx_side_jpg:new BitmapMaterial(txCarBitmap2.bitmapData),
tx_back_jpg:new BitmapMaterial(txCarBitmap3.bitmapData),
tx_under_png:new BitmapMaterial(txCarBitmap4.bitmapData)
};
//オブジェクト
_cowl = new Collada( cowlXML, new MaterialsList(cowlMaterials) );
//タイヤ-------------------------------------------------------------//
//マテリアル
var tireMaterials:Object = new Object();
tireMaterials = {
tx_tire_jpg:new BitmapMaterial(txTireBitmap.bitmapData)
};
//オブジェクト
_tireFL = new DisplayObject3D();
_tire = new Collada( tireXML, new MaterialsList(tireMaterials) );
_tireFL.addChild(_tire, "tire");
_tireFL.x = -730;
_tireFL.y = 310;
_tireFL.z = 1280;
_tireFR = new DisplayObject3D();
_tire = new Collada( tireXML, new MaterialsList(tireMaterials) );
_tireFR.addChild(_tire, "tire");
_tireFR.x = 730;
_tireFR.y = 310;
_tireFR.z = 1280;
_tireR = new DisplayObject3D();
_tire = new Collada( tireXML, new MaterialsList(tireMaterials) );
_tire.x = -730;
_tireR.addChild(_tire);
_tire = new Collada( tireXML, new MaterialsList(tireMaterials) );
_tire.x = 730;
_tireR.addChild(_tire);
_tireR.y = 310;
_tireR.z = -1100;
//影-----------------------------------------------------------------//
//マテリアル
var shadowMaterials:Object = new Object();
shadowMaterials = {
tx_shadow_png:new BitmapMaterial(txShadowBitmap.bitmapData)
};
//オブジェクト
_shadow = new Collada( shadowXML, new MaterialsList(shadowMaterials) );
//車-----------------------------------------------------------------//
_carObject = new DisplayObject3D();
_carObject.addChild(_cowl);
_carObject.addChild(_tireFL);
_carObject.addChild(_tireFR);
_carObject.addChild(_tireR);
_carObject.addChild(_shadow);
//3D登録-------------------------------------------------------------//
_scene.addChild(_carObject);
あとは車の動きに合わせて、各パーツの x, y, z, rotationX, rotationY, rotationZ あたりを操作してやればOK。この辺は理屈よりも「らしく見えるか」というセンスの問題にもなってきますね。微調整には試行錯誤しました。
デモ
» ゲームをプレイする (要:Flash Player 9.0.124.0以降)
1周走るか、ドライブ中に[C]キーを押すと、三人称カメラになって車の挙動を確認できます。
