概要
例えば指定距離進むアクタがあったとします
基本はゲームをプレイしてどのような動きにするか確認する必要があります。
もしくは動きをマップ上で確認した上で計算してパラメータを入力するなどですが、マッパーの負担になります。
確認用パラメータを用意することは可能ですが、パラメータが設定された状態で動かしたりすると大変です。
そこでちょっとしたテクニックを使って安全なデバッグパラメータを作成してみます。
仕様
矢印の方向に指定距離動くというアクタを作成します。
移動する足場、プレスする天井など、用途は様々かと思います。
実装
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::*
)を呼ぶ必要があります!
もし挙動がおかしいなどあったらここが原因なことがよくあったので使用する場合は必ず確認しましょう。
(ないといけないものって知識がないとわからないのでハマりやすい罠です。)
今回はOnConstruction
とPostEditChangeProperty
を使用します。
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);
}
これを実行してみると以下のようになります。
debugRate_
のスライダーを離すと0に戻っています。
これでエディタ上で安全に移動の確認ができました。
ただし、レベル上の変更としてDirtyになってしまうので複数人でレベルを操作するときは気を付ける必要があります。
まとめ
-
PostEditChangeProperty
を用いて移動確認用デバッグパラメータを作る -
PostEditChangeProperty
などの関数は親クラスの関数(Super::*
)を呼ぶ必要がある
以上、快適なアンリアルライフを送りましょう。