読者です 読者をやめる 読者になる 読者になる

GameProgrammar's Night

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

UE4にSpineが来た

UnrealEngine4 C++

ja.esotericsoftware.com

 Spineとは、2Dアニメーションにもボーンを取り入れて、3Dアニメーションのように、2Dアニメーションを作れるようにするツールです。誤解を恐れずに言えばSpriteStudioの親戚のようなものです。
 長らくUE4への対応は行われなかったのですが、次のバージョンアップで対応されることになりました。UE4.15から対応という予定ということで、UE4.15pre2で、動かしてみました。

 まだβ版ということもありSpine側のコードを変更する必要がありました。先行して触りたい人向けに、どこをいじれば良いかをざっと紹介したいと思います。

 Spnieが用意したUE4への導入ドキュメントはこちら

1. SpineのUE4ランタイムをDLする

 Spineのランタイムは、Githubで公開されてますのでDLします。

github.com

 UE4ランタイムが含まれているのはspine-ue4フォルダです。テスト用のUE4プロジェクトも含まれていますので、それをそのまま動かすことにします。

2. spine-ue4にspine-cのソースをコピーする

 spineランタイムの本体はspine-cフォルダのソースです。
 spine-c内のspine-cフォルダをフォルダごと、「spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public」にコピーします。
 
 コピーしたら、VSプロジェクトを再生成しておきます。

3. SpinePlugin.Build.cs にAssetToolsを追加する

 以下の2行を追加してください。

PrivateIncludePathModuleNames.AddRange(new string[] { "AssetTools" });
DynamicallyLoadedModuleNames.AddRange(new string[] { "AssetTools" });

4. コピーしたspine-c内にある「c」拡張子を「cpp」拡張子に書き換える

f:id:katze_7514:20170130202221j:plain

 Spineの製作者がcファイルをコンパイルできるようにするためのプルリクをしていて、UE4.15に含まれています。しかし、VSのプリコンパイルヘッダーの仕様でそれだけではコンパイルが通りません。そのため、cppとしてコンパイルすることにしました。

