2016年10月8日土曜日

【Unity】RTS:補給と昼夜


 補給と補充、昼夜の仕組みを導入した。戦場はマス目に分割されて、昼の時点で自軍の占領が確定する。周囲に敵がいると占領できないので敵味方が対峙する前線のマス目は中立を維持する。ユニットは補給・補充を受けるためには朝の時点で自軍のマス目にいる必要がある。従って昼間は前線の中立地帯で戦い、夜には一旦後退して自軍のマス目に戻るというのが1日のサイクルになる。


 一日の時間に応じて照明の色が変わる。UIも改善して、多言語化に対応した。ユニットをマウスオーバーするとそのユニットがリアルタイムで表示されるようした。


 さらに改善したポアソンディスクサンプリングによって木を生やした(詳しくはここ)。木はハードウェアインスタンシングで描写している。

今後は地形の生成アルゴリズムの改善、グラフィックの改善を行う予定。

ポアソンディスクサンプリング (poisson disk sampling)


ゲームで木をまんべんなく生やしたいと思いポアソンディスクサンプリング(poisson disk sampling)を利用しようとしたが技術がないのでアルゴリズムの短い論文を読んで実装するのに非常に時間がかかったので、ここに要約を書こうと思う。ポアソンディスクサンプリングとは点同士が一定以上の間隔を保って面を覆うために使われる技法で、間隔を調整することで濃淡から絵を描くこともできる。

論文の要旨

確定した点のリスト、将来性のある点のリスト、及び2次元のグリッドを用意する。確定した点のリストには最終的に出力される点、将来性のある点のリストにはその点を基準に更に点を配置できる点が入る。グリッドは点同士の距離を計算する際に計算を簡略するために用いられる。点同士の最低間隔をrとする。

1 まずランダムな点を1つ生成する。これは直ちに確定した点のリストに入る(1つ目の点だから)。同時にこの点は将来性のある点のリストにも入る(周りにはまだ1つの点もないのでこの点を基準に新しい点を生成できる可能性があるから)。 確定した点はグリッドに登録し点同士の距離の比較に備える。
2 この点を基準点とする。この点の周囲半径r~2rのリングに収まる範囲に新しい点を生成する。この点とすべての確定した点との距離を計測し、間隔が小さすぎれば(グリッドを利用し計算を簡略する)その点を破棄する。確定した点たちと十分な間隔がある点は確定した点リストおよび将来性のある点リストに入りグリッドにも登録される。こうしてリング内に均等に点を生成し続ける(10~30回程度)。この試みの後、もしリング内に生成した点がすべて確定した点たちとの間隔の不足から破棄されていれば基準になった点にはもう将来性がないということなので、この基準になった点は将来性のある点リストから除かれる。
3 次の基準点は将来性のある点のリストの最後尾にする。そうしてまた2の処理を行う。
4 将来性のある点リストがカラになるまでこの処理を繰り返す。

この方法で素早く点を生成しゲームで指定範囲内に木を生えさせた。


 この場合点は白黒のテクスチャ上で黒のエリアの部分に生成されている。黒の部分が複数あり互いに白で隔てられている場合、アルゴリズムの特性上一つの塊の黒の部分でしか点が生成できない。そこでまず大雑把に全体に点を生成し、その各々の点を基準に2度目の点を生成することですべての黒の塊に点を生成している。

2016年9月17日土曜日

【Unity】RTS:ゲームのセットアップと補給補充


 ゲームのスタートにあたりユニットの数や種類を設定できるダイアログを仮実装した。コストにあわせてランダムに精度悪く自動で編成することもできる。


 地形の仕組みも刷新して浅い森や深い森などを生成することができるようになった。


 補給や補充の仕組みついて迷いがある。そもそもこの仕組みを導入しようと思ったのは、一旦戦端が開かれると絶えず戦闘が続くことによりプレーヤーに過度なストレスを与えることを避けることだ。またこうなると最初の衝突から延々と消耗戦が続いくことになり最初の戦闘部隊の配置以外に作戦を立てる余地があまりなくなってしまい面白みは半減する。そうしないためには戦闘はある程度行われると終了して、戦闘の結果を踏まえ作戦を練り直し戦闘部隊を再配置する「休憩」の時間が与えられるのが望ましい。戦闘と休憩を繰り返し行うことでゲームが進行することが理想だ。これを実現するためにはなんらかの形で戦闘を制限する仕組みがいる。
 現実の戦闘においても戦闘部隊が絶えず戦い続けることはない。戦うと弾薬や燃料を消費し疲労が蓄積し装備は消耗する。そのために戦闘を中断して補給を受ける必要がある。夜は暗く戦闘には不向きだから補給に適した時間帯といえる。
 ゲームにこの仕様を組み込むことについていくつかのアイディアがある。

