走り回るだけの3Dサンプルゲームを作成しました。私の環境だと2~3ms程度です。
この記事では、非暗号化版を配布しつつ、ウディタで3Dゲームを作る際の考え方を紹介します。計算方法などはコモンをご参照ください。
目次
1.非暗号化版の配布
3.追加的な要素
1. 非暗号化版の配布
(1). 配布の目的
ウディタでの3Dゲーム製作は、かつては無謀な挑戦でした。しかし、3.0で計算機能が大幅に向上したことに加え、新機能のZオーダーが実装されたことにより、ゲームとして面白い、遊べる3Dゲームを製作できる可能性が高まっています。
このゲームでは、ウディタ3Dの基礎となる座標変換や回転等の計算式のコモンを組み込み、理解や製作に必要な時間を短縮すると共に、軽快な3D描写の可能性を示すことを目的としています。非暗号化なのでゲームファイルにエディタを突っ込めば編集できるはずです(多分)。
2. このゲームの3D描画の流れ
(1). 3次元座標の2次元座標への変換
3次元空間を2次元画面に表現するためには、①表示させたい物体の頂点の3次元座標を把握した上で、②3次元座標を投影用の2次元座標に変換し、③2次元座標同士をつないだ面(ポリゴン)を表示する、という手順を取る必要があります。
(2).3次元座標の管理
可変DBにあらかじめ表示させたい物体の3次元座標(X,Y,Z)を格納しておきます。
このゲームでは、ユニットとマップの3次元座標をExcelでcsvファイルとして作成し、可変DBに[読み込み]で格納しています。ゲームにはcsvファイルを同梱しています。
物体の座標は、マップは面DBと頂点DB、ユニットはユニットDBとボーンDBを加えた4つのDBで管理しています。
マップ
面DBには面を構成する4つの頂点のIDを格納し、頂点DBには各頂点の3次元座標を格納し、変換後の2次元座標を格納する場所を用意しています。
このゲームでは地面だけですが、高低差を激しくし、一定以上の高低差移動ができない処理を加えると壁にもなります。壁は壁として作った方が室内はきれいだと思います(そーま様の例)。
ユニット
ユニットDBにはユニット自体の中心座標や状態などを格納し、ボーンDBには体のパーツの中心座標(ユニットDBの座標からの差分の座標)を格納しています。また、面DBはマップと同様ですが、頂点DBにはボーンDBからの差分の座標を格納しています。
差分の座標とすることで、ユニットやパーツの移動や向きの変換にあわせて各頂点を動かせます。
木などのオブジェクトを設置したい場合は、別途オブジェクトのDBを用意することが考えられます。
(3).描画対象の特定・削減(カリング)
描画対象を限定することで計算負荷を減らします。
マップでは操作ユニットの周囲の数マスのみを表示対象としています。
ユニットは特段限定していませんが、多く設置する場合は中心座標のXZと視点(カメラ)座標のXZとの位置関係で限定します。
(4).頂点座標の透視投影変換
※透視投影変換の考え方については、そーま様のスクショの考え方を拝借しています。
頂点の3次元座標を2次元座標に変換します。
ここで、2次元座標は視界(スクリーン)上の座標なので、ある頂点の3次元座標が一定でも、観測者(視点)の3次元座標や向きにより2次元座標は変動します。
そこで、①物体の視点からの相対的な座標を求める②視点の向きを補正する③物体とスクリーンの奥行きの位置関係で補正する、という手順で座標を変換します。
①~③の考え方
①は頂点の座標から視点の座標を引き算するだけです。
②は回転行列はネットの記事で計算方法を調べて力技も可能ですが、上記のスクショを参考に作った方がスムーズです。2次元座標の回転を2回行うような感じです。
③はそーま様の図をご参照ください。
(5).面の描画
変換した頂点座標は一旦頂点DBに格納します。次に、面DBから面を構成する4頂点の2次元座標を呼び出し、ウディタのピクチャ機能[自由変形]で描画します。このタイミングでもカリングを行います。
自由変形は4つの頂点のXY座標を指定する必要があり、指定順によっては表示されない、逆転する、ねじれるため、使用する場合はテストが必要です。
なお、頂点計算→面から頂点と呼び出すのは、面に共有される頂点の計算を1回で済ませるためです。
また、このゲームでは、手前の面を前に、奥の面を後ろに表示します(Zソート)。
ウディタ2.0ではピクチャ番号で描画順が決まっていたため、描画順ソートの処理が複雑かつ重かったのですが、ウディタ3.0には[Zオーダー]という描画順専用の機能があり、ウディタ3.0自体の計算能力向上もあり、Zソートによる3D表現がとても容易かつ軽くなりました。
3.追加的な要素
(1).ユニットモーション
このゲームでは、ユニットを上下左右に向かせ、歩かせ、走らせることができます。
これにより、無限に近いポージングやアニメーションを描くことなく作成することができます。
手順は、①ボーンDB(体パーツのユニット座標を格納)を移動させる②頂点計算時に頂点+ボーン座標のみを対象にユニットの角度で回転行列により変換する、というものです。
①の方法は様々ですが、このゲームではフレームごとのボーン座標・ユニット移動値を格納したDBをモーションごとに作成し、ユニットごとのモーションとフレームをユニットDBに格納し、フレームごとに新しいボーン座標を読み込んでいます。
なお、ボーンアニメーションやキャラ造形はらたさんが神がかっています。
(2).三角ポリゴンと高低差、地面との高さ連動
ウディタの自由変形は4頂点なので四角ポリゴンですが、面は3点の座標で定まるため、何も考えずに高低差をつけると実際の高さと描画が一致しなくなります。また、形に制約が増え、角ばった表現になります。
2頂点を重ねると三角ポリゴンにできます(描画が乱れますが)。また、4頂点を再利用できるので、追加の点計算も不要です。三角ポリゴンは必ず面になるため、高低差と描画が一致し、曲面に近い表現ができます。また、高低差と描画が一致するので、ユニットの高さを地面の高さに連動する表現ができます。
面の3点の座標が分かり、かつ面上の点の2座標が分かる場合は、平面の方程式を使って残りの1座標(高さ)を求めることができます。方法は複数ありますが、リンク先の方法4がオススメです。法線ベクトルという言葉を忘れていても気合でいけます。
面の3点はユニットの所在タイルから把握できます。所在タイルは、マップを二次元平面だと考えて、ユニットのX・Z座標から1タイル当たりの幅を除したり余りを求めたりして何番目のタイルか把握できるようにしています。また、三角ポリゴンのどちらにいるかは、内外判定を使い判定します。
内外判定も外積を使うと良い感じに判定できます。
Comments