UE4の勉強記録

UE4の勉強の記録です。個人用です。

「Unreal Engine4.xを使用してRPGを作成する」のChapter 3 を勉強する。Part2

<前文>

f:id:kazuhironagai77:20190414194435p:plain

今週は、前回述べたように、カメラとキャラクターを繋ぐスプリングの設定方法のUE4C++とBPの比較とそれについての考察、turnとturnrateの違いについて、そしてその違いが何故RateとRate * BaseTurnRate * GetWorld()->GetDeltaSeconds()なのかについての考察を行います。

<本文1>

今回は前回の続きをやります。前回、カメラの設定とそのカメラとキャラクターを繋ぐスプリングの設定をUE4C++で行う方法を習いましたが、これと全く同じ事をBPで行う方法がBP 3rd Person Game: Character BP Components | 12 | v4.8 Tutorial Series | Unreal Engineに載っています。

UE4C++を学ぶ理由は色々ありますが、以下に私がUE4C++を学ぶ理由を示します。

f:id:kazuhironagai77:20190421203930p:plain

この目的の一つにBPで出来る事をC++で行うがあります。

今回のカメラの設定とそのカメラとキャラクターを繋ぐスプリングの設定はまさにこれです。それで詳しく考察する必要があると思い今週はそれを行います。

<目的>

カメラの設定とそのカメラとキャラクターを繋ぐスプリングのUE4C++による設定とBPによる設定の比較とその考察をします。

<考察>

BPでのやり方を忘れてしまったので、BP 3rd Person Game: Character BP Components | 12 | v4.8 Tutorial Series | Unreal Engineを要約してUE4C++と比較します。

BPにおけるSpring Armの作成とそのプロバティの指定>

<比較>

まず対応するUE4C++の作成手順とその実装を以下にまとめました。

f:id:kazuhironagai77:20190421204026p:plain

これと比較しつつ、BP 3rd Person Game: Character BP Components | 12 | v4.8 Tutorial Series | Unreal EngineのSpring Armの作成を要約します。

Step.1 USpringArmComponentクラスからのオブジェクトの宣言

キャラクターBPクラスから派生BPクラス(CharacterBP)を作成。そしてCharacterBPのBPエディターを開きAdd ComponentからSpringArmを選択し追加します。

f:id:kazuhironagai77:20190421204101p:plain

(SpringArmの名前をCameraBoomに変更)。

Step.2 SpringArm(CameraBoom)を初期化

Step.1の段階で初期化もされている模様です。

Step.3 CameraBoomRootComponentbind

これも、Step.1の段階でされているのでしょうか?(自信なし。)

アクタークラスならRootComponentもここで追加出来たはずです。CharacterBPは既にRootComponentが作成されているのかどうか良く分からないです。唯一言える事はこのチュートリアルではSpringArmをRootComponentにbindするために何か特別な事はしていないと言う事だけです。

Step.4 Armの長さを指定

なし。

ただし出来るはずです。どこかでスプリングの長さを調節したチュートリアルを見た記憶があります。view portから行うのか、detailsから行うのか、記憶はさだかではないです。

Step.5 Characterに対してのSpringArm(CameraBoom)の位置を指定

Viewport内でCameraBoomを選択し移動するだけでした。

f:id:kazuhironagai77:20190421204206p:plain

UE4C++に対してspring armがキャラクターに対してどの位置にあるのかが視覚的に良く分かります。この視覚的に判断する必要がある箇所はBPの方がC++より断然優れていると思います。

Step.6 Armがコントローラーによって回転するか指定

CameraBoomを選択しDetails下のCamera Settings下のUse Pawn Control Rotationをチェックします。

f:id:kazuhironagai77:20190421204234p:plain

<カメラの作成とそのプロバティの指定>

対応するUE4C++の作成手順とその実装を以下に示します。

f:id:kazuhironagai77:20190421204303p:plain