5. ソースを修正する

  • 拡張子を書き換えたcppファイルすべてに「SpinePluginPrivatePCH.h」を一番最初にincludeするように書き足す
  • 「SpineAtlasImportFactory.cpp」で「IAssetTools.h」をincludeする
  • 「SkeltonJson.cpp」の_spLinkedMesh構造体宣言をコメントアウトする
  • 「Atlas.cpp」266行目274行目あたり
    • 「if(!(count = readTuple(&begin, end, tuple))」の条件式を外に出す

まとめ

 ソースのUE4対応が中途半端なので、おそらくですがgithubに上がっているのは最新ではない気がします。

 プラグインとして、競合ソフトであるSpriteStudioより優位な部分は、

  • 追加シェーダがいらない
  • マテリアルを変更することができる

 というところでしょうか。

UE4 .15 preview1 RawInputのコードをざっと読んでみた

UnrealEngine4

 RawInputとは、PCにつながっている入力デバイスの生データを取得するAPIです。
 UE4.15からサポートされることが決まり、DirectInputのみのゲームパッドもこれで動くかなと思いまして、少し該当部分のソースを読んでみました。
 速報ということで、読み取れたことを箇条書きします。

機能

  • プラグイン扱い
    • デフォルトではOFFになっているので、ONにする必要があります
  • ジョイスティック(もしくはそれに類する)デバイスのみの対応(HID Usage=0x04)
  • 8軸、12ボタンまで
  • 軸の値は、「-1.0~1.0」にClampされる
    • 元は生データですので実値は各デバイスに異なるため必要な処理です。
  • キーイベントの名称は、「GenericUSBController_***」
    • ***には、Axis1とかButton1とかが入る
  • キーイベントが全体で一つだけ
  • バイスごとの入力を設定は、[ProjectSettings]→[Plugins]→[RawInput]のConfigurationでできる
    • BPへは公開されてないので動的な変更はできない。ActionMappingと同じポリシーの様子
    • フォーラムで各入力デバイスのこの設定を募集しています
  • ControllerID(=PlayerIndex)は、0固定
    • CreatePlayerで2Pキャラクターを作ってもRawInputでの入力取得はできない
  • 振動未対応
  • キーリピート未対応

 間違いなどありましたら、ご指摘ください。随時修正します。

UE4 イベント・関数・マクロ・インターフェイスの違いと使い分け

UnrealEngine4 Blueprints

qiita.com

この記事は、UE4 AdventCalender 18日目の記事です。

 BPには、イベント・関数・マクロ・インターフェイスと手続きの実装手段が豊富にあります。
 BPはオブジェクト指向言語ではありますが、オブジェクトより手続きを重視した思想になっている現れだと個人的に思っています。
 とはいえ、手続きの実装手段が多すぎて、結局どれで実装すれば良いのかが、わかりにくいというのも確かです。そこで、各手続きの機能的な違いと使い分けについて紹介したいと思います。

主な機能一覧表

イベント 関数 マクロ インターフェイス
入力ピン 1個 0~1個 0個以上 1個
出力ピン 1個 0~1個 0個以上 1個
引数 0個以上 0個以上 0個以上 0個以上
戻り値 なし 0個以上 0個以上 0個以上
アクセス制御 public public
procted
private
private public
オーバーライド 不可
ノード制限 なし あり なし 実装方式による
EventDispatcherへのbind 不可 不可
特徴 ネットワーク越しに呼べる いわゆるメソッドに一番近い Lispのマクロのような
Functorのような
ダックタイピング

手続き解説

イベント

 イベントは、BPにおける手続き実装の基本です。
 もっとも制限のない手続きのため、戻り値がいらないならイベントを使いましょう。

 イベントの大きな特徴は、ネットワーク越しに呼べることです。
docs.unrealengine.com

 自動でRPC機能がつくので、これだけで、ネットワークゲームがある程度作ることができます。 

関数

 戻り値が必要な時は、関数を使います。
 唯一アクセス制御をコントロールできますので、アクセス制御が必要な時も関数を使います。LatentノードやTimelineノードなど一部使えないノードが存在します。

 関数はPureフラグをオンにすることで実行ピンを省略することができます。値の取得のみで済む場合は、オンにすると良いでしょう。

 他のクラスベース言語経験者で、BPのことがよくわからない内は、関数で実装して、関数ではできないことはイベントにするというやり方でも良いと思います。

マクロ

 ノードをまとめて整理したり、部分的に使い回すのに使います。インライン化機能もついており、実行時にはノードが展開されます。
 最大の特徴は、複数の入出力ピンを使えることです。

f:id:katze_7514:20161217004936j:plain
 上記のマクロは、プレイヤーのPawnとの距離に応じて、出力ピンが実行されます。
 ちなみに「ノードの折りたたむ」はマクロにすると同じです。

 マクロはprivateになりますので継承先では使えません。継承先でも使いたい時は、イベント・関数として実装しなおすか、MacroLibraryを使います。ただ、MacroLibraryに実装すると逆に継承先でしか使えませんので、イベント・関数で実装にした方が良いかもしれません。
 また、マクロ内部ではブレイクポイントをおけませんので、はじめからマクロとして作るとデバッグが大変なこともあります。

 名前から、C言語系のプリプロセッサのマクロかなと思うかもしれませんが別物です。おそらくですが、Lispマクロを参考にしているのだと思います。
 Sequenceノードと組み合わせることで継続のようなこともできますし、マクロのローカル変数は実行終了後も値を維持しますのでFunctorのような挙動もします。
 マクロだけで1冊本が書けそうなぐらい様々なことがでできます。

インターフェイス

 インターフェイスは、キャストなしに呼ぶことができます。そのため、クラス間の依存度を下げるのに使います。テンプレートやジェネリクスのないBPでダックタイピングをするための手続きです。
 わかりやすい使い所は、Overlapイベントなどエンジンが用意しているイベントです。
f:id:katze_7514:20161217012833j:plain
 エンジンが用意するイベントは、引数がActorなど汎用的な型ですので、Interfaceにしておくと楽になります。

f:id:katze_7514:20161217011007j:plain

 インターフェイスの呼び出しは、右上に手紙マークがつきます。
 右クリックメニューから選ぶ時は、Messageとついてるのを選びます。
f:id:katze_7514:20161217012109j:plain

 クラス間の依存度下げることは、コンパイルが早くなるだけでなく、エディタのクラッシュ率やバグを踏む可能性も下げますので重要です。

 インターフェイスの実装は、戻り値がない場合はイベント、戻り値がある場合は関数として実装します。
 なお、インターフェイスはデフォルト実装が直接はできませんので、場合によっては他の手続きで実装した方が楽なこともあります。

明日は

 明日は、hima_zinnさんの「UE4のショートカットをカスタマイズして開発効率を上げる」です。

UE4 FloatingPawnMovement を使う

UnrealEngine4

 FloatingPawnMovementとは、UE4が用意している移動を担うComponentの一つです。
 CharacterMovementのように状態(歩き、ジャンプ、しゃがみ)があるわけでもなく、設定したパラメータ通りに位置を変化させるだけのシンプルな実装のMovementComponentです。
 シンプルですが2Dゲームで使うには十分な機能を持っており、自分のゲームでの移動はFloatingPawnMovementをメインに使っています。
 

移動させる

f:id:katze_7514:20161026154832p:plain

 移動させる時は、AddInputVectorノードを使います。
 FloatingPawnMovementは、移動させたい方向のベクトルを与えることで移動します。

●X+方向なら(1.0, 0.0, 0.0)
f:id:katze_7514:20161026161546p:plain

●45度方向だったら(cos45, sin45, 0.0)
f:id:katze_7514:20161026161554p:plain

 方向ベクトルの長さは「0.0~1.0」です。1.0以上与えても1.0として扱われます。この長さは、次に説明する速度パラメータのスケール値として働きます。

 AddInputVectorは呼ぶ度に方向ベクトルが加算されて行きます。FloatingPawnMovementのTickが呼ばれるまでの加算結果を用いて移動処理が実行されます。
 これを利用することで、Pawnの外部からの影響を受ける特殊な移動処理を簡単に実現することもできます。

ある地点に引っ張られる

 青いエフェクトが出ている間、通常の移動処理に加えて、中央に移動する方向ベクトルをAddInputVectorすることで実現しています。

速度パラメータ

 MovementComponentでの移動は、与えたベクトル方向に加速していき、最大の速さに到達したら速さアップを止めます。ベクトルの入力が無くなったら減速します。
 移動の調整は、それらのパラメータをいじることで行います。

f:id:katze_7514:20161026150207p:plain

パラメータ名 意味(単位)
Max Speed 最大の速さ(unit/sec)
Acceleration 加速度(unit/sec)
Deceleration 減速度(unit/sec)
Turning Boost 方向転換した際の追加加速スケール

 単位は、unit/secです。2Dゲームで、PPUを1.0に設定している場合は、pixel/sec と思って大丈夫です。

 TurningBoostは、どれだけ素早く方向転換できるか、ということを示すパラメータです。TurningBoostの値が大きいほど素早く方向転換が行われ、小さいほどゆっくり方向転換します。動作としては、方向転換する時だけ、加速度がTurningBoost倍されます。

 デフォルトの値では、加速も減速も方向転換も、かなり素早く行う設定となっています。そのため、すぐに最大の速さになりますし、ピタっと静止できるし、瞬間的に方向転換します。

慣性のある移動(滑りながら移動)

 速度パラメータ設定の応用として、慣性のつく設定を紹介します。
 以下のように、最大の速さ以外のパラメータの値を大きく下げ、また加速より減速の値を低くします。

f:id:katze_7514:20161026180052p:plain

 すると次の動画のようになります。

youtu.be

移動制限パラメータ

 移動する平面を指定することができます。指定した平面以外へは動かなくなります。
 詳細パネルのPlanarMovementで設定します。
 
f:id:katze_7514:20161026154839p:plain

 図の設定だと、移動がXY平面のみとなりZ方向には動かなくなります。

パラメータ 意味
Constrain to Plane チェックを入れると平面に移動が制限される
Snap to Plane at Start Spawnした時から指定した平面に制限するか
Plane Constraint Axis Setting 移動制限したい平面の簡易設定。移動制限する平面の法線軸を指定。Customを選んだ場合は次の2項目を自分でいれる
Plane Constraint Normal 移動制限平面との法線ベクトル
Plane Constraint Origin 移動制限平面の法線ベクトルの原点

 ただし、Pawnに直接Locationを入れれば(AddWorldLocationなど)、動かない方向にも動きます。あくまで、FloatingPawnMovementによる移動が制限される設定となります。

Navigation

 FloatingPawnMovementは、Navigation移動に対応しています。AIControllerを持つPawnに持たせれば、MoveTo系ノードを使うことで、今まで紹介したパラメータに従ってNavigationします。

注意点

 FloatingPawnMovementは、AddInputVectorでベクトルが追加されなかった場合に減速する仕組み上、前フレームとの位置差分を速度ベクトルに変換する処理が入っています。
 そのため、直接Locationを入れて動かすことと併用している場合、想定してない移動になることがまれにあります。

 自分の場合は、移動制限せずに、描画順制御のためにZ方向の移動だけはSetWorldLocationで行っていた所、Z方向に速度が発生してしまいました。描画順がおかしくなったり、衝突するはずのコリジョンが当たらなくなったりしていました。

PlayStation4のコントーラをWindowsで使う時の開発側の注意点

DirectX Input

 PS4がアップデートされて、PCからリモートプレイができるようになりました。
 それに合わせて、PS4コントローラをPCにUSB接続するだけで、ゲームパッドとして利用することができるようにもなりました。そのため、これからPCゲームをPS4コントローラで遊ぶ人が増えると思います。
 UEDirectInputPadPluginでPS4コントローラを使った所、キーコンフィグBPがちゃんと動かないと言われまして調査しました。

 その結果、開発側としては、考慮しておいた方が良い事項がありましたので、書いておきたいと思います。

PS4コントローラ

  • DirectInputで動作している
  • L2/R2ボタンは、回転軸とボタンの両方にマッピングされている
    • L2はX回転と7ボタン
    • R2はY回転と8ボタン
    • 回転は-1.0(押されてない)~1.0(一番下まで押し込む)の範囲の値が取得される*1

f:id:katze_7514:20160806154518p:plain

 1つのボタンで2つ値が返ってくるので、キーコンフィグを作る時にはちょっと頭にいれて置くと良いと思います。

 PS4コントローラが意図している所は理解できるんですが、どうせならXInputで動くようにしてくれれば良いのにね……。と思ったのですが、タッチパッドの情報を使うためにDirectInputにしているのかもしれません。PSボタンは13ボタン、タッチパッドボタンは14ボタンに割り当てられています。

*1:XInputのLT/RTは0.0~1.0