2012年12月31日月曜日
2012年の終わり
とうとう、2012年が終わろうとしています。私にとって2012年はCGに注力した年でした。それまでは思い出したかのようにぽつぽつとCGを描くことはありましたが絵についてはもっぱら透明水彩に時間の大部分を割いていました。しかし今年はかなりの労力をCGに投入したのです…
アーカイブによると今年は158枚描いたようです(まあ、ぼつになって日の目をみなかったものもありますが)。とくに四月から六月にかけては1日1枚のペースで描いていました。このときは鉛筆で描いた線をそのまま線画として使ってSAIで塗っていました。これは大変時間を節約できる手法でした。その後ラインレスの絵を目指して塗りによる表現重視に移行していきました。線画に頼りすぎると表現が硬くなる気がします。たとえば髪を描く際は線画よりも筆で一発で塗った方がより自然な流れになる気がします。ただ指などは線を使った方がいい結果が得れるでしょう。全体を通して見ると塗り方が上達しました。人体のバランスのとり方もすこしましになったようです。
ゲームの開発はそれほど力を入れる予定はありませんでしたが、結果として進展がありました。UnityでRTSゲームを開発中で、RTSで必要とされる基本的な動作―クリックによるユニット選択、移動指示、攻撃など―は実装できました。問題はAIの開発にあります。この連休でこの問題に取り組むことにしましょう。
来年は引き続きCGに多くの力を注ぐつもりです(200枚は描きたいところです)。ゲームの開発も引き続き行います。
ではみなさん良いお年を。
2012年12月13日木曜日
【Unity】RTS:AI 10 部隊の役割
RTSのAIを考える上でここの記事はすべての答を与えてくれたわけではないが大変参考になった。攻撃目標を決めた後、各部隊に任務を割り振ってどの部隊が特定の任務を一番効率よく出来るかコストを計算させよう。コストが一番低い部隊がその任務に向いている。AIは常に複数の作戦を計画しており全部隊がその作戦を実行するコストと成功した際の見返りを鑑みて作戦を決定するだろう。
そこで各部隊に割り振る任務にはどのようなものがあるか考えてみよう。
大きく分けると部隊は攻撃を実行するグループ(攻撃グループ)と攻撃部隊を支援するグループ(支援グループ)にわかれることになる。ここでこれまでの記事で触れてきた「攻撃円」だとか「危険区域」について再定義してみよう。
各部隊は「支配地域」と「交戦責任範囲」を持つ。支配地域はボードゲームでお馴染みのZOC(Zone Of Control)であり潜在的な攻撃範囲を示す。交戦責任範囲はほとんど射程とイコールである。支援グループの圧迫と支配についての定義は以下のようにした。
圧迫:圧迫とは敵の行動の自由を奪うことである。
支配地域の対象:味方部隊に攻撃を仕掛ける可能性がある敵部隊
圧迫を受けている敵部隊は移動の際に攻撃を受けるリスクを覚悟しなければならない。しかし速度が早いのならリスクは低くなるだろう。
支配:支配とは戦場の一地点を確保することである。
支配地域の対象:敵が存在すると味方部隊が攻撃を受けてしまう地点
支配地域に侵入する敵は攻撃されるリスクを覚悟しなければならない。
AIは攻撃はもちろん、圧迫と支配を上手く使って戦場の主導権を狙うべきだ。簡単な例を考えてみよう。
青軍は左から二番めの部隊が攻撃を行う。ほかは支援グループで攻撃部隊が敵の攻撃を受けないように圧迫と支配をつかい敵を牽制している。五分の勝負には持ち込めそうだ。
そこで各部隊に割り振る任務にはどのようなものがあるか考えてみよう。
大きく分けると部隊は攻撃を実行するグループ(攻撃グループ)と攻撃部隊を支援するグループ(支援グループ)にわかれることになる。ここでこれまでの記事で触れてきた「攻撃円」だとか「危険区域」について再定義してみよう。
圧迫:圧迫とは敵の行動の自由を奪うことである。
支配地域の対象:味方部隊に攻撃を仕掛ける可能性がある敵部隊
圧迫を受けている敵部隊は移動の際に攻撃を受けるリスクを覚悟しなければならない。しかし速度が早いのならリスクは低くなるだろう。
支配:支配とは戦場の一地点を確保することである。
支配地域の対象:敵が存在すると味方部隊が攻撃を受けてしまう地点
支配地域に侵入する敵は攻撃されるリスクを覚悟しなければならない。
AIは攻撃はもちろん、圧迫と支配を上手く使って戦場の主導権を狙うべきだ。簡単な例を考えてみよう。
青軍は左から二番めの部隊が攻撃を行う。ほかは支援グループで攻撃部隊が敵の攻撃を受けないように圧迫と支配をつかい敵を牽制している。五分の勝負には持ち込めそうだ。
2012年12月9日日曜日
【Unity】RTS:AI 9 攻撃目標の選択と部隊展開
AIは最適な攻撃目標を選択し、攻撃部隊の展開位置を算定できるようになった。下の写真は左のプレーヤーの部隊の陣形に応じて、右側のAI部隊が計画している攻撃展開位置を示している。
上の陣形ではAIはプレーヤーの右翼が脆いと判断し目標の正面と側面に部隊を展開し攻撃することを計画している |
部隊を突出させるとAIは目標を切り替えた。この場合側面攻撃を実施するとプレーヤーの後衛部隊から攻撃を受ける可能性があるため正面攻撃のみを計画している |
攻撃部隊以外は何をするのか、複数目標を同時攻撃するときはどうするのか、状況変化に応じ計画を修正するタイミングはいつなのか…等々課題は山積しているが今日はここで止めておくことにする。疲れたよ、俺は。
【Unity】RTS:AI 8 しゃぼん玉作戦
敵を多方面から攻撃するのは効果的だが、部隊が展開した時に敵から挟撃を受けるのは避けたい。挟撃を受ける可能性があるポジションは敵の部隊と部隊の間である。そこで敵部隊の間に円形の「危険区域」を指定する(ひとまずシャボン玉で表示)。AIは多方面攻撃を仕掛ける際に展開する地点が危険区域内にないか調査を行う…
とにかくAIの設計は複雑で難しすぎる。本当に作れるのだろうか
2012年12月6日木曜日
【Unity】RTS:AI 7 戦力投射コストの計算
プレイヤーの部隊(左)、AIの部隊(右)。各AI部隊からAIの計算によりラインがプレイヤー部隊に伸びている。ラインが青いほどAIにとって戦力投射コストが低い(攻撃しやすい)。手前のプレイヤー部隊には多数のAI部隊から青いラインが引かれておりAIはこの部隊を攻撃する可能性が高い。一番奥のAI部隊はどのプレイヤー部隊からも遠いので戦力投射コストは高くなっている。 |
【Unity】RTS AI 6 攻撃円と展開
以前考えたAIの設計では最適の攻撃目標を選ぶことができても、どのような戦術で目標を打ち破るのかまた実際に攻撃した場合の敵の反撃を考慮することが出来なかった。そこで攻撃円という考え方を導入した。各部隊は攻撃円という円形エリアを前方に持っている。攻撃のためにはこの円内に敵を収める必要がある。包囲や側面攻撃など連携攻撃を行う場合には各部隊ごとに計算された位置に攻撃円が設置される。
各部地は攻撃円上に敵を補足できるように展開し補足したら敵に攻撃を開始する(つまり攻撃円は一種のトリガーである)。展開に際し各部隊は敵の攻撃円内に立ち入らないよう注意すべきである。また敵の攻撃円は味方の攻撃円で中和が可能である。AIは敵の連携攻撃を想定した敵の攻撃円を計算し、常に味方が不用意に敵の攻撃円に立ち入らないようにする。
各部地は攻撃円上に敵を補足できるように展開し補足したら敵に攻撃を開始する(つまり攻撃円は一種のトリガーである)。展開に際し各部隊は敵の攻撃円内に立ち入らないよう注意すべきである。また敵の攻撃円は味方の攻撃円で中和が可能である。AIは敵の連携攻撃を想定した敵の攻撃円を計算し、常に味方が不用意に敵の攻撃円に立ち入らないようにする。
2012年12月2日日曜日
【Unity】RTS:AI 5 脅威度の算出
プレーヤーの部隊(左)とAIの部隊(右)。 |
脅威度算出プロセス |
上の写真では総合戦闘力が上回っているユニットに対してAIのユニットから黄色いラインが引かれている。特に脅威度が高いと赤線になる。一方戦力投入コストについては以下のようなプロセスで算出することを予定している。うまくすると脅威度と戦力投入コストは統合できるかもしれない。関数を追加するごとにCPU負荷が高まっている。心配だ。
【Unity】RTS:AI 4 総合戦闘力を算出する
前回の設計に基づき総合戦闘力関数を導入した。ユニットに表示される数値がそのユニットの総合戦闘力を示している。上の写真では孤立した左上のユニットは155と他の右下3つのユニットに比べ低い数値を示している。下の写真では真ん中のユニットは左右のユニットから支援を得れるので一番高い総合戦闘力を示している。従って特別な理由がない限りこのユニットを攻撃目標にするのは割に合わないとAIは判断するだろう。
【Unity】RTS:AI 3 攻撃目標の選定
複数の敵の中から攻撃目標を選ぶ場合、基準が必要となる。戦闘において努むるべきは味方の損害を最小にし敵の損害を最大にすることだとすると、「撃破しやすい敵」か「味方を撃破しうる敵」が優先目標となる。「撃破しづらくかつ味方を撃破し得ない敵」はほっといても大丈夫である。問題は常に「撃破しやすい敵」=「味方を撃破しうる敵」ではないということだ。以上を踏まえて攻撃目標評価関数を導入する。
まずAIが攻撃目標を評価する上で基本となるユニットのスペックを規定する。「戦闘移動コスト」は速度・射程・目標座標までの距離をパラメータに持つ関数である。「支援戦闘力」はパラメータに攻撃力と戦闘移動コストを持ち、味方を支援できる力を示す。例えユニットの攻撃力が大きくとも低速なら支援戦闘力は低くなる。「総合戦闘力」はユニット自身の攻撃力+周辺の味方のこのユニットへの支援戦闘力を示しており、これがAIが各ユニットの戦闘力を評価する際の基準となる。攻撃力が低いユニットでも群れていれば戦闘力評価は高くなるのだ。
この総合戦闘力をもとにさらに2つの関数を設定する。一つは「戦力投入コスト」である。これは敵の総合戦闘力をもとに敵を撃破するのに必要な味方戦力を動員するコストを示す。味方の総合戦闘力が劣っている場合追加の戦力が必要となるが戦力の集結には時間がかかるため戦力投入コストは高くなる。「脅威度」は敵が近く、強大なほど大きくなる。同一状況下でも戦力投入コストと脅威度は敵について相反する評価を示す場合がある。これら2つの評価を調整し最終的な評価を下すのが「攻撃目標評価」である。
2012年11月30日金曜日
【Unity】RTS:AI 2 概念図
2012年11月29日木曜日
【Unity】RTS:AI 1 単純な移動
2012年11月25日日曜日
【Unity】RTS:遠隔攻撃の付与
矢を目標に放っているところ |
ユニットが矢を放てるようになった。これでユニットのスクリプト開発はひと通り完了したことになる。これまでの開発でユニットは以下の様なことが可能になった。
- 指定された座標への移動
- 障害物を回避する
- 近接、間接攻撃
- ダメージ計算
これであとはAIを実装すればゲームとして機能するようになる。尤もそのAIが一番の関門なのだが。
さて、とにかくもここまで来ればどんなゲームを目指して開発をしているのか表明することもあながち場違いではないと思う。
ゲームのコンセプトアート |
来年度中に完成すれば万々歳だろう。
【Unity】RTS:集団行動
2012年11月21日水曜日
【Unity】RTS:障害物回避6
2012年11月18日日曜日
【Unity】RTS:障害物回避5
ウェイポイントシステムを構築した。まあこれは簡単だった。配列に座標を格納して指定した順にユニットは移動することが出来る。
さて、ユニットに搭載していた場当たり的な回避システムにはかねてより問題があった。大きい障害物は回避不能であり、広大な山岳を避けたり川にかけた橋などを通過させるためにはより改良された回避システムが必須だった。最初は超長距離センサーを搭載して回避を図ったがこれはこれまでの場当たり的な回避システムを単に大型化しただけで役には立たなかった。そこで大きな障害物の周りに4つのビーコンを置くことを思いついた。上の画像で光っているのがビーコンだ。大きな障害物はユニットが近づいてくると、ビーコンを作動させる。各ビーコンはただちにユニットとユニットの目的地そしてビーコン間の距離を測定しユニットがどのビーコンを中継して進めば大きな障害物にぶつかることなく、目的地に到達できるかを特定する。ユニットはビーコンの助言に基づき先のウェイポイントシステムを利用して新たにウェイポイントを設定し目的地まで無事にたどり着く…筈だがこれは回避システムの複雑化を招くこととなった。時々ユニットが明後日の方向に向かってしまう。非常に厄介だ。
2012年11月11日日曜日
【Unity】RTS:障害物回避4
2012年11月10日土曜日
【Unity】RTS:障害物回避3
色々考えたのだけども、障害物回避にはrayで周囲をスキャンして障害物を探知するのが良かろうという結論になった。そこで個々のユニットにくるくる自身が回転しながらrayを照射するオブジェクトを搭載させた。照射が障害物に当たると赤い線が表示される。馬鹿馬鹿しいことにこれを作るのに4時間もかかった。
2012年11月9日金曜日
2012年10月26日金曜日
【Unity】RTS:障害物回避2
ハブられる一人(´・ω・`) |
何故前回と同じような記事を投稿するのかと思うだろう。gifアニメを試してみたかっただけである。前回の障害物回避スクリプトを改良し後退中でも回避が可能になった。
これだけだと今回の記事はこれでおしまいになってしまうので―というのも他に前進したところがないので―スクリプトの仕組みを簡単に説明しよう。さてユニットはレンジ:SearchRangeの範囲でPhysics.OverlapSphereを使って周囲をスキャンしcolliderを見つけると障害物かどうか判定する(障害物にはタグが付いている)。
こんな図を作っているほど暇ではないのだが… |
障害物は更に方角に応じL(left)、FL(FrontLeft)などと分類される。最寄りの障害物がDodge Rangeに入るとユニットは回避行動に入る。FLエリアの障害物が最寄りの場合通常ユニットは右にスライドするが、Rエリアでも障害物が観測される場合は左にスライドする。Lでも観測されたら?ユニットは停止する(世の中は厳しいのだ!)。時々ユニット同士がニアミスする事故が起きる。その時のためにDodge Range内に更に赤色のエリアを確保しここに障害物が入ると問答無用で回避(後退も含む)を行う。
2012年10月21日日曜日
【Unity】RTS:障害物回避
2012年10月18日木曜日
【Unity】RTS:攻撃と移動
白兵ユニットの攻撃について以下のように分類した。
指定攻撃はマウスで敵ユニットをクリックすると選択した味方ユニットが移動を開始し、攻撃範囲に敵を収めると攻撃を開始する。
自動攻撃はプレーヤーの操作を必要としないパッシブな攻撃で続く3種類に分けられる。
「反撃」は敵の近接先制攻撃を受けた後に攻撃を開始する。「遭遇」は敵が正面にいてかつ至近の場合にこちらから接近し攻撃を開始する。正面に敵がいるのにユニットが棒立ちしているのは不自然なため。「防御」は遭遇と同じ条件だが敵に接近しようとせず、敵が攻撃範囲に入った場合のみ攻撃する。特にこちらが後退しながら追いすがる敵を攻撃する場面を想定したもの。
「反撃」は全方位からの攻撃に反応するが、ユニットがプレーヤーの命令を受けて移動中の場合は働かない(一方的に攻撃を受ける)。ただし正面からの攻撃は「遭遇」扱いとなり移動中でも移動命令を破棄し敵との戦闘を開始する。問題は発動条件が全く同じ「遭遇」と「防御」の使い分けだが、これは移動目的地が敵より向こう側の場合「遭遇」とし、敵と反対方向の場合は「防御」扱いになるようにした。
指定攻撃はマウスで敵ユニットをクリックすると選択した味方ユニットが移動を開始し、攻撃範囲に敵を収めると攻撃を開始する。
自動攻撃はプレーヤーの操作を必要としないパッシブな攻撃で続く3種類に分けられる。
「反撃」は敵の近接先制攻撃を受けた後に攻撃を開始する。「遭遇」は敵が正面にいてかつ至近の場合にこちらから接近し攻撃を開始する。正面に敵がいるのにユニットが棒立ちしているのは不自然なため。「防御」は遭遇と同じ条件だが敵に接近しようとせず、敵が攻撃範囲に入った場合のみ攻撃する。特にこちらが後退しながら追いすがる敵を攻撃する場面を想定したもの。
「反撃」は全方位からの攻撃に反応するが、ユニットがプレーヤーの命令を受けて移動中の場合は働かない(一方的に攻撃を受ける)。ただし正面からの攻撃は「遭遇」扱いとなり移動中でも移動命令を破棄し敵との戦闘を開始する。問題は発動条件が全く同じ「遭遇」と「防御」の使い分けだが、これは移動目的地が敵より向こう側の場合「遭遇」とし、敵と反対方向の場合は「防御」扱いになるようにした。
移動目的地の方位を分析し「遭遇(Encounter)」「防御(Defence)」を使い分ける |
2012年10月15日月曜日
【Unity】RTS:ダメージ計算の実装
2012年10月6日土曜日
【Unity】RTS:攻撃行動の追加
1年以上触っていなかったUnityを再開。開発が止まっていたRTS型のゲームをいじって攻撃指示ができるようにした。
ユニットを選択した後地面をクリックするとその地点に移動を開始するが、敵ユニットをクリックすると対象に突撃し攻撃範囲に収めると攻撃を開始する。現時点ではポーズだけでなんのダメージを与えることも出来ない。
本ゲームはRTSなのでダメージ計算は当たり判定ではなく敵味方のスクリプト間の通信で行う。AがBを攻撃した場合、AからメッセージがBに送られる。Bはメッセージを受け取ると自らのヒットポイントを減じる。またAの位置を特定し側面攻撃や背面攻撃の場合は追加のダメージを自身に与える。
今後はモデルを作り直し足と胴体を独立させて動かし、走りながら攻撃が出来るようにする。
執拗に箱を攻撃する剣士たち!ポーズだけだが |
ユニットを選択した後地面をクリックするとその地点に移動を開始するが、敵ユニットをクリックすると対象に突撃し攻撃範囲に収めると攻撃を開始する。現時点ではポーズだけでなんのダメージを与えることも出来ない。
本ゲームはRTSなのでダメージ計算は当たり判定ではなく敵味方のスクリプト間の通信で行う。AがBを攻撃した場合、AからメッセージがBに送られる。Bはメッセージを受け取ると自らのヒットポイントを減じる。またAの位置を特定し側面攻撃や背面攻撃の場合は追加のダメージを自身に与える。
今後はモデルを作り直し足と胴体を独立させて動かし、走りながら攻撃が出来るようにする。