1)補給圏を設置して補給のためには最前線から引き上げる必要があるようにする。補給圏を囲む補給線は最前線の前進に伴ってその後方において前進する。
2)グローバルな補給可能な時間帯を定める。ごはんの時間になるとみんな遊ぶのを止めて家に帰るようになる。
3)戦闘ペナルティがつく時間帯を設定する。攻撃速度や射程が低下し弾薬の対効果が悪くなる。

 補給線の移動のルールはよく考える必要がある。戦闘部隊の平均位置から決めるのは合理的に見えるが、素直に従っていると戦闘部隊の大半が補給のために後退するとその分補給線も後退してしまう。どの時点で補給線を更新するかが鍵だ。昼夜の概念を取り入れたらいいのかもしれない。夕方の時点での前線を基準にするとか。夜のうちに戦闘部隊は補給され朝には最前線に復帰している。そして夕方まで戦い新たな前線を勝ち取る。
 補給・補充(ヒットポイントの回復)と攻撃力のバランスにも慎重になる必要がある。前提としてユニットがポンポン死ぬようなバランスは避けたい。多くのユニットが必要になるからだ。もともと戦略よりのゲームにしたいという気持ちがあり、ユニットを大事に使うようにしたい。この場合弾薬を消費して敵に打撃を与えてもたっぷり補充されて翌朝ピンピンしているようでは戦闘の意味がなくなってしまう。従って補充は限定的なものであるべきだ。翌朝には場合によっては前線を維持するために消耗したユニットを投入する必要に迫られるだろう。補充の限界とはユニットのHPが最大値まで回復しないことかも知れない。最大HPからの差分の6割しか回復しないとか。あまりに傷ついたユニットは前線のはるか後方に後送し、一定時間後にフルに回復したユニットを手に入れられるようにすれば敵のユニットを消耗させると一時的に敵の前線戦力を減少させ前線を前進させることに繋がるようになる。前線を前進させるには相手を病院送りにすることが大切になるのだ。
 より作戦の幅を広げるためには前線を前進、あるいは後退させることにそれぞれメリットがあるべきだ。一般的には戦力が消耗した側が前線を後退させることになる。一方で戦局を有利に進めている場合は前線を前進させるだろう。前線の後退には防御に関するメリットが、前進には攻撃と勝利についてのメリットが必要になる。勝利については勝利条件を定めれば十分だろう。後退には補充の最大値が上昇するようにする。前線の前進は直接の効果はないが、拠点を制圧することでより多くのポイントを得、支援を得られるようになる。前線のより深い前進に対して補給線の追随が鈍くなるのはいいかもしれない。急速な前進を行うと補給線が追随せず補給が困難になる。補給線が追いつくまで踏みとどまるか撤退する必要が出てくる。
 こうした補給・補充の概念を導入した場合の懸念点は操作が煩瑣になることだ。自動化があったほうが良さそうだ。細かいことは忘れてひとまず全ユニットが一旦補給線まで後退する機能と翌日昨日の位置まで戻る機能は実装してもいいかもしれない。
 夜間はユニットが休むのでやや手持ち無沙汰になる。その間に翌日の支援を予約できるようにしたらいいかもしれない。支援とは砲撃や航空支援、ユニットの追加、一定エリアに攻撃・防御などのボーナスを適用するなどが挙げられる。

2016年9月8日木曜日

【Unity】RTS:ユニットのUI


 各ユニットのタイプごとにアイコンを作成してユニットの状態を示すUIを実装した。UIはユニットの種類とHP、戦闘継続時間を示している。


UIを作るのは楽しい。


また合わせて射程円とユニットの移動先を示す矢印も実装した。
今後は操作ボタンの実装を進めていく。

2016年8月26日金曜日

【Unity】RTS:戦闘継続時間


 HPの他に戦闘継続時間という仕組みを導入した。ユニットはこれにより一定の時間しか攻撃ができず、その後はクールダウンする必要がある。このため戦闘にかならず小休止が入るようになり常に戦闘しているという状態はなくなった。


2016年6月18日土曜日

【Unity】RTS ランダムな地形の自動生成


 ランダムに地形を生成するようにした。テクスチャは地面っぽく見えるように3種類を掛けあわせて適用している。


 デプスをとってグラデーションを適用している(遠くの紫、青)。このあたりは「王立宇宙軍」を見てて思いついた。



 地形のそれぞれのテクスチャはマスクをかけて表示するところを限定している。このマスクのために不思議なノイズを生成する仕組みを実装した。パラメータを変えるとノイズがかわる。



 これをもとにシェーダーでマスクをかけている。
また木も生成するようにした(まだテクスチャがないので白色)。木はGraphics.DrawingMeshを使って表示している。木の位置を決めるために木のエリアでポアソンディスクサンプリングを行っている(木同士が重ならないように配置する)。


 建物なども配置したいが時間がないのでベータ版には間に合わないだろう。今後は再度ゲームロジックに立ち戻って実装を続ける。




2016年6月5日日曜日

【Unity】 RTS UIとフラッグ、カメラの移動


 ユニットのUIとしてHPゲージと有効射程円を表示するようにした。射程円を示すにはプロジェクターを使っている。UnirXを部分的に使い始めた。HPゲージはリアクティブプロパティを利用している。上の写真はexeとして書きだしたゲームで旧いPCでもスムースに動いているようだ。


 カメラの挙動を改善してWASDによる移動に加え、中ボタンでぐりぐり回転できるようにした。スクロールで拡大縮小。スクロールはユーザーによってスピードがかなり異なるので適切なスピードで動くようにする必要がある。


 ユニットが占領可能なフラッグを実装。指揮官AIはフラッグを考慮に入れて戦線を設定する。明日からは地形の改善を行う。