Step.1 UCameraComponentクラスからオブジェクト(FollowCamera)を宣言

以下に示すように、CharacterBPのBPエディター内のAdd ComponentからCameraを選択し追加します。

f:id:kazuhironagai77:20190421204334p:plain

(Cameraクラスのオブジェクトの名前は、CameraでUE4C++のFollowCameraではなかったです。)

Step.2 FollowCameraを初期化

Step.1の段階で初期化もされている模様。

Step.3 FollowCameraUSpringArmComponentクラスのオブジェクトであるCameraBoombind

以下に示すようにAdd Component内でCameraをCameraBoomの下に配置します。

f:id:kazuhironagai77:20190421204420p:plain

来ました。これがbindのやり方だったのですね。と言う事は、CameraBoomはBootCompomentにbindされていないと言う事ですね。

Step.4 Arm(CameraBoom)の回転と一緒に回転するか指定(しないと指定)

なし?

プロパティ名がbUsePawnControlRotationでないので、このBPのチュートリアルでArm(CameraBoom)の回転と一緒に回転するか指定はしていなののですが、回転に関して何か良く分からない事を指定しています。

Step.5  Arm(CameraBoom)に対しての角度を指定

なし。

だたし、これ以外のBPのチュートリアルでこの指定をviewportでしているのを勉強した記憶があります。

<考察>

教科書とBP 3rd Person Game: Character BP Components | 12 | v4.8 Tutorial Series | Unreal Engineチュートリアルは同じ機能をUE4C++とBPで作成していますが、その詳細は全然違うので一概に比べられなかったです。しかし一般的なUE4C++とBPの実装方法の比較は十分に出来ました。

UE4C++では、まずコンポーネント(SpringArmやCamera)の宣言をヘッダーファイルで行い、その初期化をソースファイルのコンストラクターで行います。そのコンポーネントが他のコンポーネントにbindする場合は、SetupAttachment()関数を使用してbindします。その後、そのコンポーネントの相対的な位置や角度、bindしているコンポーネントの動作に付随するかなどのプロパティをそのコンポーネントが持つメンバー関数を使用して指定します。

BPではコンポーネントの作成やそのプロパティの指定をBPエディター内で行います。最初にAdd Component内で作成するコンポーネントを選択し作成します。もしそのコンポーネントが他のコンポーネントにbindする場合は、そのbindするコンポーネントの下に配置します。コンポーネントの相対的な位置や角度、bindしているコンポーネントの動作に付随するかなどのプロパティは、viewport内で視覚的に指定するか、details下のパラメーターで指定します。

この他に述べておきたい重要な事は、このBPのチュートリアルで、Characterクラスの派生クラスであるCharacterBPの設定で何故それをするのか全く分からない箇所がありました。RPGCharacterクラスの作成が完成したらもう一度、UE4C++のPlayerPawnとBPのPlayerPawnの比較も行う必要があるかもしれません。

<本文2>

AddControllerYawInput()関数はBindAxis()関数のTurnとTurnRateの両方に使用されています。

以下に示すようにTurnはマウスでplayerPawnを操作する時に使用されTurnRateはジョイスティックでplayerPawnを操作する時に使用されます。

f:id:kazuhironagai77:20190421204551p:plain

違う種類の装置を違うように扱うための2つのバージョンの回転のバインドがあります。

“turn”は絶対的なデルタを提供する装置、例えばマウス、を扱います。

“turnrate”は変化の割合を扱う装置、例えばアナログのジョイスティック、のためです。

大変驚きですがTurnとTurnRateの実装部の違いはAddControllerYawInput()関数にパスするパラメーターの違いだけでした。

もしTurn とTurnRateが文字通りの意味ならばTurnの単位はRadian。TurnRateの単位はRadian/secondもしくはRadian/Frameなはずです。その意味はturnはその場で回転してTurnRateはその瞬間における回転の割合を示しているとなります。

