📜 ⬆️ ⬇️

Creating a system of placing objects by level using the blueprint editor. Part 2: Adding a Preview Window

image

Hello, my name is Dmitry. I create computer games on the Unreal Engine as a hobby. So, today I will continue to create a system of placement of objects. After I did it, I thought that adding a preview window would speed up the process of placing objects. I will tell about it today.

If you have not read the first part, I recommend to do it ( article ). Here I will give only the code that was changed to save space. Sources, as always, can be downloaded from the links at the end of the article.

First you need to add another tab to the editor window of the CustAssetEditor.cpp file:
')
const TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout("CustomEditor_Layout_2") ->AddArea ( FTabManager::NewPrimaryArea() ->SetOrientation(Orient_Vertical) ->Split ( FTabManager::NewStack() ->SetSizeCoefficient(0.1f) ->SetHideTabWell(true) ->AddTab(GetToolbarTabId(), ETabState::OpenedTab) ) ->Split ( FTabManager::NewSplitter() ->SetOrientation(Orient_Horizontal) ->SetSizeCoefficient(0.2f) ->Split ( FTabManager::NewStack() ->SetSizeCoefficient(0.75f) ->SetHideTabWell(true) ->AddTab(FCustomEditorTabs::ViewportID, ETabState::OpenedTab) ) ->Split ( FTabManager::NewSplitter() ->SetOrientation(Orient_Vertical) ->SetSizeCoefficient(0.25f) ->Split ( FTabManager::NewStack() ->SetSizeCoefficient(0.35f) ->SetHideTabWell(true) ->AddTab(FCustomEditorTabs::DetailsID, ETabState::OpenedTab) ) ->Split ( FTabManager::NewStack() ->SetSizeCoefficient(0.65f) ->SetHideTabWell(true) ->AddTab(FCustomEditorTabs::PreviewID, ETabState::OpenedTab) ) ) ) ); 

Important: If you add or remove a tab, you need to change the name of the layer.

After that we create a new PreviewViewport object.

 TPreviewViewport = SNew(SCustomEditorViewport) .CustomEditor(SharedThis(this)) .ObjectToEdit(PropBeingEdited); class SCustomEditorViewport : public SEditorViewport//, public FGCObject { public: SLATE_BEGIN_ARGS(SCustomEditorViewport){} SLATE_ARGUMENT(TWeakPtr<FCustAssetEditor>, CustomEditor) SLATE_ARGUMENT(UMyObject*, ObjectToEdit) SLATE_END_ARGS() void Construct(const FArguments& InArgs); ~SCustomEditorViewport(); void SetParentTab(TSharedRef<SDockTab> InParentTab) { ParentTab = InParentTab; } EVisibility GetToolbarVisibility() const; FReply OnRebildScen(); FReply OnShowPropertyPreview(); void RebildScen(); protected: /** SEditorViewport interface */ virtual TSharedRef<FEditorViewportClient> MakeEditorViewportClient() override; virtual EVisibility OnGetViewportContentVisibility() const override; virtual void OnFocusViewportToSelection() override; virtual TSharedPtr<SWidget> MakeViewportToolbar() override; private: bool IsVisible() const; void DestroyActors(); FName ActorTag; TWeakPtr<FCustAssetEditor> CustomEditorPtr; UMyObject* ObjectToEdit; TWeakPtr<SDockTab> ParentTab; TSharedPtr<class FEditorViewportClient> EditorViewportClient; TSharedPtr<FPreviewScene> PreviewScene; USkyLightComponent* Skylight; UAtmosphericFogComponent* AtmosphericFog; }; 

Here the most interesting for us is the MakeEditorViewportClient () method. In this method, an FEditorViewportClient object is created that needs to pass a pointer to an FPreviewScene (this object was created in the Construct method). Now, if you get a pointer to the world using this object, and then use it when creating an Actor object, then Actor will appear not in the editor window, but in the preview window.

 World = PreviewScene->GetWorld(); World->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), FVector(0, 0, 0), FRotator(0, 0, 0)); 

In the MakeViewportToolbar () method, you guessed it, a preview window toolbar is created. Here I created two buttons: one updates the preview window, the other displays the properties of this window. The properties of the preview window are similar to those of TestActor. These properties are not stored in the PreviewViewport object (because it lives only when the asset editor is open), but in the MyObjekt object (the file MyObjekt.h).

 UCLASS() class UCustomEditorViewportProperties : public UObject { GENERATED_BODY() public: UPROPERTY(EditAnywhere, BlueprintReadWrite) TArray<FRoot> Roots; }; UCLASS(Blueprintable) class UICUSTOM_API UMyObject : public UObject { GENERATED_UCLASS_BODY() public: UPROPERTY(EditAnywhere, Category = "My Object Properties") FString Name; URootNode* FindRootFromType(ERootType RootType); UPROPERTY() UEdGraph* UpdateGraph; #if WITH_EDITORONLY_DATA UPROPERTY() UCustomEditorViewportProperties* PreviewViewportProperties; #endif // WITH_EDITORONLY_DATA }; 

Actually that's all about the preview window. In addition, for more convenient editing, I added the ability to open the rule editor for nodes by double-clicking on these nodes (you just need to select a rule).

 void FCustAssetEditor::OnNodeDoubleClicked(class UEdGraphNode* Node) { ((UCustomNodeBase*)Node)->DoubleClicke(); } void URuleNode::DoubleClicke() { FStreamableManager AssetLoader; TArray<FString> Name; if (Rule) { Name.Add(Rule->GetPathName()); FAssetEditorManager::Get().OpenEditorsForAssets(Name); } } 

That's all.

Source project here .

Source: https://habr.com/ru/post/278491/


All Articles