0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【UE4】エディタ上で移動を確認できるスライダーを用意する【C++】

Posted at

概要

例えば指定距離進むアクタがあったとします
基本はゲームをプレイしてどのような動きにするか確認する必要があります。
もしくは動きをマップ上で確認した上で計算してパラメータを入力するなどですが、マッパーの負担になります。
確認用パラメータを用意することは可能ですが、パラメータが設定された状態で動かしたりすると大変です。
そこでちょっとしたテクニックを使って安全なデバッグパラメータを作成してみます。

仕様

矢印の方向に指定距離動くというアクタを作成します。
移動する足場、プレスする天井など、用途は様々かと思います。

実装

UObjectにはいくつか編集用の関数が用意されています。
少しだけ紹介してみます。

// 移動やプロパティの変更など幅広く呼ばれる関数
void OnConstruction(const FTransform& Transform);
// プロパティ編集前に呼ばれる関数
void PreEditChange(FEditPropertyChain& PropertyAboutToChange);
// プロパティ編集後に呼ばれる関数
void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent);
// 移動後に呼ばれる関数(bFinisheedはドラッグ移動などで移動完了後にtrueになる)
void PostEditMove(bool bFinished);
// Undo前に呼ばれる関数
void PreEditUndo();
// Undo後に呼ばれる関数
void PostEditUndo()
// 複製前に呼ばれる関数
void PreDuplicate(FObjectDuplicationParameters& DupParams);
// 複製後に呼ばれ鵜関数(PIEはPlay In Editorで、エディタ上でプレイする場合も内部で複製処理をしているためそのこと)
PostDuplicate(bool bDuplicateForPIE);

正直OnConstruction以外はあんまり頻出ではないですね。
Undo系は怖いのでなかなか手が出せません。アセット使用者が変にUndoしないように祈りましょう。
Duplicate系はOnConstructionなどでコンポーネントを生成している系は複製時に複製元のコンポーネントが参照されてしまう上に
コンポーネントまで複製されてしまうので、それをどうにかするという手があります。
個人的にはOnConstructionでコンポーネント全部取得してUActorComponent::IsDefaultSubobject関数で判定し、
非デフォルトなコンポーネントは削除しちゃうのが楽です(これで一本記事書けるなぁ。)
一番大事なことですがOnConstruction関数を除いた他のすべての関数は、
BeginPlayなどと同様に親クラスの関数(Super::*)を呼ぶ必要があります!
もし挙動がおかしいなどあったらここが原因なことがよくあったので使用する場合は必ず確認しましょう。
(ないといけないものって知識がないとわからないのでハマりやすい罠です。)

今回はOnConstructionPostEditChangePropertyを使用します。
PostEditChangePropertyの引数のPropertyAboutToChangeにはChangeTypeというパラメータがあり、
EPropertyChangeType::ValueSetで値が確定した時を判別できます。
これを使用してデバッグ用パラメータを初期化しちゃいます。
また、ベースとなる位置を取得したいのでOnConstructionで位置を取得します。
配置するときに最初だけ先にPostEditMoveより先にPostEditChangePropertyが来てしまうので、
順序の速いOnConstructionで値をとっておきます。
(PostEditMoveは移動中は重くて行えないような処理を移動完了時に行う時ぐらいしか使い道はないです…自分は過去に一回だけ使いました)
ベースとなる位置の変数(baseLocation_)はレベル開きなおしても値を保持するようにUPROPERTY()をつけておきましょう。
moveDistance_は移動距離として公開、debugRate_は0~1でクランプして公開してあります。

void AArrowMoveBox::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);
	
	baseLocation_ = GetActorLocation();
}

# if WITH_EDITOR
void AArrowMoveBox::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet)
	{
		debugRate_ = 0.f;
	}

	SetRateLocation(debugRate_);
}
# endif

void AArrowMoveBox::SetRateLocation(float rate)
{
	const FVector direction = arrow_->GetForwardVector();
	const FVector location = FMath::Lerp(baseLocation_, baseLocation_ + direction * moveDistance_, rate);
	SetActorLocation(location);
}

これを実行してみると以下のようになります。

ArrowMoveBox00.gif

debugRate_のスライダーを離すと0に戻っています。
これでエディタ上で安全に移動の確認ができました。
ただし、レベル上の変更としてDirtyになってしまうので複数人でレベルを操作するときは気を付ける必要があります。

まとめ

  • PostEditChangePropertyを用いて移動確認用デバッグパラメータを作る
  • PostEditChangePropertyなどの関数は親クラスの関数(Super::*)を呼ぶ必要がある

以上、快適なアンリアルライフを送りましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?