エディター上で変更したコンポーネント内の変数を別のコンポーネント内の変数にも反映させる方法【UnrealC++】

## 概要

エディター上でコンポーネント内の変数値が変更されると呼び出される関数を使って、別のコンポーネントの変数値も変わるようにします。

:::note warn
・サンプルとしてThirdPersonTemplateのC++を利用します。(versionは5.1.1を使用)
・今回はCharacter側で新たに作成した変数(MaxWalkSpeed)からCharacterMovement内の変数(MaxWalkSpeed)を変更したいと思います。
・プロジェクト名はSampleEditorChangeとしました。
:::

## 最終的にはこうなります
![スクリーンショット 2023-06-19 163705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/8e7caaca-eff2-f08a-c51c-ec4182887c8e.png)
(SampleEditorChangeのMaxWalkSpeedを変更すると)

↓

![スクリーンショット 2023-06-19 1640522.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/0d3d855b-0512-dc4f-903e-00ca053bfdfb.png)
(CharacterMovementのMaxWalkSpeedも同じ値に変更されます)

<br>

## プロジェクト作成

それでは手順を説明していきます。
まずはこの記事用のプロジェクトを作成します。
![スクリーンショット 2023-06-18 170230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/19d797e8-7ad6-7c15-7901-77601ed2d396.png)

プロジェクトが開いたらC++クラスの中のSampleEditorChangeCharacterをダブルクリックします。
VisualStudioが立ち上がります。
![スクリーンショット 2023-06-19 151136.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/d641f311-29e6-41c6-a950-5f0f901b0362.png)

## .hファイル

まずSampleEditorChangeCharacter.hに変数(MaxWalkSpeed)を作成します。
```c++:SampleEditorChangeCharacter.h
public:
    UPROPERTY(EditAnywhere) // BP側で設定できるようにしておく
    float MaxWalkSpeed;
```
<br>

続いて次の関数"PostEditChangeProperty()"を記述します。
```c++:SampleEditorChangeCharacter.h
public:
    UPROPERTY(EditAnywhere) // BP側で設定できるようにしておく
    float MaxWalkSpeed;

#if WITH_EDITOR // これは条件付きコンパイルの記述。エディターのみでコンパイルされる。
	virtual void PostEditChangeProperty(struct FPropertyChangedEvent& Event) override;
#endif
```
<br>

## .cppファイル
次はcppファイルに中身を記述していきます。
SampleEditorChangeCharacter.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
```

<br>
※実際にPropertyNameに何が入っているか確認したい場合は以下の３行を追記してください。(デバッグ用)

```cpp:SampleEditorChangeCharacter.cpp
.....

#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
```

<br>

## エディターで挙動を確認

では実際にエディターで確認してみます。BP_ThirdPersonCharacterを開きます。

![スクリーンショット 2023-06-19 163501.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/35d95e2c-ee23-8e90-0b84-1e95c525afd1.png)

BP_ThirdPersonCharacter(self)を選択し、Details(詳細)にてMaxWalkSpeedで検索をかけます。
![スクリーンショット 2023-06-19 163705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/0a67bd7e-7bf9-8804-bd99-126c7c18520b.png)

SampleEditorChangeCharacterのMaxWalkSpeedの値を変更すると同時にCharacterMovementのMaxWalkSpeedの値も同じものに変更されました。これで実装は以上となります。
![スクリーンショット 2023-06-19 164052.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/08a79129-fc4a-cf88-2a4d-99855ec7c93b.png)

***

先程のデバッグコードを記述された方はエディターのOutput Logを開いてください。
値を変更するとPropertyNameに入った名前を確認することができます。
![スクリーンショット 2023-06-19 164527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110651/915146e6-c704-e513-8ff8-836ae0ad6992.png)

***