開発中のメイン画面地形の高さを取得してユニットの配置を調整中。まだ微妙にズレるようで、地面にめりこむ兵士が存在する。
◎XNAのバージョンアップ今回は、地形の高さを取得してユニットの配置を調整します。高さ情報は地形作成プログラムで取得できるので、この情報をファイルに出力し、メインプログラムで読み込みます。
テキストファイル入出力は他の言語では簡単ですが、XNAではシリアライズとか同期とか面倒なことがあります。そのシリアライズですが、
こちらの記事によると、XNA3.1のコンテントパイプラインでは自動化されたようです。
今回は自動化の恩恵に与れるか否か微妙なところですが、これを機にXNAを3.0→3.1にバージョンアップしました。一旦アンインストールしてからインストールしろとのことですが、インストールに1時間ぐらいかかります。あまり頻繁にはやりたくないなぁ…。
ちなみに、ネット接続状態で3.0の日本語ヘルプを起動すると、自動的に3.1の日本語ヘルプが追加されます。実は今までF1キーを押すと英語ヘルプが優先表示されていたのですが、今回から日本語ヘルプが優先表示されて快適になりましたw
◎ソリューションのアップグレードソリューション(プログラム)のアップグレードは任意です。
メインプログラムをアップグレードしたらそのまま動きましたが、ユニット画像取得プログラムをアップグレードしたらビルドエラーになりました。ACLのバージョンチェックではじかれたようです。
3.1版のACLはTEAさんがコンパイルしてくれていて、
こちらのDLLを組み込んだら無事に動きました。
問題はSoftimageのランタイムで、こちらもプログラムをアップグレードするとビルドエラーになりますが、これに関する情報は見当たりませんでした。
XNA3.1でXNA3.0のプログラムがそのまま動くので、アップグレードしなければ当面不都合はありませんが、情報が無いのは不安です。このランタイムでゲームを作ってる人はACLよりも少ないってことなんでしょうね…。
◎使えませんアップグレードが完了したので本題に入ります。
グレースケールマップの高さ情報を一旦テキストファイルに出力し、それをメインプログラムで読み込むつもりでしたが、よく考えたら、既存のコンテントパイプラインでソレをやってるような気がしてきました。
実際に出力されるのはXNBファイル1つだけなので、いまいち確信が持てないのですが、この中にモデルデータと高さデータが混在してるはず…?
そこでまず地形作成プログラムのベースとなったHeightmapCollision(XNA公式サンプル)を複製し、コードを削りまくって高さ情報の受け渡し機能だけを残そうと考えました。高さ情報は最終的にModel.Tagに格納されますが、モデルデータは不要です。Model型からfloat型の二次元配列に変更したいのですが、これが私には難しくて…(−_−;
XNA3.1で自動XNBシリアライズ機能を利用する場合は ContentSerializerRuntimeType で型変更できるらしいので、ContentTypeWriter/ContentTypeReaderをコメントアウトしたらビルドエラーになりました。
多次元配列をシリアライズできません。多次元配列の場合、自動シリアライズ機能は利用できないようです。わざわざバージョンアップしたのに…(T−T)
◎カスタムプロセッサの修正仕方がないので自力で型変更を試みます。
Model.TagはObject型なので、Model→Objectに型変更してからfloatに変換しても良いのですが、問題はコンテントプロセッサの出力タイプです。ModelはModelContentが該当しますが、Objectやfloatに該当するものはありません。
そうなるとカスタムプロセッサを記述するしかなさそうですが、.xmlファイルを記述したり、ContentItemクラスを使用しなければならないのでしょうか?うーむ…。
…結局、HeightMapInfoContentを出力タイプに指定するだけで上手くいきました。元のサンプルはModelクラスの拡張プロセッサでしたが、こうすることで純粋なカスタムプロセッサになりました。
これまで散々悩んできましたが、ようやくカスタムプロセッサのプログラミングが理解できた気がします。
◎スケールの調整新しいコンテントパイプラインプロジェクトと高さ取得メソッドをメインプログラムに組み込んでスケールサイズの調整を行います。これまでテキトーにやってたので、メタセコイアとXNAとユニットのスケールがなかなか合いません。
・マップを256倍すると端の座標がおよそ
(-320,-320)〜(320,320)になるのは何故?
→256×256の地形モデルを中心にずらして256倍したので
256÷2×256÷100=327.68
→(-327.68、-327.68)、(327.68、327.68)に
ユニットを配置して目視確認OK
・マップの前後と左右でサイズが異なるように見える?
→地形画像を2D正射影で取得した際に
上下が少し切れていたため
→当面無視
・ユニットが向きを変えると表示位置も変わる?
→ユニットの原点位置を最大人数で調整しているため、
人数を減らすと表示位置が変わる
→ユニットの原点位置は、陣形毎&人数毎に
調整する必要あり?
・GetHeightメソッドの有効範囲がおよそ
(-320,-320)〜(180,180)で中心がずれている理由は?
→GetHeightの中でint型に直してから計算しているため
// left = (int)positionOnHeightmap.X / (int)terrainScale;
↓
left = (int)(positionOnHeightmap.X / terrainScale);
◎日本語のエラーメッセージスケールは概ね合わせたつもりですが、まだズレます。XNAとメタセコイアの分解数が異なるのが原因かな?
メタセコイアマップを分解数256で再作成し、XNAに取り込んで実行すると、日本語のエラーメッセージが表示されました。(従来は英語でした)

わかりにくいメッセージですが、英語で出されるよりマシでしょう。
分割数を256×256としたらインデックスが16ビット(65535)をオーバーしてしまったので、分割数を254×254に落としました。
これでエラーは解消され、以前よりマシになった気がしますが、でもまだズレます。
◎次回予告放っておくと、ズレがズレを呼んでわけわからなくなるのがこれまでのパターンだったので、今回は徹底的に潰そうとしたのですが、まだズレます。こうなったら、正確な頂点情報を出力して1つ1つ比較しますか。
11月になったので、次回は「10月の総括と11月の目標」です。
テーマ : ゲーム製作 関連 - ジャンル : ゲーム
始めまして。
教師の才能がおありかもしれません!?
今度XNAで何かを作ってみようかと思い立ち、始めたばかりの人間にとっては足しげくチェックさせて頂くHPの一つになりそうです。
製作しつつブログと大変かと思いますが、どうぞこれからも頑張ってください。
ありがとうございます
>記事が素晴らしく丁寧に書かれていたので、ついつい読みふけってしまいました。
そう言って頂けると、とても嬉しいです(^^)
>教師の才能がおありかもしれません!?
そんな風に言われたのは初めてです。お世辞でも嬉しいですw
>製作しつつブログと大変かと思いますが、どうぞこれからも頑張ってください。
どうもありがとうございます。
XNAはとっつきにくい所がありますが、ある程度使えるようになると面白くなってきますので、zeroさんも頑張ってください。
私もまだまだ未熟なレベルですが、少しでもお役にたてればと思います。
コメントの投稿