2018年7月19日木曜日

【Unity】RTS Bwars2 至近の課題

Bwars2開発にはやるべきことがたくさんあるが、至近のやることは3つある。それは射撃処理の洗練化、地物の生成、道路だ。


射撃処理の洗練

射撃は今は1つの砲弾ごとに命中・ダメージ判定を行っているが、高レートで連射した場合処理負荷が集中する可能性がある。例えばシルカ対空戦車は機銃を4門装備し一斉に射撃すると毎分数千発を射撃することになり、1秒あたり50発以上を発射する。これ1発1発について命中を判定しダメージを適用するのはあまり賢くなさそうだ。そのためある程度ゴマカシが必要になる。

そこで一定時間内に発射される砲弾をまとめて1つの砲弾として扱う。(まだ手法は考えていないけど)処理を一括して行うことで負荷の軽減が見込める。 この方法は弾の着弾地点が1箇所になる欠点がある。つまりきちんと1発ずつ計算していいれば複数弾の着弾地点はバラけ、様々な場所のユニットにダメージを与える可能性があるがこの方法では範囲が限られてしまう(その分範囲内のユニットには複数弾の合計されたダメージが入る)。そのためあまり多くの砲弾をまとめるべきではない。一方で簡略化は避け得ないのでやむを得ない方法だ。

また砲弾の処理に用いる入力パラメータを使い回すことでも処理を軽減できる。厳密に言うと敵味方のユニットが移動している場合、距離などのパラメータは刻一刻変化するので砲弾の発砲ごとに最新のパラメータを入力して命中判定などを行うのが望ましい。しかしパラメータの変更は計算のやり直しを招く(判定のしきい値がその都度再計算必要になる)。そのためある程度の時間内は同じパラメータを続けて使用するようにする。もちろん時間が経過することに状況は変化するのでなるたけ短時間の使用が望ましい。この同じパラメータを利用する連射を同一射撃と言うことにしよう。同一射撃時間は例えば1秒とする。この場合1秒の間はたとえ目標が破壊されたりロストしてもとにかく同じパラメータを利用して撃ち続ける。そして射撃開始から1秒後まだ目標が有効であり、かつリロードなどもクリアしていれば最新のパラメータを取り込み再び1秒撃ち続ける(パラメータは別のゲームループで更新されているので前回と同じ場合もありうる)。この場合見た目上はひたすら計算を行い連射しているように見えるが実際には1秒毎に計算が行われていることになる。同一射撃時間はそのままクールダウン時間となり、射撃開始後、同一射撃時間内は新たな発砲はできない。

以上2つの方法を用いる場合、射撃レートごとに以下のように利用することになる。

・高レート
同一射撃を開始する。例えば100発を同一射撃時間内に発砲するとしよう。それを25発ごとに1つの砲弾として同じパラメータを使って処理を行う

・低レート
同一射撃を開始する。4発を同一射撃時間内に発砲するとして、個々の砲弾ごとに同じパラメータを使って判定を行う。

・単発
戦車砲など毎分10発前後の場合は同一射撃終了後、リロードを挟んで再度射撃を行うことになる。

こうした処理を行うために、射撃制御クラスを作る。各ユニットの武器クラスは同一射撃時にパラメータを制御クラスに渡しあとはお任せすることになる。


地物の生成

今は地形の特性はテクスチャに描かれた図形で表現されているが、やはり立体のほうがいい。ただしBwarsは低スペック・旧PCにも対応したいのでGPUをブン回して描写を行うことは避けたく、またユーザーが手軽にmodを作れることを目指しており、加えて基本的には遠くから俯瞰しながらプレイするゲームであることから地物はとても簡略した描写に抑えたい。市街地や森ではたくさんの建物や木を並べて高密度さを表現したいがGPUインスタンシングでも数が多いと負荷は馬鹿にならない。そこでこうした高密度オブジェクトは連続したポリゴンを生成し描くようにする。これはGoogle Mapの3Dと同じような感じになる。郊外や茂みなど低密度な地域は一つ一つ地物描くようにする。ポリゴンの生成とLOD処理が課題になる。また地物ポリゴンが省略された場合でも自然に見えるマップテクスチャの生成も必要だ。


道路

個人的には道がないテラインは梅干しがない白米みたいだと思っていて、道路の実装は必須だ。道路はノードで定義され、各ノードは座標と接続ノードの情報を持っている。課題がいくつかある。1つは道路のノードの編集で、エディターなどを整備しないといけない。また実際にノードから地形に沿って目に見える道路を生成する必要がある。これには橋やトンネルも含まれる。最後に道路を全体の経路探索に組み込み、ユニットが道路に対応し道路上を移動できるようにしなければならない。課題は多いがRTSゲームではコンプレックスな道路の実装は少なく(せいぜい川に橋がかかるだけ、都市系シムと比べると特に見劣る)、実装できればマップの表現や戦術に新しい光を当たることができるだろう。


1 件のコメント:

aki/c さんのコメント...

こんばんは。ツイッターでのいいねありがとうございます。
高レート機関砲等の処理で思いついたのがあるので書き込んでみます。
 一定時間内発射される砲弾(a)を1つの砲弾(b)として考える場合
士気や距離などで命中率を出して、(a)一発が与えるダメージを装甲や地形等割ったり引いたりしたもので出して、それを発射した数でかけて(b)として総ダメージを出す…と思うんですけど、他のユニットに攻撃を与えた場合の代替としてその時に出した命中率の低さで広がるサークルを作り出してそこをダメージゾーンとして作るのはいかがでしょう。つまり一度の攻撃に付き狙った敵に与えたダメージを計算するものと、外れた弾による範囲ダメージの2つを計算するものを作ってしまえば、大体の同口径弾はレート以外威力が似たようなものなのでパラメーターを考えるのも楽になるかと思うのですが。
長文で失礼しました。