PlayerPawnは前進しながら左右に曲がる訳でTurnとTurnrateには以下に示す違いが生じると思われるのですがどうなのでしょうか?

f:id:kazuhironagai77:20190421204643p:plain

<目的>

TurnとTurnrateに使用される関数が両方とも同じ関数AddControllerYawInput()でした。違いはパスされるパラメーターだけでした。この二つの違いを考察してみます。

<考察>

TurnとTurnrateの左折の違いについてもう一度、以下に示します。もしTurn とTurnRateが文字通りの意味ならばturnはその場で回転してTurnRateはその瞬間における回転の割合を示していると考えられます。PlayerPawnは前進しながら左右に曲がる訳でTurnとTurnrateには以下に示す違いが生じると思われますので検討したいと思います。

f:id:kazuhironagai77:20190421204747p:plain

この違いがあるとどうして重要と私が考えるかについて説明します。

私は一時期VRにはまっていたんですが、付属のソフトで、キャラクターを操作して右左折する時にものすごく気持ち悪くなるんです。本当に吐くんじゃないかと言うくらいに。VRの酔いは個人差があると言われていますがこの時の気持ち悪さはそんなレベルではなかったです。それで何故こんなに気持ち悪くなるのかを自分なりに調べて見たんです。

私が行った事は、実際に人間が右左折した時にどんな風景を見ているのか録画する事でした。携帯に私が右左折した時に見ている風景を録画しました。不思議だったのはその録画した動画を見ても全く酔わなかった事です。勿論動画をそのまま携帯で再生したのでVRで見た状態とは違いますがそれでも全く違うと感じました。それで、その録画した動画をよく見てみると風景の中に上下に伸びた見えない軸がありその軸を中心に私が回っている事に気がつきました。

VR内で右左折をする(少なくともその付属のソフトの場合)時はその人の体の中心から上下に伸びた見えない軸を中心に回転するのですが、実際の人が右左折する時は体からかなり離れた所に上下に伸びた見えない軸がありその軸を中心に回っている違いがあったのです。

その後、VRに対する熱が冷めてしまい、どうすれば酔わない右左折を作る事が出来るのかと言う疑問に対する解答を欲する気持ちもなくなってしまい、すっかりその事は忘れてしまいました。

今回、TurnとTurnRateの違いを見た時この事を思い出しました。そして何故、人が右左折をする時、体からかなり離れた所に上下に伸びた見えない軸がありその軸を中心に回るのかが分かりました。単純に前進しながら回っているからです。人間は前進しながらじゃないと曲がれなかったんです。

これってVRで右左折する時の悪酔いの原因じぁないでしょうか?VRでは、(少なくともその付属のソフトの場合)前進する時の加速、減速とそれに基づく回転による右左折が全く考慮されていなかったです。

よって、このTurnとTurnrateを良く勉強する事はVRで酔わない右左折を実現出来る可能性があると私は考えています。

しかし全てを解明する時間は到底ありませんので、VRで酔わない右左折を実現するための第一歩として、今週はAddControllerYawInput()関数のパラメーターのみに注目します。

Turnの時のAddControllerYawInput()関数のパラメーターはRateのみです。TurnrateのAddControllerYawInput()関数のパラメーターはRate * BaseTurnRate * GetWorld()->GetDeltaSeconds()です。もしRateの単位がradian/secondならば、BaseTurnRateは単位なし、DeltaSecondは文字通り⊿秒(非常に短い時間と言う意味)となり考えていたのと逆に、Turnの時のパラメ―ターの単位は、radian/secondでturnRateの時のパラメーターの単位はradianとなります。

f:id:kazuhironagai77:20190421205022p:plain

あれ?想像していたのと逆でした。うーん。これだけではまだ良く分かりませんね。今回は酔わない右左折のための第一歩としてAddControllerYawInput()関数のパラメーターをTurnとTurnrateの両方で調べたとしておきましょう。