前回Alternativa3D(A3D7.7)でJiglibFlashを使えるところまで行ったので、今回はキャラクタ用コリジョンを作ってみます。
最初に考えていたのは、回転しないようにした縦長のカプセルコリジョンを作って歩く方向に力を加えていくものだったんですが、実際やってみると設定が悪いせいか動くカプセルの衝突判定がなんだかおかしい。他のボックス・球・カプセルとぶつかった時にピクピクしたり簡単にすり抜けたり。設定で何とかならないか色々試してみたもののなかなか改善できなかったので、結局動くカプセルはなるべく使わないようにする事にしました。カプセル以外のコリジョンが動かないカプセルにぶつかったときは問題なかったんだけどね。
色々と試行錯誤しつつ決めたキャラクタの処理
最初に考えていたのは、回転しないようにした縦長のカプセルコリジョンを作って歩く方向に力を加えていくものだったんですが、実際やってみると設定が悪いせいか動くカプセルの衝突判定がなんだかおかしい。他のボックス・球・カプセルとぶつかった時にピクピクしたり簡単にすり抜けたり。設定で何とかならないか色々試してみたもののなかなか改善できなかったので、結局動くカプセルはなるべく使わないようにする事にしました。カプセル以外のコリジョンが動かないカプセルにぶつかったときは問題なかったんだけどね。
色々と試行錯誤しつつ決めたキャラクタの処理
- 回転しない球体コリジョンを用意する。
- 必要ならキャラクタのメッシュと連携させる。一人称視点ならコリジョンだけで。
- キー入力で前後左右に移動。ジャンプもできるようにする。
- 必要ならマウスドラッグで視点を動かす。
- キャラクタの視線ベクトルと垂直ベクトルの外積で水平横方向のベクトルを作り、そこから水平前方向のベクトルも作って前後左右の移動処理に使う。
- 視線が真上か真下を向いていると上記の計算ができなくなるので角度は制限する。
- 自分のコリジョンが周囲のコリジョンとぶつかっているか、どの角度で触れているかをチェックして、ジャンプできるか判定する。(空中や絶壁でのジャンプをさせないため)
- 摩擦があると壁に接触した状態でのジャンプが難しいため0にする。その代わり毎フレーム水平方向のみ移動量を減退させて摩擦っぽくさせる。
- 摩擦を0にした事でちょっとした坂もずるずる滑ってしまう為、足元がゆるい傾斜+接地中のみ無重力にして滑らないようにする。
つくってみた
移動 :WSAD か 矢印キージャンプ:SPACE
視点移動:マウスドラッグ

ソース(2011/4/13修正)
net.morocoshi.jiglib.a3d.A3dWalker.asを作って上にリストアップした処理をまとめたクラスにしました。ソースにはそれ以外の細々したクラスも入ってるけど。
一人称視点でカメラの向き=キャラクタの向きになってます。なんとなくそれっぽく動けてはいるんですが、接地中は無重力にしているせいかゆるい坂を少し上ってすぐ止まると勢いで一瞬浮き上がった感じになります。あと、どうしても動くオブジェクトがいろんな所にめり込んでしまって、最悪埋まったままになることも。。。でもこれはしかたないのかな。長時間めり込んでいたら位置をリセットするような処理が組めればなんとかなりそうだけど。
JiglibFlashでわかった事色々
- 動くオブジェクトで回転だけさせたくない場合はRigidBody.maxRotVelocities = 0
- オブジェクトを動かすにはRigidBody.addWorldForce(力ベクトル,加える位置)
- addWorldForceの第二引数の座標は、RigidBodyと同じ座標にすればスピンしない
- オブジェクトの現在位置はRigidBody.currentState.positionで取れる
- オブジェクトに力を加えて動く距離は、シミュレーション速度に影響されるっぽい
- なので毎回同じ高さにジャンプさせたい場合はAbstractPhysics.step()ではなくAbstractPhysics.engine.integrate(~)を使った方がいい?
- 特定のRigidBodyだけ無重力にするには毎フレーム重力ベクトルを-RigidBody.mass倍したものを加えればいい
- 現在の重力ベクトルはPhysicsSystem.getInstance().gravityでどこからでも取得できる
- オブジェクトの減速はRigidBody.currentState.linVelocityを弄ればいい
コリジョン用モデル
今回のステージは単純な形状ではあるけど、それでも複数のコリジョンを組み合わせる必要があったので、見た目のモデルとコリジョン用のモデルを分けている部分があります。
こっちが表示用メッシュで


こっちがコリジョン用のメッシュ。
これを同じファイルでレイヤを分けて管理しています。いくつか見た目とコリジョンが一致しているものがあって、ボールとか上下するリフトとかは表示用メッシュのをそのままコリジョンにしてます。
一応OpenCOLLADAではオブジェクトごとに設定したユーザー定義プロパティも書き出せるようになっているのでそれを利用したいんですが、A3D側でそのプロパティを取得する方法がちょっと分からなくて。もしA3DのCOLLADAパーサがパースしていないようだったら、ユーザー定義プロパティを抜き出す為だけのパーサを自作する必要があるのかな。仮にパースできるようになったとしても、3dsMax上でモデルごとにユーザー定義プロパティを設定したり確認するのが結構面倒なので、パラメータを簡易設定できるMaxスクリプトも作りたいし。色々大変そうだ・・・。
これを同じファイルでレイヤを分けて管理しています。いくつか見た目とコリジョンが一致しているものがあって、ボールとか上下するリフトとかは表示用メッシュのをそのままコリジョンにしてます。
オブジェクトごとのプロパティ
どれがどんな形状のコリジョンだとか、動くオブジェクトなのか固定オブジェクトなのか、他にも色々とオブジェクトごとにパラメータを持たせたいのに、今のところオブジェクトの名前につけた記号だけで管理している状態でそろそろ厳しくなってきました。名前はA3Dで参照を取得するのにも使うので極力余計なものはつけたくないし。一応OpenCOLLADAではオブジェクトごとに設定したユーザー定義プロパティも書き出せるようになっているのでそれを利用したいんですが、A3D側でそのプロパティを取得する方法がちょっと分からなくて。もしA3DのCOLLADAパーサがパースしていないようだったら、ユーザー定義プロパティを抜き出す為だけのパーサを自作する必要があるのかな。仮にパースできるようになったとしても、3dsMax上でモデルごとにユーザー定義プロパティを設定したり確認するのが結構面倒なので、パラメータを簡易設定できるMaxスクリプトも作りたいし。色々大変そうだ・・・。










コメントする