ギルティギア2のサーヴァントの動き方について

作りたいっていう理由もあるので、ゲームの作りについて書いていこうかと。
そのうちUE4でどう作るかも詳しく書いていくかも。
今の時点ではこれで出来るっていうやり方もちゃんと分かってないわけだけど…

で、作りたいゲームっていうのは「ギルティギア2」(以下、GG2)

RTS + アクション でできているゲームで、RTSでも他と比べると内政とかがないので結構取っつきやすいはず。
とりあえずRTS部分の要になるユニット(ゲーム内ではサーヴァント)の動きの中でも、
指示を与えて目的地に移動するための考え方について書いていこうかと。

どんな感じの動きをしているかはYouTubeとかニコニコで対戦動画とか見て欲しいんだけれども、ゲーム中でやることが忙しくてユニットが歩かないようにしていたりするので、とにかく何をやってるか分かりにくい。
分かりやすそうなのはニコニコの公式対戦動画くらいかな?
ギルティギア2 公式対戦動画「HEAVEN OR HELL ? #1」 ‐ ニコニコ動画:GINZA

 

ストーリーモードやってる動画もいいかな?
チュートリアルを兼ねてるし。

この記事を書いてる間にsteamで配信が開始されたようなので、とりあえず買ってみて、やるかどうか考えるのもいいかと思います。

 

GG2ではサーヴァントがとにかく最短経路を歩くようにはなっておらず、途中の陣地(ゴースト)を通るように歩いたりしている。
つまり、予めどこを通るのかが決まっているということ。
イメージとしてはそれぞれのゴーストの間の道に線が引かれていて、その上を歩くようなイメージ。

じゃあ、その線がどういうふうに引かれているのかというと、サーヴァントの動きをよく見ると分かるけれど、道が曲がっているような場所でも真っ直ぐに歩いて、常に同じ地点で向きを変えてまたまっすぐに歩いている。
つまり、全て直線で構成された道になっていそうな感じ。

大雑把にこんなの。
数字はゴースト

f:id:aki_senri:20160401012354p:plain

 

ただ、実際には直線の道だけではないし、障害になるような物があったりもする。
そうなるとどうすればいいのかというと、曲がっているような道にも見えない中継地点が設定されていて、そこに向かって直進し、中継地点で次の中継地点の方を向き、また直進を行っていくということを繰り返せばいいはず。

こんな感じ。

f:id:aki_senri:20160401013802p:plain

 最近見たのだとLoLやParagonなんかはミニオンがこの形で動いていそう。


そこの中継地点がどれくらいあるかとかは場合によるからおいておき、じゃあ実際にどこを通るかを決定するにはどうするのか。
探索の計算量をあまり増えないようにすることを考えると、正方形のタイルで構成されたマップ上を探索するようなのは、マップが広くなると計算量が増えていくのであまり現実的ではなくなっていく。

じゃあどうするのかというと、「グラフ」というデータ構造を利用する。
これはそれぞれの頂点同士を繋ぎ合うデータ構造で、GG2のようにゴーストとゴーストが道で繋がれているのと同じようなイメージのデータ構造になるので、利用するのにはとても都合がいい。
このグラフで現在地の頂点から目的地の頂点までの探索をすれば、そのままサーヴァントが通るルートが出来上がる。

ただ、グラフにも種類があり、GG2のように距離が関わるような場合には「重み付きグラフ」を利用する。
この「重み付きグラフ」のいいところは、頂点に重みをつけるのではなく、頂点同士をつなぐ辺に重みをつけること。
つまり重みを距離と置き換えれば、最短距離になるルートを探索できる、まさにGG2にはおあつらえ向きなデータ構造になっている。
さらにグラフには種類があり、無向と有向のグラフがある。
無向グラフというのは、例えばAとBという頂点がつながっている時に、A→BのルートもB→AのルートもOKになる構造。
有向グラフというのはA→BのルートはOKだけれど、B→Aのルートがないような構造。
例えば崖のようになっている道があり、上から下には行けるけど、下から上には行けないような道にしたい場合には有向グラフ、どちらからも行けるような道だけにしたいのであれば無向グラフを使用するのがいい。


有向グラフの場合には方向だけでなく、重みも方向毎別々に設定ができるので、
A→Bは行きやすいけど、B→Aには行きにくいというような事もできる。

 

無向グラフの例
赤字は重み。

f:id:aki_senri:20160401014915p:plain

 

有向グラフの例

f:id:aki_senri:20160401015013p:plain

 

実際に実装する場合には色々と探索を行うアルゴリズムがあるんだけど、その場で計算するとそれなりの時間がかかったりするので、事前に計算しておいた結果を利用するといいかも。
これをUE4で作りたいけど、データ構造をどうしたものか・・・