Pull to refresh

Создание системы расстановки объектов по уровню при помощи редактора blueprint. Часть 2: добавление окна пред просмотра

Reading time4 min
Views7.5K
image

Здравствуйте, меня зовут Дмитрий. Я занимаюсь созданием компьютерных игр на Unreal Engine в качестве хобби. Итак, сегодня я продолжу создание системы расстановки объектов. После того, как я её сделал я подумал, что добавление окна пред просмотра позволит ускорить процесс расстановки объектов. Об этом я сегодня и расскажу.

Если вы не читали первую часть, то рекомендую сделать это (статья). Здесь я буду приводить только код, который был изменен, для экономии места. Исходники, как всегда, можно скачать по ссылкам в конце статьи.

Сначала нужно добавить ещё одну вкладку в окно редактора файл CustAssetEditor.cpp:

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)
					)
				)


			)

		);


Важно: Если добавляете или убираете вкладку, то необходимо менять название слоя.

После этого создаем новый объект PreviewViewport.

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;
};

Здесь наиболее интересным для нас является метод MakeEditorViewportClient(). В этом методе создается объект FEditorViewportClient, которому нужно передать указатель на FPreviewScene (этот объект создан в методе Construct). Теперь, если получить указатель на мир при помощи этого объекта, а потом использовать его при создании объекта Actor, то Actor появится не в окне редактора, а в окне предпросмотра.

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

В методе MakeViewportToolbar(), как вы наверно догадались, создается панель инструментов окна предпросмотра. Здесь я создал две кнопки: одна обновляет окно предпросмотра, другая отображает свойства этого окна. Свойства окна предпросмотра аналогичны свойствам TestActor. Свойства эти хранятся не в объекте PreviewViewport, (поскольку он живет только когда открыт редактор ассета), а в объекте MyObjekt (файл 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
};

Собственно на этом все, что касается окна предпросмотра. Кроме этого, для большего удобства редактирования, я добавил возможность открывать редактор правил для нод, по двойному щелчку на эти ноды (надо только выбрать какое-нибудь правило).

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);

	}

}

На этом все.

Проект с исходным кодом здесь.
Tags:
Hubs:
+6
Comments0

Articles