GameProgrammar's Night

ゲームプログラム系の覚え書き

UnrealEngine4で2Dゲームを作ろう! その3 2Dアクターと移動のさせ方

※ 最新の情報で2Dゲーム制作についてまとめ直しましたので、「UnrealEngine4で2Dゲームを作ろう! 「2Dゲームを作るために必要なこと 基本編」 - GameProgrammar's Night」をご覧ください

 UE4で2Dゲームを作るのに参考になるプロジェクトを公開しているフォーラムを@aizen76 さんに教えていただいたので、ここでも紹介します。

 プロジェクト自体はちゃんとしてるのですが、アップされているサイトが出してくる広告がなかなか怪しいのでお気を付け下さいw 「DOWNLOAD LINK]じゃなくて[alternative link]の方をクリックするとすぐにDLできるサイトに飛びます。

 今回は、2Dアクターの作り方についてです。

2Dアクターの作り方

背景などで特に動かないスプライトを表示する

 Paper2DでSpriteにしたのち、コンテンツブラウザからビューポートにドラッグ&ドロップするだけでOK

コントローラ入力やAIなどで動く2Dアクターを作る

 衝突判定との兼ね合いでコンポネートのぶら下げ方が決まっています。
 一番外側を囲むコリジョンから順番にぶら下げて、一番最後にSpriteを追加します。

CollisionをPaper2Dで設定したものをそのまま使う

 この場合は、特に気をつけることはありません。ビューポートにドラッグ&ドロップして作られるPaper2Dアクターをそのまま使うか、別に作ったアクターに直接追加します。

CollisionをPaper2D設定とは別に作る

f:id:katze_7514:20150320181331j:plain

 上記の画像のように、collisionコンポーネントの下にSpriteをぶら下げます。
 この場合は、SpriteのコリジョンはOFFにするかOverlap専用にするのが良いと思います。

2Dアクターの移動のさせ方

 2Dの場合、物理を使って動かす(AddForceとか)のは、某鳥を飛ばすみたいな物理ゲームで無い限り、色々面倒を抱えこむので物理に寄らない方法で動かしたいと思います。
 やり方は、2つあります。

AddMovementInput

f:id:katze_7514:20150320185135j:plain

 このノードは、Pawnでのみ使うことができます。またTickイベントの中でのみ動作します。
 AddMovementInputによって動かすと、動き出しに加速度が付きますので、ぬるっとした感じに動きます。某配水管工のように。
 [Scale Value]にマイナスを入れると向きが反転するので、このノード一つで簡単に動きが作れます。

AddActorWorldOffset

 とはいえ、動き出しに加速度なんていらない! ということも良くあると思います。その時は、AddActorWorldOffsetノードを使います。(AddMovementInputでもパラメータを調整すれば加速なしで動くかもしれませんが)

f:id:katze_7514:20150320185141j:plain

 名前の通り、アクターの位置をワールド空間座標系で移動させるノードです。アクターであればなんでも良いので、CharacterActorを使わなくても大丈夫です。
 このノードを使う時は、画像のように[Sweep]引数にチェックを入れます。チェックが入っていないと、衝突判定が上手く動きません。チェックなしだと、Block指定してあってもCollisionをすり抜けます。ただ、Sweep引数での衝突処理は、衝突した一つ目に対してのみ有効らしいので、複雑な衝突を処理しながら進むゲームの場合は不向きかもしれません。

※追記
UE4.9以降では、Teleportフラグが追加されCollisionを完全に無視した移動も可能になりました。

AddInputVecotr

f:id:katze_7514:20160118181427j:plain

 AddMovementInputの別バージョンのようなノードにAddInputVectorがあります。こちらはPawnMovementComponentが必要になります。
 Tickイベント関係なく呼ぶことができます。指定したVectorを速度として移動をします。フレームの間に呼ばれた速度Vectorをすべて加算し、MovementComponentのTickタイミングで座標が移動されます。
 AddMovementInputより加速度感がなく、移動方向が変わった際にAddActorWorldOffsetより滑らかに速度がつながりますので、このノードを使うが個人的にはオススメです。

次回?

 FPS・解像度の指定、カメラの設定、アクターの作り方とゲームを作る最低限の操作はできるようになりましたので、あとは作るだけかなー、たぶん。
 なので、次回からは、こういうのを実現しようと思ってこんな感じに作ってます、という報告的な話題になると思います。


以下は、UE4のソースレベルで衝突によるBlockがどう行われてるかを解析したメモ書きです。興味のある方はどぞー

UE4の衝突判定からのBlockの流れ

衝突判定

 衝突判定自体は、有効なCollisionが設定されていれば物理挙動と関係無く([Simulate Physics]がオンになって無くても)行われています。
 Collisionは、UWorldクラスのインスタンスに登録されて、設定に応じて衝突判定が毎フレーム行われています。結果はUWorldが保持していて、必要に応じてアクターが引き出しているようです。
 

Block処理

 Block処理とは、Collision同士が重ならないように、重なってしまったCollisionをずらす処理のことです。UE4ドキュメントのコリジョン反応 インタラクションの項にわかりやすい画像があります。

 このBlock処理なのですが、アクターレベルでは、UMovementComponentクラスが行っています。
 ただ、このUMovementComponentクラスは速度ベクトルベースの移動を基本にしているため、速度ベクトルを生成しない移動だとBlock処理が走りません。
 前述したAddMovementInputは速度ベクトルを生成しますので、UMovementComponentによるBlock処理が走ります。AddActorWorldOffsetは直接位置を加算しますので速度ベクトルを生成しないため、Block処理が走りません。
 Sweep引数は、通常は走らないBlock処理を走らせる効果があるため、Sweep引数をオンにするとAddActorWorldOffsetでもBlock処理が行われるということになります。