UE4 CurveTableについてのメモ

# 概要
UnrealEngine のデータテーブルのカーブテーブルについてのメモです。


## 環境
Windows10
Visual Studio 2017
UnrealEngine 4.22

## 参考
以下を参考にさせて頂きました、ありがとうございます。

[[UE4] CSVデータを扱う方法　CurveTable編](http://historia.co.jp/archives/1067/)
[UE4 値が補完されるCSVファイルを使う（Curve Table、Evaluate Data Table Row）](http://kagring.blog.fc2.com/blog-entry-204.html)


# カーブテーブル(CurveTable)
アンリアルにはカーブアセットがたくさんあります。

![curve_kind.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/cb90252e-f349-5454-9de4-7afaad1246f5.jpeg)

↑のカーブではなく、データテーブル派生のカーブテーブルについて扱います。


## カーブテーブルアセットの作成
まず、csvデータを用意します。

```CT_test.csv
,0,10,20,30,40,50,60,70,80,90,100
Curve01,10,11,12,13,50,51,52,53,1000,1100,1200
Curve02,20,21,22,23,24,25,500,600,700,800,900

```

コンテンツブラウザにcsvデータをドラッグ＆ドロップします。
データテーブルと同様にインポートメニューが表示されます。

![DataTableOption.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/070c5328-774b-9fe4-fdca-9807c75b7552.jpeg)

インポートを[CurveTable]、カーブ補間タイプを[Liner]を選択します。
補間タイプによっては別途選択が必要です。

できたアセットを開くとデータを見ることができます。
csvデータと同じです。
![CurveTable_Data.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/ccce63c5-23be-0399-02fd-e4cffae939ab.jpeg)

[ウィンドウ] -> [CurveView]を選択すると表示が切り替わります。

![CurveTable_View.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/4927867e-dbe9-cff6-ffbf-dee2a9602928.jpeg)

微妙に見にくいですが、カーブの具合を見ることができます。
（カーブと違い、なぜかカーブテーブルはズームすることができないです。。）

また、カーブの補間タイプは最初のインポート時で決まり、変更ができないようです。



### 補足
上記例ではcsvから作成しましたが、データテーブルのようにjsonからでも作成ができます。
その場合は以下のようなJSONデータになります。

```json:CT_test.json
[
	{
		"Name": "Curve01",
		"0": 10,
		"10": 11,
		"20": 12,
		"30": 13,
		"40": 50,
		"50": 51,
		"60": 52,
		"70": 53,
		"80": 1000,
		"90": 1100,
		"100": 1200
	},
	{
		"Name": "Curve02",
		"0": 20,
		"10": 21,
		"20": 22,
		"30": 23,
		"40": 24,
		"50": 25,
		"60": 500,
		"70": 600,
		"80": 700,
		"90": 800,
		"100": 900
	}
]
```


## BPでのカーブデータ取得
BPでは[Evalute Curve Table Row]を使い、テーブルデータと行の名前を指定して取得できます。
(ソースは "Engine\Source\Runtime\Engine\Private\DataTableFunctionLibrary.cpp" です)
![EvaluteCurveTable_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/23eeacd2-f951-d08c-5edb-ffd3ad9bb08b.jpeg)

上の例では[In XY]で 15.0 を指定しているので、[Out XY]で 11.5 が返ってきます。（カーブの補間方法が違うと値も変わります）


## C++でのカーブデータ取得
以下がC++での取得コード例です。

```cpp:.h
UPROPERTY()
UCurveTable* CurveTable;
```

CurveTableアセットのポインタをコンストラクタでFindして、FCurveTableRowHandle 経由で取得するか、カーブを一旦保持してから値を取得します。

```cpp:.cpp
#include "Classes/Engine/CurveTable.h"

// コンストラクタ
// CT_test というカーブテーブルを探す
static ConstructorHelpers::FObjectFinder< UCurveTable > find_curvetable(TEXT("CurveTable'/Game/CT_test.CT_test'"));
if (find_curvetable.Succeeded()) {
	CurveTable = find_curvetable.Object;
}

...

// カーブデータを取得例１
FCurveTableRowHandle _Handle;
_Handle.CurveTable = CurveTable;
_Handle.RowName = *FString::Printf(TEXT("Curve01"));
float _OutXY;
static const FString _ContextString(TEXT("GENERAL"));

if (_Handle.Eval(15.0f, &_OutXY, _ContextString)) {
	UE_LOG(LogTemp, Log, TEXT("OutXY = %f"), _OutXY);
}

// カーブデータを取得例２
auto _Curve = CurveTable->FindCurve(*FString::Printf(TEXT("Curve02")), _ContextString);
if (_Curve != nullptr) {
	UE_LOG(LogTemp, Log, TEXT("Value=%f"), _Curve->Eval(25.0f) );
}
```


# コンポジットカーブテーブル(Composite Curve Table)
4.21から追加されたアセットタイプのようです。
複数のカーブテーブルをまとめることができるます。

![compositecurvetable.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/64017a75-7304-7989-3828-fee135825260.jpeg)

CT_test と CT_test2 のカーブテーブルをまとめています。
![compositecurvetable_editor.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/b4bad632-e4ff-0676-6f7d-6ac0202ce952.jpeg)

Rowデータの取り出しは通常のカーブテーブルと同様に[Evalutate Curve Table Row]ノードを使って取り出すことが可能のようです。
コンポジットカーブテーブルを使うとカーブ補間タイプが違うカーブテーブルをまとめて１つのアセットのように扱うことができます。

複数のカーブテーブルを取りまとめるため、Row名がかぶるとどうなるのかは検証しきれていませんが、警告のようなものは確認できませんでした。
使う場合は、Row名のルール決めが必要だと思われます。



# まとめ
カーブはいろいろ種類が多く、エディターのビューも違うため注意が必要なようです。
カーブテーブルはシンプルなつくりのためキャラクターのパラメータの補間などの用途には使えると思います。