[UE4](C++)BlueprintSetterとLevelSequenceと

検証UE4: 4.27.1

変数の UPROPERTY の BlueprintSetter での関数指定、UFUNCTION での BlueprintSetter 設定の話になります。
それを LevelSequence(シーケンサー） から使用したときの挙動の注意点です。
まちがってたらごめんなさい。

・BlueprintSetterの参考
[UE4] UE4.17リリースノートピックアップ - 花繁吹き
http://unwitherer.blogspot.com/2017/08/ue4-ue417.html

# まとめ
- LevelSequence で変数UPROPERTYの BlueprintSetter は動作しない
- LevelSequence からは関数名を「Set+<変数名>」にする事でフックできる
- BPから、LevelSequenceから、両方取りたい場合はBlueprintSetter指定して、関数名を「Set+<変数名>」と合わせることで出来る

|処理方法|BPから値設定|LevelSequenceから値設定|
|:--|:--:|:--:|
|BlueprintSetter使用|○|×|
|関数名「Set+<変数名>」|×|○|
|BlueprintSetter使用+関数名「Set+<変数名>」|○|○|

ちなみに、
どれも関数はC++のアクセス権を private にしてても呼ばれます。
「Set+<変数名>」にする際、bool型の prefix の "b" は無くて大丈夫です。(変数bool bValue -> 関数SetValue)



# BPからのBlueprintSetter
標準的な BlueprintSetter の設定の下記コード

```C++:C++.h
	UFUNCTION(BlueprintSetter)
	void SetBPSetterHogeHogeF(float Val);

	UPROPERTY(interp, VisibleAnywhere, BlueprintSetter=SetBPSetterHogeHogeF)
	float BPSetterValF = 0.0f;
```

```C++:C++.cpp
void ASetterTestActor::SetBPSetterHogeHogeF(float Val)
{
	UE_LOG(LogTemp, Log, TEXT("%u %s: SetBPSetterHogeHogeF"), GFrameNumber, *GetName());
}
```
BPから変数へ設定すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/33b1b299-5047-94c9-2c0a-f217b38a19a8.png)
問題なく呼ばれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/3823262e-3349-626a-d21a-2bf9185420cb.png)

# LevelSequenceからのBlueprintSetter
上記を LevelSequence から値を設定するようにしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/6b56c44f-2e99-eb76-80e9-9065f8dd4b52.png)
しかし、ログには何も出てきません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/1006b722-8d9d-40da-1245-5f55511d9588.png)

LevelSequence でのトラックからは BlueprintSetter が動作してくれません。

# LevelSequenceからの値設定をフックする方法
フックする方法はあります。
UFUNCTIONでかつ、関数名を **Set+<変数名>** で用意します。

下記のように記述します。UPROPERTY、UFUNCTIONに **BlueprintSetter指定は必要ありません** 。
変数 FuncNameValF に対して、PrefixにSetを付けた SetFuncNameValF 関数

```C++:C++.h
	UFUNCTION()
	void SetFuncNameValF(float Val);

	UPROPERTY(interp, VisibleAnywhere)
	float FuncNameValF = 0.0f;
```

```C++:C++.cpp
void ASetterTestActor::SetFuncNameValF(float Val)
{
	UE_LOG(LogTemp, Log, TEXT("%u %s: SetFuncNameValF"), GFrameNumber, *GetName());
}
```

上記を LevelSequence から値を設定するようにしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/dd35ef0d-0d6d-6431-77c9-6800a34136ed.png)
無事ログが出力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/e5433e21-1290-53f9-ee67-8601394b20f9.png)

この場合、Blueprintから設定しても
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/e279b5e5-479a-650f-71b0-b41dde11a5b1.png)
呼び出されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/a3b8ea0e-278a-412a-c412-7047b213ed74.png)

# BPからLevelSequenceから両方から呼ばれるようにする
どちらの場合でも処理を挟みたい場合は、**BlueprintSetterを使用しつつ、関数名をSet+<変数名>で用意します** 。

```C++:C++.h
	UFUNCTION(BlueprintSetter)
	void SetAllOKValF(float Val);


	UPROPERTY(interp, VisibleAnywhere, BlueprintSetter=SetAllOKValF)
	float AllOKValF = 0.0f;
```

```C++:C++.cpp
void ASetterTestActor::SetAllOKValF(float Val)
{
	UE_LOG(LogTemp, Log, TEXT("%u %s: SetAllOKValF"), GFrameNumber, *GetName());
}
```

BPから設定して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/334243fe-c381-ca41-2dc4-367e094ab1e0.png)
無事ログが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/34681b38-7981-1d7e-85a5-44b0a77c4cb2.png)

LevelSequenceから設定して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/6240c89c-2468-79a3-85b0-b2d7ddd6d4e0.png)
無事ログが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58518/8a2f225e-461e-e753-c23d-235b37c2a546.png)