Створення системи розміщення об'єктів по рівню за допомогою редактора blueprint. Частина 2: додавання вікна перед перегляду

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.1 f)
->SetHideTabWell(true)
->AddTab(GetToolbarTabId(), ETabState::OpenedTab)
)
->Split
(
FTabManager::NewSplitter()
->SetOrientation(Orient_Horizontal)
->SetSizeCoefficient(0.2 f)
->Split
(

FTabManager::NewStack()
->SetSizeCoefficient(0.75 f)
->SetHideTabWell(true)
->AddTab(FCustomEditorTabs::ViewportID, ETabState::OpenedTab)

)
->Split
(
FTabManager::NewSplitter()
->SetOrientation(Orient_Vertical)
->SetSizeCoefficient(0.25 f)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.35 f)
->SetHideTabWell(true)
->AddTab(FCustomEditorTabs::DetailsID, ETabState::OpenedTab)
)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.65 f)
->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);

}

}

На цьому все.

Проект з кодом тут.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.