［UE5］便利そうなUPROPERTYまとめ

# 概要
この記事では、今年2023年に新卒ゲームプログラマとして働き始めた、Unreal Engine 初心者である筆者が UPROPERTY の一覧を見て、使ったことがない、もしくはあまりないけど、便利そうで今後使えそうだなと思った UPROPERTY をまとめて、紹介させていただきます。


# この記事の主な対象者
- Unreal Engine の C++ 初心者の方


# UPROPERTY

### DisplayName
```cpp
UPROPERTY( meta = (DisplayName = "[Blueprintエディタでの表示名]") )
```
Blueprintのイベントグラフや、詳細パネルで表示される変数名を、指定した名前にすることができます。
「プログラマのみが見るプログラムではより詳細な変数名にしておきたいけど、プログラマ以外の人が見るエディタでは、わかりやすさ重視の名前にしたい」というようなときに使えると思います。


```cpp
// Playerの1秒間当たりの移動量
UPROPERTY( BlueprintReadWrite, EditAnywhere, meta = (DisplayName = "Player Speed") )
    FVector PlayerVelocitySec = FVector::ZeroVector;
```
![displayname.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/7dbd9604-e226-98c6-0fb8-fbf107fbcab4.jpeg)
<br>

### DisplayPriority
```cpp
UPROPERTY( meta = (DisplayPriority = [表示の優先度]) )
```
エディタの詳細パネルにおける表示順の優先度をつけることができ、優先度の値が小さいほど、上に表示されます。
「DisplayPriority」をつけていない状態だと、ヘッダファイルで宣言した順番通りに表示されます。

例）
```cpp
UPROPERTY( EditDefaultsOnly, meta = (DisplayPriority = 1) )
    int NumPriority1 = 0;

UPROPERTY( EditDefaultsOnly, meta = (DisplayPriority = 0) )
    int NumPriority0 = 0;

UPROPERTY( EditDefaultsOnly )
    int NumPriorityNone1 = 0;

UPROPERTY( EditDefaultsOnly )
    int NumPriorityNone0 = 0;
```

![displaypriority.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/4b7a5399-598c-235b-87fd-27836c9cfcc5.jpeg)
<br>


### EditCondition
```cpp
UPROPERTY( meta = (EditCondition = "[編集できるときの条件式]") )
```
「EditCondition」プロパティで指定した条件式を満たしていないときは、下図のように「EditCondition」プロパティをつけた変数をエディタ上で編集できない状態になります。

例)
```cpp
// 攻撃力
UPROPERTY( EditAnywhere )
    float AttackPower = 10.0f;

// 攻撃力が100以上ある場合、必殺技を使わせることもできる
UPROPERTY( EditAnywhere, meta = (EditCondition = "AttackPower >= 100.0") )
    bool bCanUseSpecialAttack = false;
```
![editcondition.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/f78c4ea4-0626-14d9-5410-49488244cad5.jpeg)
<br>


### InlineEditConditionToggle
```cpp
UPROPERTY( meta = (InlineEditConditionToggle) )
```
下のように「EditCondition」プロパティと組み合わせて使用します。
「InlineEditConditionToggle」プロパティをつけたbool変数を「EditCondition」プロパティに指定すると、「InlineEditConditionToggle」プロパティをつけたbool変数と「EditCondition」プロパティをつけた変数が結びつき、エディタ上では1行で表示されます。

例）
```cpp
// 攻撃をできるならばtrue
UPROPERTY( EditAnywhere, meta = (InlineEditConditionToggle) )
    bool bCanAttack = true;

// 攻撃できるなら、攻撃力を設定できるようにする
UPROPERTY( EditAnywhere, meta = (EditCondition = "bCanAttack") )
    float AttackPower = 10.0f;
```

![inlineeditconditiontoggle2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/238b3ca5-c958-83c3-86d9-b8ed325cf23f.jpeg)

（上図の赤丸のチェックボックスが「bCanAttack」となっています。「bCanAttack」がtrueになっていないと、「AttackPower」は編集できません。）
<br>


### Multiple
```cpp
UPROPERTY( meta = (Multiple = [倍数の値]) )
```
エディタの詳細パネル上で、指定した倍数の値になるように補正がかかります。

例）
偶数の値だけが入るように、2の倍数の値になるようにします。
```cpp
// 2の倍数、0以上の整数値
UPROPERTY( BlueprintReadWrite, EditAnywhere, meta = (ClampMin = 0,  Multiple = 2) )
    int EvenNum = 0;
```

<iframe width="640" height="360" src="https://www.youtube.com/embed/fvto5Zk1sLI" title="multiple 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

下図のように、エディタの詳細パネル以外の場所からは、指定した倍数の値にするための補正はかからないので、注意します。

![multiple2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/b534b250-2656-1c65-8bfd-d1a79a7ed4a3.jpeg)

![multiple3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/22dace0e-2067-c1ea-868a-315550dc31b7.jpeg)
<br>


### ForceUnits
```cpp
UPROPERTY( meta = (ForceUnits = "[値の単位]") )
```
特定の単位の値になるように、補正を書けることができます。

使用できる単位については、株式会社ヒストリア様が下記の記事にまとめてくださっていたので、下記の記事を参考にされると良いと思います。

https://historia.co.jp/archives/36394/


例)
```cpp
// 走り続けられる時間の最大値（秒）
UPROPERTY( EditAnywhere, meta = (ClampMin = 0, ForceUnits = "s") )
	float MaxRunningTime = 0;
```

<iframe width="640" height="360" src="https://www.youtube.com/embed/HxN3CwUEEIY" title="forceunits 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


