概要
エディター上でコンポーネント内の変数値が変更されると呼び出される関数を使って、別のコンポーネントの変数値も変わるようにします。
・サンプルとしてThirdPersonTemplateのC++を利用します。(versionは5.1.1を使用)
・今回はCharacter側で新たに作成した変数(MaxWalkSpeed)からCharacterMovement内の変数(MaxWalkSpeed)を変更したいと思います。
・プロジェクト名はSampleEditorChangeとしました。
最終的にはこうなります
(SampleEditorChangeのMaxWalkSpeedを変更すると)
↓
(CharacterMovementのMaxWalkSpeedも同じ値に変更されます)
プロジェクト作成
それでは手順を説明していきます。
まずはこの記事用のプロジェクトを作成します。
プロジェクトが開いたらC++クラスの中のSampleEditorChangeCharacterをダブルクリックします。
VisualStudioが立ち上がります。
.hファイル
まずSampleEditorChangeCharacter.hに変数(MaxWalkSpeed)を作成します。
public:
UPROPERTY(EditAnywhere) // BP側で設定できるようにしておく
float MaxWalkSpeed;
続いて次の関数"PostEditChangeProperty()"を記述します。
public:
UPROPERTY(EditAnywhere) // BP側で設定できるようにしておく
float MaxWalkSpeed;
#if WITH_EDITOR // これは条件付きコンパイルの記述。エディターのみでコンパイルされる。
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& Event) override;
#endif
.cppファイル
次はcppファイルに中身を記述していきます。
SampleEditorChangeCharacter.cppを開いて以下を記述します。
// BP_ThirdPersonCharacter(self)内の変数の値が変わるたびにこの関数が呼び出される
#if WITH_EDITOR
void ASampleEditorChangeCharacter::PostEditChangeProperty(FPropertyChangedEvent& Event)
{
Super::PostEditChangeProperty(Event);
// PropertyNameには変更した値のコンポーネント名or変数名が格納される
FName PropertyName = Event.Property != nullptr ? Event.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_CHECKED(ASampleEditorChangeCharacter, MaxWalkSpeed))
{
if (GetCharacterMovement())
{
// 実際に値を変更(紐付け)している部分
GetCharacterMovement()->MaxWalkSpeed = MaxWalkSpeed;
}
}
}
#endif
※実際にPropertyNameに何が入っているか確認したい場合は以下の3行を追記してください。(デバッグ用)
.....
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Kismet/KismetStringLibrary.h" // 追記
.....
// BP_ThirdPersonCharacter(self)内の変数の値が変わるたびにこの関数が呼び出される
#if WITH_EDITOR
void ASampleEditorChangeCharacter::PostEditChangeProperty(FPropertyChangedEvent& Event)
{
Super::PostEditChangeProperty(Event);
// PropertyNameには変更した値のコンポーネント名or変数名が格納される
FName PropertyName = Event.Property != nullptr ? Event.Property->GetFName() : NAME_None;
FString StringPropertyName = UKismetStringLibrary::Conv_NameToString(PropertyName); // 追記
UE_LOG(LogTemp, Warning, TEXT("PropertyName: %s"), *StringPropertyName); // 追記
if (PropertyName == GET_MEMBER_NAME_CHECKED(ASampleEditorChangeCharacter, MaxWalkSpeed))
{
if (GetCharacterMovement())
{
// 実際に値を変更(紐付け)している部分
GetCharacterMovement()->MaxWalkSpeed = MaxWalkSpeed;
}
}
}
#endif
エディターで挙動を確認
では実際にエディターで確認してみます。BP_ThirdPersonCharacterを開きます。
BP_ThirdPersonCharacter(self)を選択し、Details(詳細)にてMaxWalkSpeedで検索をかけます。
SampleEditorChangeCharacterのMaxWalkSpeedの値を変更すると同時にCharacterMovementのMaxWalkSpeedの値も同じものに変更されました。これで実装は以上となります。
先程のデバッグコードを記述された方はエディターのOutput Logを開いてください。
値を変更するとPropertyNameに入った名前を確認することができます。