UE5 独自UIプラグインを作成する 03 ~UIから入力した2次元座標でViewportのFloorを動かす~
【今回のポジティブワード】
努力するものが
楽しむ者に
勝てるワケがない
~範馬刃牙~
つい癖で人に教えるように書いてしまい「真面目か!」という内容になっていってしまいます。大事なことなのですが、少し硬くなって努力が見えてきてしまいます。
楽しんで書いて、出来ることを増やしていける方が読む側としても楽しいはず。
楽しむことは努力すること以上に大切です。
前回は「Windowに基本的な部品を追加する」方法について調査しました。
今回は「入力した2次元座標でViewportのFloorを動かす」方法について調査していきます。
前回からの続きになります。
入力した2次元座標でViewportのFloorを動かす
目標とする動作
プラグインらしく、ビューポート内のアクタを動かす処理を実装してみます。
デフォルトのレベルに置かれているFloorをX,Y座標だけプラグインのUIから動かします。
今回学習できること
2次元座標を操作するUIの作成
ビューポート上のアクタを動かす
2次元座標を操作するUIの作成
2次元座標(X、Y)を設定する入力項目と、Floorを動かす処理を実装するためのボタンを実装します。
まずは2次元座標の値を保持するための変数と、入力した際に変数の値を保持するための関数をヘッダに定義します。
(プラグイン名).h
Public:
// X座標側の関数
TOptional<int32> GetCoordinate2DX() const { return Coordinate2D.X; }
void SetCoordinate2DX(int32 NewValue);
void SetCoordinate2DXCommit(int32 NewValue, ETextCommit::Type);
// Y座標側の関数
TOptional<int32> GetCoordinate2DY() const { return Coordinate2D.Y; }
void SetCoordinate2DY(int32 NewValue);
void SetCoordinate2DYCommit(int32 NewValue, ETextCommit::Type);
private:
// 2次元座標
FIntPoint Coordinate2D;
ヘッダで定義した関数を実装します。
(プラグイン名).cpp ヘッダーで定義した関数の処理
void FpositaUIModule::SetCoordinate2DX(int32 NewValue)
{
Coordinate2D.X = NewValue;
}
void FpositaUIModule::SetCoordinate2DXCommit(int32 NewValue, ETextCommit::Type)
{
SetCoordinate2DX(NewValue);
}
void FpositaUIModule::SetCoordinate2DY(int32 NewValue)
{
Coordinate2D.Y = NewValue;
}
void FpositaUIModule::SetCoordinate2DYCommit(int32 NewValue, ETextCommit::Type)
{
SetCoordinate2DY(NewValue);
}
2次元座標(X、Y)を設定する入力項目とボタンのUIを作成する処理をOnSpawnPluginTab関数に追加します。
OnSpawnPluginTab関数にUIを追加します。
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(10.0f, 3.0f, 10.0f, 3.0f)
.VAlign(VAlign_Center)
.AutoWidth()
[
SNew(SButton)
.Text(LOCTEXT("Coordinate_Button", "Coordinate"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(0.0f, 3.0f, 8.0f, 3.0f)
[
SNew(SNumericEntryBox<int32>)
.IsEnabled(true)
.AllowSpin(true)
.MinSliderValue(-10000)
.MaxSliderValue(10000)
.Value_Raw(this, &FpositaUIModule::GetCoordinate2DX)
.OnValueChanged_Raw(this, &FpositaUIModule::SetCoordinate2DX)
.OnValueCommitted_Raw(this, &FpositaUIModule::SetCoordinate2DXCommit)
.AllowSpin(true)
.MinDesiredValueWidth(75)
.Label()
[
SNew(SBox)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(LOCTEXT("Coordinate2D_X", "X"))
]
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(0.0f, 3.0f, 8.0f, 3.0f)
[
SNew(SNumericEntryBox<int32>)
.IsEnabled(true)
.AllowSpin(true)
.MinSliderValue(-10000)
.MaxSliderValue(10000)
.Value_Raw(this, &FpositaUIModule::GetCoordinate2DY)
.OnValueChanged_Raw(this, &FpositaUIModule::SetCoordinate2DY)
.OnValueCommitted_Raw(this, &FpositaUIModule::SetCoordinate2DYCommit)
.AllowSpin(true)
.MinDesiredValueWidth(75)
.Label()
[
SNew(SBox)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(LOCTEXT("Coordinate2D_Y", "Y"))
]
]
]
]
コンパイルすると目的としていたUIが追加されています。
ボタンにViewportのFloorを動かす処理を実装する
まずはヘッダファイルにボタンのクリックしたときに動作する関数を定義します。
(プラグイン名).h
Public:
// CoordinateButtonをクリックした時の処理
FReply CoordinateButtonClicked();
Viewport内のStaticMeshを取得します。
Label名がFloorのStaticMeshのみをUIかどうかを判定します。
UI設定したX,Yの値をFloorのLocationのX,Yに設定します。ZはFloorの値を変更せずに設定します。
(プラグイン名).cpp ヘッダーで定義した関数の処理
// 関数の処理内で必要となるヘッダのIncludeを追加します
#include "EngineUtils.h"
#include "Runtime/Engine/Classes/Engine/StaticMeshActor.h"
FReply FpositaUIModule::CoordinateButtonClicked()
{
UWorld* world = GEditor->GetEditorWorldContext().World();
for (TActorIterator<AStaticMeshActor> actorItr(world); actorItr; ++actorItr)
{
FString staticMeshName = actorItr->GetActorLabel();
if(staticMeshName.Equals(TEXT("Floor")))
actorItr->SetActorLocation(FVector(Coordinate2D.X, Coordinate2D.Y, actorItr->GetActorLocation().Z));
}
return FReply::Handled();
}
ボタンをクリックした際にCoordinateButtonClicked関数を呼び出すように設定します。
SNew(SButton)
.Text(LOCTEXT("Coordinate_Button", "Coordinate"))
.OnClicked_Raw(this, &FpositaUIModule::CoordinateButtonClicked)
Floorだけ動くか確認吸うためにCubeをViewportに追加します。
コンパイルして、UIでX、Yの値を変更し、Coordinateボタンをクリックします。
FloorだけUIから設定した値で動かすことが出来ました。
まとめ
操作する部品を増やそうかと考えて記事を書いていましたが、楽しくなかったので、急遽Viewportのアクタを動かすように内容を書きながら変更しました。
やはり、楽しい方に舵を切った方が調べていて楽しかったですし、身に付いたことが実感できました。
UIからWindow外を操作するとプラグインらしくて楽しいですね。
当面行き当たりばったりで書いていくことになりますが、楽しい方で出来ることを増やしていきます。