変数名のsuffix（接尾語）に「Sec」などの単位をつけなくても、エディタ上に単位が表示されてわかりやすくなるので、変数名をすっきりさせることができるとともに、見やすくできそうと思いました。


### MultiLine
```cpp
UPROPERTY( meta = (MultiLine = true) )
```
「Shift + Enter」で、改行して入力することができるようになります。

```cpp
UPROPERTY( EditAnywhere, meta = (MultiLine = true) )
    FString TalkText = "";
```

![multiline.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/1a6302ab-032b-df7b-42d8-c7f7feb2a8fa.jpeg)
<br>


### TitleProperty
```cpp
UPROPERTY( meta = (TitleProperty = "[タイトルとして使用する構造体の中の変数名]") )
```
構造体の配列などに使用します。
エディタ上の配列の要素の見出しに、指定した構造体の中の変数名に設定された値が表示されるようになります。

例）
```cpp
USTRUCT( BluepritType )
struct FCharacterStatus
{
    GENERATED_BODY()

public:
    UPROPERTY( EditDefaultsOnly )
        FString Name = "";

    UPROPERTY( EditDefaultsOnly )
        int HP = 10;

    UPROPERTY( EditDefaultsOnly )
        int AttackPower = 10;
}
```
```cpp
UPROPERTY( EditAnywhere, meta = (TitleProperty = "Name") )
    TArray<FCharacterStatus> StatusArray;
```

![titleproperty.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/125dcec6-ee00-5cd8-0e74-31e07e8ac83e.jpeg)
<br>


### AllowPreserveRatio
```cpp
UPROPERTY( meta = (AllowPreserveRatio) )
```
FVectorなどにおいて、ほかの入力できる項目との比率を保った状態で値を編集できるようになります。

例）
```cpp
UPROPERTY( EditAnywhere, meta = (AllowPreserveRatio) )
    FVector TestScale = FVector::ZeroVector;
```

<iframe width="640" height="360" src="https://www.youtube.com/embed/3bdkDD6Xb0Q" title="allowpreserveratio 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br>


### BlueprintSetter、BlueprintGetter
```cpp
UPROPERTY( BlueprintGetter = [値を取得するのに使用する関数名], BlueprintSetter = [値をセットするのに使用する関数名] )
```


例）
```cpp
UPROPERTY( EditAnywhere, BlueprintReadWrite, BlueprintSetter = SetTalkText, BlueprintGetter = GetTalkText )
	FString TalkText = "";

// イベントグラフ上でTalkText変数に文字列を代入するときに呼ばれる関数
UFUNCTION(BlueprintSetter)
	void SetTalkText(FString text);

// イベントグラフ上でTalkText変数から文字列を取得するときに呼ばれる関数
UFUNCTION(BlueprintGetter)
	FString GetTalkText();
```

```cpp
void ATestActor::SetTalkText(FString text)
{
	TalkText = "Hello " + text;
}

FString ATestActor::GetTalkText()
{
	return TalkText + " !!";
}
```
（「ATestActor」クラスは、テスト用に作成したアクタのクラスです。）

上のような処理を実装したとき、下のようなノードを組むと、セットノードを呼んだときに SetTalkText 関数が呼ばれ、ゲットノードを呼んだときに GetTalkText 関数が呼ばれるので、下のように出力されます。

![settergetter1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/1709278e-736d-c160-1eef-c1a0ae4e3555.jpeg)

![settergetter2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/3b7d9f8c-50a6-7753-66f6-155ab23539c9.jpeg)
<br>


### ExposeOnSpawn
```cpp
UPROPERTY( meta = (ExposeOnSpawn = true) )
```
アクタをスポーンするノードに、入力ピンとして追加されるようになります。
「BlueprintReadOnly」か「BlueprintReadWrite」をつけないと、エラーが出るので注意しましょう。

```cpp
UPROPERTY( EditAnywhere, meta = (ExposeOnSpawn = true) )
    float LifeTime = 30.0f;
```
（上の変数を定義したクラスは、テスト用に作成した「ATestActor」クラスです。）

![exposeonspawn.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/66db92a3-8bd2-94db-d1be-0a52366bc273.jpeg)
<br>

 
### Categories
```cpp
UPROPERTY( meta = (Categories = "表示したいGameplayTagのカテゴリ名") )
```
GameplayTagをエディタで指定するとき、指定したGameplayTagのカテゴリ以外のGameplayTagが表示されなくなります。

例）
```cpp
// 「Categories」をつけない場合
UPROPERTY( EditAnywhere )
    FGameplayTag TestTag = FGameplayTag::EmptyTag;

// 「Categories」をつけて、「Test1」カテゴリしか表示しないようにした場合
UPROPERTY( EditAnywhere, meta = (Categories = "Test1") )
    FGameplayTag TestTagWithCategories = FGameplayTag::EmptyTag;
```
「Categories」をつけた変数の方は、下図の右のように指定したカテゴリのGameplayTagのみを表示し、不要なカテゴリを表示しないようにできます。

![categories.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/0a7d4376-21e1-122b-910e-4ec018d0990b.jpeg)

（GameplayTagはテスト用に適当に用意したものです。）
<br>


### Interp
```cpp
UPROPERTY( Interp )
```
シーケンサー内のタイムラインで、値を編集できるようになります。



# 参考文献
(1) ben🌱ui , "All UPROPERTY Specifiers · ben🌱ui", https://benui.ca/unreal/uproperty/, （参照 2023-12-11）

https://benui.ca/unreal/uproperty/

<br>

(2) 株式会社ヒストリア, [UE5]プロパティの数値入力欄に単位を追加しよう, https://historia.co.jp/archives/36394/, （参照 2023-12-12）

https://historia.co.jp/archives/36394/