File CollisionDataEditorToolkit.cpp
File List > CollisionEditor > Private > CollisionDataEditorToolkit.cpp
Go to the documentation of this file
#include "CollisionDataEditorToolkit.h"
#include "Logging.h"
#include "CelAssetTree.h"
#include "Battle/Objects/PlayerObject.h"
#include "Data/CollisionData.h"
#include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
#include "Viewport/CollisionAnimationPreviewScene.h"
#include "Viewport/CollisionAnimationViewport.h"
#include "Widgets/Docking/SDockTab.h"
#include "Widgets/Layout/SBorder.h"
#include "Widgets/Text/STextBlock.h"
#define LOCTEXT_NAMESPACE "NightSkyCollisionEditor"
FCollisionDataEditorToolkit::FCollisionDataEditorToolkit()
{
}
FCollisionDataEditorToolkit::~FCollisionDataEditorToolkit()
{
}
void FCollisionDataEditorToolkit::Initialize(UCollisionData* InCollisionData, const EToolkitMode::Type Mode,
const TSharedPtr<IToolkitHost>& InitToolkitHost)
{
CollisionData = InCollisionData;
for (auto& Collision : CollisionData->CollisionFrames)
{
for (auto& Box : Collision.Boxes)
{
Box.EditorInit();
}
}
// Setup details view
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
FDetailsViewArgs DetailsViewArgs;
DetailsViewArgs.bUpdatesFromSelection = true;
DetailsViewArgs.bLockable = false;
DetailsViewArgs.bAllowSearch = true;
DetailsViewArgs.bHideSelectionTip = true;
DetailsView = PropertyModule.CreateDetailView(DetailsViewArgs);
DetailsView->SetObject(CollisionData);
// Setup PlayerObject BP picker
InitializePlayerObjectBPPicker();
// Setup cel asset tree
InitializeCelAssetTree();
#if WITH_EDITORONLY_DATA
// Subscribe to collision frames changes to refresh tree
CollisionData->OnCollisionFramesChanged.AddSP(this, &FCollisionDataEditorToolkit::OnCollisionFramesChanged);
#endif
// Set up viewport
InitializePreviewScene();
// Define the layout
const TSharedRef<FTabManager::FLayout> StandaloneLayout = FTabManager::NewLayout(
"Standalone_CollisionDataEditor_Layout")
->AddArea
(
FTabManager::NewPrimaryArea()
->SetOrientation(Orient_Horizontal)
->Split
(
// Left side
FTabManager::NewStack()
->AddTab("PlayerObjectSelectorTab", ETabState::OpenedTab)
->SetSizeCoefficient(0.15f)
)
->Split
(
// Middle
FTabManager::NewStack()
->AddTab("ViewportTab", ETabState::OpenedTab)
->SetHideTabWell(true)
->SetSizeCoefficient(0.55f)
)
->Split
(
// Right side
FTabManager::NewStack()
->AddTab("CollisionDataDetailsTab", ETabState::OpenedTab)
->SetSizeCoefficient(0.3f)
)
);
// Register tab spawners
// Ensure the ToolkitHost is valid and has a valid TabManager
if (InitToolkitHost.IsValid() && InitToolkitHost->GetTabManager().IsValid())
{
TabManager = InitToolkitHost->GetTabManager(); // Do I need to set this or is it already set?
RegisterTabSpawners(TabManager.ToSharedRef());
}
else
{
// Handle the error condition here, e.g., log an error or assert
UE_LOG(LogCollisionEditor, Warning, TEXT("Toolkit host or tab manager is not valid."));
}
InitAssetEditor(Mode, InitToolkitHost, FName("CollisionDataEditorApp"), StandaloneLayout, true, true,
TArray<UObject*>({CollisionData}));
PreviewScene->SetupScene(CollisionData);
}
void FCollisionDataEditorToolkit::InitializePlayerObjectBPPicker()
{
PlayerObjectBPPicker = SNew(SClassPropertyEntryBox)
.MetaClass(APlayerObject::StaticClass())
.SelectedClass(PlayerObjectClass)
.OnSetClass(this, &FCollisionDataEditorToolkit::OnPlayerObjectBPSelected)
.AllowNone(false);
}
FGameplayTag FCollisionDataEditorToolkit::GetCurrentCelName() const
{
if (PlayerObject && PlayerObject->CelName.IsValid())
return PlayerObject->CelName;
return FGameplayTag::EmptyTag;
}
void FCollisionDataEditorToolkit::OnClose()
{
#if WITH_EDITORONLY_DATA
if (CollisionData)
{
CollisionData->OnCollisionFramesChanged.RemoveAll(this);
}
#endif
FAssetEditorToolkit::OnClose();
}
void FCollisionDataEditorToolkit::InitializeCelAssetTree()
{
SAssignNew(CelAssetTree, SCelAssetTree, CollisionData)
.OnCelSelected(this, &FCollisionDataEditorToolkit::OnCelSelected);
}
void FCollisionDataEditorToolkit::OnCelSelected(int32 CelIndex)
{
if (!CollisionData || !CollisionData->CollisionFrames.IsValidIndex(CelIndex))
{
return;
}
const FGameplayTag& CelName = CollisionData->CollisionFrames[CelIndex].CelName;
SelectedCel = CelName;
if (PlayerObject && CelName.IsValid())
{
PlayerObject->SetCelName(CelName);
}
#if WITH_EDITORONLY_DATA
CollisionData->EditorSelectedIndex = CelIndex;
if (DetailsView.IsValid())
{
DetailsView->ForceRefresh();
}
#endif
}
void FCollisionDataEditorToolkit::OnCollisionFramesChanged()
{
if (CelAssetTree.IsValid())
{
CelAssetTree->RefreshTree();
}
}
void FCollisionDataEditorToolkit::OnPlayerObjectBPSelected(const UClass* Class)
{
if (!Class) return;
PlayerObjectClass = const_cast<UClass*>(Class);
PlayerObject = PreviewScene->SetPlayerObject(Class);
// CollisionData->SelectedPlayerObjectClass = Class;
PlayerObject->SetCelName(SelectedCel);
UE_LOG(LogCollisionEditor, Log, TEXT("Selected PlayerObject: %s"), *PlayerObject->GetName());
}
TSharedRef<SDockTab> FCollisionDataEditorToolkit::SpawnTab_CollisionDataDetails(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.Label(LOCTEXT("CollisionDataDetailsTabLabel", "Collision Data Details"))
.TabRole(ETabRole::NomadTab)
[
SNew(SBorder)
.Padding(4)
[
DetailsView->AsShared()
]
];
}
TSharedRef<SDockTab> FCollisionDataEditorToolkit::SpawnTab_PlayerObjectSelector(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.Label(LOCTEXT("PlayerObjectSelectorTabLabel", "Cel Browser"))
.TabRole(ETabRole::NomadTab)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SBorder)
.Padding(4)
[
PlayerObjectBPPicker.ToSharedRef()
]
]
+ SVerticalBox::Slot()
.FillHeight(1.f)
[
SNew(SBorder)
.Padding(4)
[
CelAssetTree.ToSharedRef()
]
]
];
}
TSharedRef<SDockTab> FCollisionDataEditorToolkit::SpawnTab_ViewportTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.Label(LOCTEXT("ViewportTabLabel", "Viewport"))
.TabRole(ETabRole::MajorTab)
[
SNew(SBorder)
.Padding(4)
[
PreviewViewportWidget.ToSharedRef() // Make sure to use the viewport widget
]
];
}
FText FCollisionDataEditorToolkit::GetSelectedState() const
{
return FText::FromString(SelectedCel.ToString());
}
// Code to set the animation to a specific frames
void FCollisionDataEditorToolkit::UpdateAnimationPlayback(int32 Frame)
{
if (PlayerObject)
{
PlayerObject->CelIndex = Frame;
}
}
void FCollisionDataEditorToolkit::InitializePreviewScene()
{
if (!PreviewScene.IsValid())
{
PreviewScene = MakeShareable(new FCollisionAnimationPreviewScene(
FPreviewScene::ConstructionValues()
.AllowAudioPlayback(false)
.ShouldSimulatePhysics(false)
, SharedThis(this)
));
}
PreviewViewportWidget = SNew(SCollisionAnimationViewport, SharedThis(this), PreviewScene);
}
FName FCollisionDataEditorToolkit::GetToolkitFName() const
{
return FName("CollisionDataEditor");
}
FText FCollisionDataEditorToolkit::GetBaseToolkitName() const
{
return LOCTEXT("AppLabel", "Collision Data Editor");
}
FText FCollisionDataEditorToolkit::GetToolkitName() const
{
return FText::FromString(CollisionData->GetName());
}
FString FCollisionDataEditorToolkit::GetWorldCentricTabPrefix() const
{
return FString("CollisionDataEditor");
}
FLinearColor FCollisionDataEditorToolkit::GetWorldCentricTabColorScale() const
{
return FLinearColor::White;
}
void FCollisionDataEditorToolkit::RegisterTabSpawners(const TSharedRef<FTabManager>& InTabManager)
{
UE_LOG(LogCollisionEditor, Warning, TEXT("Registering Tab Spawners"));
WorkspaceMenuCategory = InTabManager->AddLocalWorkspaceMenuCategory(
LOCTEXT("WorkspaceMenu_CollisionDataEditor", "Collision Data Editor"));
FAssetEditorToolkit::RegisterTabSpawners(InTabManager);
InTabManager->RegisterTabSpawner("CollisionDataDetailsTab",
FOnSpawnTab::CreateSP(
this, &FCollisionDataEditorToolkit::SpawnTab_CollisionDataDetails))
.SetDisplayName(LOCTEXT("CollisionDataDetailsTab", "Collision Data Details"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef());
InTabManager->RegisterTabSpawner("PlayerObjectSelectorTab",
FOnSpawnTab::CreateSP(
this, &FCollisionDataEditorToolkit::SpawnTab_PlayerObjectSelector))
.SetDisplayName(LOCTEXT("PlayerObjectSelectorTab", "Cel Browser"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef());
InTabManager->RegisterTabSpawner("ViewportTab",
FOnSpawnTab::CreateSP(this, &FCollisionDataEditorToolkit::SpawnTab_ViewportTab))
.SetDisplayName(LOCTEXT("ViewportTab", "Viewport"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef());
}
void FCollisionDataEditorToolkit::UnregisterTabSpawners(const TSharedRef<FTabManager>& InTabManager)
{
FAssetEditorToolkit::UnregisterTabSpawners(InTabManager);
InTabManager->UnregisterTabSpawner("CollisionDataDetailsTab");
InTabManager->UnregisterTabSpawner("PlayerObjectSelectorTab");
InTabManager->UnregisterTabSpawner("ViewportTab");
}
#undef LOCTEXT_NAMESPACE