UE4-CustomGravityPlugin を試してみる

# 概要
UnrealEngine4のプラグインである[UE4-CustomGravityPlugin](https://github.com/mhousse1247/UE4-CustomGravityPlugin)を試してみた記録です。
各サンプルマップについての動作テストとコンポーネントのソースについての覚書メモを記載しています。

## 参考
以下の記事を参考にいたしました、ありがとうございます。
https://qiita.com/gansaibow/items/760c4dac0dcb75916b99


## 環境
Windows10
Visual Studio 2017
UnrealEngine 4.22


# 実行
ver.4.22でプラグインのリビルトを行います。

\Plugins\CustomGravityPlugin\Source\CustomGravityPlugin\Private\Pawns\CustomPawn.cpp
の 58行目

```C++:CustomPawn.cpp
PawnMesh->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::AlwaysTickPose;
```
上記でエラーがでます。
メンバ変数MeshComponentUpdateFlagが4.21以降で廃止されたためコメントアウトしして対処します。



# テスト
## Start_Map
各マップへの遷移用です。通常再生するとここが実行されます。

## GravityDash_Map
任意の方向へ重力変化をするサンプルのようです。
右クリックで浮遊、青いターゲットで対象の壁を狙って再度右クリックをすると対象に対して重力変化をします、キャラクターとオブジェクトに影響しています。

![gravityDash.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/c253b9e1-eab7-8db0-3a37-8c332c8ae048.png)



## GravityRoom_Map
重力方向が6方向変化するサンプルのようです。
[E]キーで重力方向が変化します。
![gravityRoom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/d04e7b21-a13c-71f0-0ce7-e7af606b7740.png)


## PlanetGravity_Map
惑星のような球体の中心に重力が働くサンプルのようです。一人称視点です。

![planetGravity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/35dfef51-0360-a7c6-7b18-8b6580997d6d.png)


## SurfaceGravity_Map
床の法線に対して立つ重力方向が計算されているサンプルのようです。
[Shift]押しながら移動をするとダッシュします。

![surfaceGravity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/9c9df63c-b9c1-d606-a9b4-2633c93f4b87.png)


## 2DGravity_Map
2Dでの重力移動のサンプルのようです。
矢印メッシュに触れると重力が変化します。
上下左右のカーソルで移動、スペースキーでジャンプをします。
![2Dgravity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/0098bff1-adb2-aa6b-e8cf-7181c85a100a.png)


# 考察
各マップの中のレベルブループリントにて変数設定を行っています。

## Componentについて
キャラクタ(Pawn)に対して、CustomMovementComponent.h
オブジェクト(Actor)に対して、CustomGravityComponent.h
を適用しているようです。

## Movementについて
FloatingPawnMovementComponentを使用しているため、各PawnのMovementComponentのFloatingPawnMovementのプロパティを変えると移動速度がかわります。
![floatingPawnMovement.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/79f5963d-e07b-e9b7-dc66-765b1bc2570c.png)

|プロパティ名|説明|設定されているデフォルト値|
|:---|:----|:----|
|Max Speed|最大速度|500.0 unit/sec|
|Acceleration|加速度|2048.0|
|Deceleration|減速度|2048.0|
|Turning Boost|方向転換時の速度スケール|8.0|

## CustomMovementComponentについて
処理で重要になるのが、TickComponentでのキャラクタが地上にいる場合の処理のようです。トレースがLineかSphereかBoxかいずれかで床面を調べ、法線方向と逆に重力を更新しています。(全部Lineでいいような気がしたのですが。)

```cpp:CustomMovementComponent.cpp
ShapeRadius = CapsuleComponent->GetScaledCapsuleRadius() * CurrentTraceShapeScale;
TraceEnd = TraceStart - CapsuleComponent->GetUpVector()* (CapsuleHalfHeight + GroundHitToleranceDistance + 1.0f);

if (TraceShape == ETraceShape::ETS_Line)
{
	UKismetSystemLibrary::LineTraceSingle(this, TraceStart, TraceEnd, UEngineTypes::ConvertToTraceType(TraceChannel), true, ActorsToIgnore, DrawDebugType, HitResult, true);
}
else if (TraceShape == ETraceShape::ETS_Sphere)
{
	TraceEnd += CapsuleComponent->GetUpVector() * ShapeRadius;
	UKismetSystemLibrary::SphereTraceSingle(this, TraceStart, TraceEnd, ShapeRadius, UEngineTypes::ConvertToTraceType( TraceChannel),　true, ActorsToIgnore, DrawDebugType, HitResult, true);
}
else
{
	TraceEnd += CapsuleComponent->GetUpVector() * ShapeRadius;
	UKismetSystemLibrary::BoxTraceSingle(this, TraceStart, TraceEnd, FVector(1, 1, 1)*ShapeRadius, CapsuleComponent->GetComponentRotation(), UEngineTypes::ConvertToTraceType(TraceChannel), true, ActorsToIgnore, DrawDebugType, HitResult, true);
}

CurrentTracedSurface = HitResult;
```

これらのコンポーネントはCustomPhysicsActorクラスやCustomPawnクラスのコンストラクタで作成されています。

# まとめ
Unreal側での物理シミュレートをなくしているわけではないので、プラグインで干渉したカスタム重力との合成状態になっていると思われるのですが、そこらへんの影響がどのようになっているのかはよくわかりませんでした。