Unreal Engine 4でアセットタイプを作成し、プロパティバーをカスタマイズします





こんにちは私の名前はドミトリーです。 私は趣味としてアンリアルエンジンでコンピューターゲームを作っています。 今日は、Unreal Engineで独自のアセットタイプを作成する方法と、アセットプロパティパネルに追加の要素を追加する方法を説明したいと思います。 それでは始めましょう。



アセットを作成することから始めましょう。 まず、アセットのクラスを作成する必要があります。



UCLASS() class UICUSTOM_API UMyObject : public UObject { GENERATED_BODY() public: UPROPERTY(EditAnywhere, Category = "My Object Properties") FString Name; };
      
      





その後、アセットをコンテンツブラウザに表示する必要がありますこれを行うには、UFactoryクラスの子孫を作成します。



 UCLASS() class UICUSTOM_API UMyObjectFactory : public UFactory { GENERATED_UCLASS_BODY() // UFactory interface virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override; // End of UFactory interface virtual bool CanCreateNew() const override; };
      
      





ここで、私たちにとって最も重要なメソッドは、クラスをインスタンス化するFactoryCreateNewです。



 UObject* UMyObjectFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) { UMyObject* NewObjectAsset = NewObject<UMyObject>(InParent,Class, Name, Flags | RF_Transactional); return NewObjectAsset; }
      
      





そのため、コンテンツブラウザーで既にアセットを作成できますが、名前、アイコンの色、カテゴリを選択することはできません。 これらすべてのために、別のクラス、FAssetTypeActions_Baseの子孫を作成する必要があります。



 class UICUSTOM_API FMyObjectAssetAction : public FAssetTypeActions_Base { public: virtual FText GetName() const override; virtual FColor GetTypeColor() const override; virtual UClass* GetSupportedClass() const override; virtual bool HasActions(const TArray<UObject*>& InObjects) const override { return false; } virtual uint32 GetCategories() override; static void RegistrateCustomPartAssetType(); };
      
      





RegistrateCustomPartAssetType()メソッドを除くメソッドの名前によって、プリンター内のすべてが明確になります。 このメソッドは、このクラスを登録するために必要です。 それでどこから呼び出されるのですか? このメソッドは、エディターをロードするときに1回呼び出す必要があるため、呼び出すのに最適な場所はGameModeコンストラクターです。 それは実際にはそれです:



 AUICustomGameMode::AUICustomGameMode() { #if WITH_EDITORONLY_DATA FMyClassDetails::RegestrateCostumization(); FMyObjectAssetAction::RegistrateCustomPartAssetType(); #endif //WITH_EDITORONLY_DATA }
      
      





その後、プロジェクトをコンパイルして結果を楽しむことができます。







おそらく尋ねるでしょう。 しかし、ポイントは何ですか、私はMyObjectを継承する鈍器を作成することもできます。hemoを使わずに同じことを行うことができます。 ここでは、ブループリントが自分ではなくMyObjectのクラス継承であることを明確にする必要があります。



たとえば、MyObjectへのリンクを他のアセットに配置する場合、この方法で作成されたアセットを選択できますが、このアセットが基本的なブループリントはありません。







ご覧のとおり、資産はありますが、設計図はありません。



それでは、アセットプロパティパネルに要素を追加します。 これを行うには、実験クラスを作成します。



 UCLASS() class UICUSTOM_API ATestAct : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties ATestAct(); // Called when the game starts or when spawned virtual void BeginPlay() override; // Called every frame virtual void Tick( float DeltaSeconds ) override; UPROPERTY(EditAnywhere, BlueprintReadWrite) UMyObject* MyObject; };
      
      





プロパティパネルをカスタマイズするには、IDetailCustomizationクラスの子孫を作成する必要があります。



 class FMyClassDetails : public IDetailCustomization { public: static FReply MClick(IDetailLayoutBuilder* DetailBuilder); /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef<IDetailCustomization> MakeInstance(); static void RegestrateCostumization(); /** IDetailCustomization interface */ virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; static void ShowNotification(FText Text, SNotificationItem::ECompletionState State = SNotificationItem::CS_None); static ATestAct* GetObject(IDetailLayoutBuilder* DetailBuilder); };
      
      





そのため、追加したボタンをクリックするとMClickメソッドが機能することを明確にします(例として、ボタンを選択しましたが、任意のインターフェイス要素を使用できます)。



新しい項目が詳細パネルに追加されるCustomizeDetailsメソッド:



 void FMyClassDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) { // Create a category so this is displayed early in the properties ATestAct* TestAct = GetObject(&DetailBuilder); IDetailCategoryBuilder& MyCategory = DetailBuilder.EditCategory("Button", FText::GetEmpty(), ECategoryPriority::Important); //You can get properties using the detailbuilder //MyProperty= DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(MyClass, MyClassPropertyName)); FText TestHUDText = FText::FromString("Your Text"); MyCategory.AddCustomRow(TestHUDText) .ValueContent() //NameContent() [ SNew(SButton) .Text(FText::FromString("ShowMessage")) .OnClicked(FOnClicked::CreateStatic(&FMyClassDetails::MClick, &DetailBuilder)) ]; }
      
      





RegestrateCostumizationこのカスタマイズの登録に必要な方法。 (おそらく、GameModeコンストラクターからの彼の呼び出しに気付きました)TestActはAプレフィックスなしで入力する必要があることに注意してください。



 void FMyClassDetails::RegestrateCostumization() { FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor"); //Custom detail views PropertyModule.RegisterCustomClassLayout("TestAct", FOnGetDetailCustomizationInstance::CreateStatic(&FMyClassDetails::MakeInstance)); }
      
      





ShowNotificationは、画面にメッセージを表示するだけです。 GetObjectカスタムオブジェクト(この場合はATestAct)への参照を取得します。



そのため、結果は次のようになります。







ご清聴ありがとうございました。このレッスンにより、より良い、より面白いゲームを作成できることを願っています。



ソースコードプロジェクトは こちらです。



PSちょっとした説明。 1行に複数のボタンを挿入する場合は、次のように記述する必要があります。

 SNew(SHorizontalBox) + SHorizontalBox::Slot() [ SNew(SButton) .Text(FText::FromString("OK")) ] + SHorizontalBox::Slot() [ SNew(SButton) .Text(FText::FromString("OK")) ]
      
      





必要なボタンの数が事前にわからない場合は、次のように記述できます。

 TSharedPtr<SHorizontalBox> Container = SNew(SHorizontalBox); for (int32 idx = 0; idx < 2; idx++) { Container->AddSlot() [ SNew(SButton) .Text(FText::FromString("OK")) ]; } MyCategory.AddCustomRow(TestHUDText) .ValueContent() [ Container.ToSharedRef() ];
      
      






All Articles