Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add filter to select only prefabs when using rectangular selection in viewport #17

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
19 changes: 19 additions & 0 deletions Source/PrefabricatorEditor/Private/PrefabEditorCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Framework/Commands/UIAction.h"
#include "Framework/Commands/UICommandList.h"
#include "UObject/Object.h"
#include "PrefabricatorEditorModule.h"

#define LOCTEXT_NAMESPACE "ContentBrowser"

Expand All @@ -30,6 +31,24 @@ void FPrefabricatorCommands::RegisterCommands() {
FExecuteAction::CreateStatic(&FPrefabTools::CreatePrefab),
FCanExecuteAction::CreateStatic(&FPrefabTools::CanCreatePrefab)
);

UI_COMMAND(AllowOnlyPrefabSelection, "Select Only Prefabs", "Allow only prefabs to be selected", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::NumPadOne));

LevelMenuActionList->MapAction(
AllowOnlyPrefabSelection
, FExecuteAction::CreateStatic(&FPrefabTools::SetAllowOnlyPrefabSelection)
, FCanExecuteAction()
, FIsActionChecked::CreateStatic(&FPrefabTools::GetAllowOnlyPrefabSelection)
);


UI_COMMAND(CreatePrefabZeroPivot, "Create Prefab On Zero Oirgin", "Create New prefab on Zeroed pivot", EUserInterfaceActionType::Button, FInputChord(EKeys::NumPadTwo));

LevelMenuActionList->MapAction(
CreatePrefabZeroPivot
, FExecuteAction::CreateStatic(&FPrefabTools::CreatePrefabOnZeroPivot)
, FCanExecuteAction::CreateStatic(&FPrefabTools::CanCreatePrefab)
);
}


Expand Down
21 changes: 20 additions & 1 deletion Source/PrefabricatorEditor/Private/PrefabricatorEditorModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@
#include "PropertyEditorModule.h"
#include "ThumbnailRendering/ThumbnailManager.h"
#include "UnrealEdGlobals.h"

#include "Engine/Selection.h"
#include "Prefab/PrefabActor.h"
#define LOCTEXT_NAMESPACE "PrefabricatorEditorModule"



class FPrefabricatorEditorModule : public IPrefabricatorEditorModule
{
FPrefabDetailsExtend PrefabActorDetailsExtender;
FDelegateHandle SelectionDelegateHandle;

virtual void StartupModule() override
{
SelectionDelegateHandle = USelection::SelectObjectEvent.AddRaw(this, &FPrefabricatorEditorModule::OnSelectionChanged);
FPrefabEditorStyle::Initialize();
FPrefabricatorCommands::Register();

Expand Down Expand Up @@ -129,6 +132,22 @@ class FPrefabricatorEditorModule : public IPrefabricatorEditorModule
TSharedPtr<IComponentAssetBroker> PrefabAssetBroker;
TArray< TSharedPtr<IAssetTypeActions> > CreatedAssetTypeActions;
EAssetTypeCategories::Type PrefabricatorAssetCategoryBit;

void OnSelectionChanged(UObject* Object)
{
if(FPrefabTools::GetAllowOnlyPrefabSelection())
{
APrefabActor* Prefab = Cast<APrefabActor>(Object);

if (!Prefab)
{
GEditor->GetSelectedActors()->BeginBatchSelectOperation();
GEditor->GetSelectedActors()->Select(Object, false);
GEditor->GetSelectedActors()->EndBatchSelectOperation(false);
}
}

}
};

IMPLEMENT_MODULE(FPrefabricatorEditorModule, PrefabricatorEditor)
Expand Down
2 changes: 2 additions & 0 deletions Source/PrefabricatorEditor/Private/UI/EditorUIExtender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ void FEditorUIExtender::Extend()

MenuBuilder.BeginSection("Prefabricator-Prefabs", LOCTEXT("PrefabHeader", "Prefabs"));
MenuBuilder.AddMenuEntry(FPrefabricatorCommands::Get().CreatePrefab);
MenuBuilder.AddMenuEntry(FPrefabricatorCommands::Get().CreatePrefabZeroPivot);
MenuBuilder.AddMenuEntry(FPrefabricatorCommands::Get().AllowOnlyPrefabSelection);
MenuBuilder.EndSection();

MenuBuilder.BeginSection("Prefabricator-Randomization", LOCTEXT("RandomizationHeader", "Randomization"));
Expand Down
3 changes: 2 additions & 1 deletion Source/PrefabricatorEditor/Public/PrefabEditorCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class PREFABRICATOREDITOR_API FPrefabricatorCommands : public TCommands<FPrefabr

TSharedPtr<FUICommandInfo> CreatePrefab;
TSharedPtr<class FUICommandList> LevelMenuActionList;

TSharedPtr< FUICommandInfo > AllowOnlyPrefabSelection;
TSharedPtr<FUICommandInfo> CreatePrefabZeroPivot;
};


Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
class PREFABRICATOREDITOR_API IPrefabricatorEditorModule : public IModuleInterface
{

public:

/**
Expand All @@ -42,5 +41,4 @@ class PREFABRICATOREDITOR_API IPrefabricatorEditorModule : public IModuleInterfa
virtual EAssetTypeCategories::Type GetPrefabricatorAssetCategoryBit() const = 0;
virtual FPrefabDetailsExtend& GetPrefabActorDetailsExtender() = 0;
virtual void UpgradePrefabAssets() = 0;
};

};
34 changes: 19 additions & 15 deletions Source/PrefabricatorRuntime/Private/Asset/PrefabricatorAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ FVector FPrefabricatorAssetUtils::FindPivot(const TArray<AActor*>& InActors)
Bounds += ActorBounds;
}

switch (GetDefault< UPrefabricatorSettings>()->PivotPosition)
{
case EPrefabricatorPivotPosition::ExtremeLeft:
Pivot = Bounds.GetCenter() - Bounds.GetExtent();
break;
case EPrefabricatorPivotPosition::ExtremeRight:
Pivot = Bounds.GetCenter() + Bounds.GetExtent();
break;
case EPrefabricatorPivotPosition::Center:
Pivot = Bounds.GetCenter();
break;
default:;
switch (GetDefault< UPrefabricatorSettings>()->PivotPosition)
{
case EPrefabricatorPivotPosition::ExtremeLeft:
Pivot = Bounds.GetCenter() - Bounds.GetExtent();
break;
case EPrefabricatorPivotPosition::ExtremeRight:
Pivot = Bounds.GetCenter() + Bounds.GetExtent();
break;
case EPrefabricatorPivotPosition::Center:
Pivot = Bounds.GetCenter();
break;
default:;
}
Pivot.Z = Bounds.Min.Z;
}
Expand Down Expand Up @@ -95,7 +95,7 @@ UPrefabricatorAsset* UPrefabricatorAssetCollection::GetPrefabAsset(const FPrefab

FRandomStream Random;
Random.Initialize(InConfig.Seed);

TSoftObjectPtr<UPrefabricatorAsset> PrefabAssetPtr;

if (TotalWeight == 0) {
Expand All @@ -116,11 +116,15 @@ UPrefabricatorAsset* UPrefabricatorAssetCollection::GetPrefabAsset(const FPrefab
}
StartRange = EndRange;
}
if (!bFound) {
if (PrefabAssetPtr.IsNull()) {
PrefabAssetPtr = Prefabs.Last().PrefabAsset;
}
}
return PrefabAssetPtr.LoadSynchronous();

if (!PrefabAssetPtr.IsNull()) {
return PrefabAssetPtr.LoadSynchronous();
}
return nullptr;
}

void UPrefabricatorEventListener::PostSpawn_Implementation(APrefabActor* Prefab)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void UPrefabComponent::PostEditChangeProperty(struct FPropertyChangedEvent& e)
}
}
}

Super::PostEditChangeProperty(e);
}
#endif // WITH_EDITOR

141 changes: 138 additions & 3 deletions Source/PrefabricatorRuntime/Private/Prefab/PrefabTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "Serialization/ObjectAndNameAsStringProxyArchive.h"
#include "Serialization/ObjectReader.h"
#include "Serialization/ObjectWriter.h"
#include "PrefabricatorSettings.h"

DEFINE_LOG_CATEGORY_STATIC(LogPrefabTools, Log, All);

Expand Down Expand Up @@ -93,6 +94,22 @@ void FPrefabTools::IterateChildrenRecursive(APrefabActor* Prefab, TFunction<void
}
}

void FPrefabTools::SetAllowOnlyPrefabSelection()
{
auto* Settings = GetMutableDefault<UPrefabricatorSettings>();

// Toggle 'allow select translucent'
Settings->bSelectOnlyPrefabs = !Settings->bSelectOnlyPrefabs;
#if WITH_EDITOR
Settings->PostEditChange();
#endif
}

bool FPrefabTools::GetAllowOnlyPrefabSelection()
{
return GetDefault<UPrefabricatorSettings>()->bSelectOnlyPrefabs;
}

bool FPrefabTools::CanCreatePrefab()
{
return GetNumSelectedActors() > 0;
Expand Down Expand Up @@ -133,7 +150,16 @@ namespace {
}

}
void FPrefabTools::CreatePrefabFromActors(const TArray<AActor*>& InActors)

void FPrefabTools::CreatePrefabOnZeroPivot()
{
TArray<AActor*> SelectedActors;
GetSelectedActors(SelectedActors);

CreatePrefabFromActorsOnZeroPivot(SelectedActors);
}

void FPrefabTools::CreatePrefabFromActorsOnZeroPivot(const TArray<AActor*>& InActors)
{
TArray<AActor*> Actors;
SanitizePrefabActorsForCreation(InActors, Actors);
Expand All @@ -152,10 +178,68 @@ void FPrefabTools::CreatePrefabFromActors(const TArray<AActor*>& InActors)
Service->BeginTransaction(LOCTEXT("TransLabel_CreatePrefab", "Create Prefab"));
}


UWorld* World = Actors[0]->GetWorld();

FVector Pivot = FPrefabricatorAssetUtils::FindPivot(Actors);
APrefabActor* PrefabActor = World->SpawnActor<APrefabActor>(Pivot, FRotator::ZeroRotator);
FVector Pivot = FVector::ZeroVector;

TArray<FTransform> OriginalActorTransforms;

for (AActor* A : Actors)
{
OriginalActorTransforms.Add(A->GetTransform());
FBox BB = A->GetComponentsBoundingBox();

A->SetActorRotation(FRotator::ZeroRotator);
}

{
float LowestZ = MAX_flt;
FBox Bounds(EForceInit::ForceInit);
for (AActor* Actor : Actors)
{
FBox ActorBounds = FPrefabTools::GetPrefabBounds(Actor, false);
Bounds += ActorBounds;
}

Pivot = Bounds.GetCenter();
Pivot.Z = Bounds.Min.Z;
}

FVector RelativePosition = Pivot;

FActorSpawnParameters SpanParams;
SpanParams.bNoFail = true;

APrefabActor* PrefabActorTemp = World->SpawnActor<APrefabActor>(RelativePosition, FRotator::ZeroRotator, SpanParams);
PrefabActorTemp->GetRootComponent()->SetMobility(EComponentMobility::Static);

//attach to dummy
for (AActor* A : Actors)
{
A->DetachFromActor(FDetachmentTransformRules(EDetachmentRule::KeepWorld, true));
A->AttachToActor(PrefabActorTemp, FAttachmentTransformRules(EAttachmentRule::KeepWorld, true));

FTransform RT = A->GetRootComponent()->GetRelativeTransform();

FVector RelLoc = RT.GetLocation();
}

//move to world origin
PrefabActorTemp->SetActorLocation(FVector::ZeroVector);

//detach from dummy.
for (int32 Idx = 0; Idx < Actors.Num(); Idx++)
{
Actors[Idx]->DetachFromActor(FDetachmentTransformRules(EDetachmentRule::KeepWorld, true));
}

//we don't need it anymore.
PrefabActorTemp->Destroy(true, true);

Pivot = FVector::ZeroVector;

APrefabActor* PrefabActor = World->SpawnActor<APrefabActor>(FVector::ZeroVector, FRotator::ZeroRotator);

// Find the compatible mobility for the prefab actor
EComponentMobility::Type Mobility = FPrefabricatorAssetUtils::FindMobility(Actors);
Expand All @@ -167,6 +251,11 @@ void FPrefabTools::CreatePrefabFromActors(const TArray<AActor*>& InActors)
ParentActors(PrefabActor, Actor);
}

for (int32 Idx = 0; Idx < Actors.Num(); Idx++)
{
Actors[Idx]->SetActorRotation(OriginalActorTransforms[Idx].GetRotation());
}

if (Service.IsValid()) {
Service->EndTransaction();
}
Expand All @@ -175,6 +264,52 @@ void FPrefabTools::CreatePrefabFromActors(const TArray<AActor*>& InActors)

SelectPrefabActor(PrefabActor);

PrefabActor->SetActorLocation(RelativePosition);
}

void FPrefabTools::CreatePrefabFromActors(const TArray<AActor*>& InActors)
{
TArray<AActor*> Actors;
SanitizePrefabActorsForCreation(InActors, Actors);

if (Actors.Num() == 0) {
return;
}

UPrefabricatorAsset* PrefabAsset = CreatePrefabAsset();
if (!PrefabAsset) {
return;
}

TSharedPtr<IPrefabricatorService> Service = FPrefabricatorService::Get();
if (Service.IsValid()) {
Service->BeginTransaction(LOCTEXT("TransLabel_CreatePrefab", "Create Prefab"));
}


UWorld* World = Actors[0]->GetWorld();

FVector Pivot = FPrefabricatorAssetUtils::FindPivot(Actors);

APrefabActor* PrefabActor = World->SpawnActor<APrefabActor>(Pivot, FRotator::ZeroRotator);

// Find the compatible mobility for the prefab actor
EComponentMobility::Type Mobility = FPrefabricatorAssetUtils::FindMobility(Actors);
PrefabActor->GetRootComponent()->SetMobility(Mobility);

PrefabActor->PrefabComponent->PrefabAssetInterface = PrefabAsset;
// Attach the actors to the prefab
for (AActor* Actor : Actors) {
ParentActors(PrefabActor, Actor);
}

if (Service.IsValid()) {
Service->EndTransaction();
}

SaveStateToPrefabAsset(PrefabActor);

SelectPrefabActor(PrefabActor);
}

void FPrefabTools::AssignAssetUserData(AActor* InActor, const FGuid& InItemID, APrefabActor* Prefab)
Expand Down
9 changes: 8 additions & 1 deletion Source/PrefabricatorRuntime/Public/Prefab/PrefabTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ class PREFABRICATORRUNTIME_API FPrefabTools {
public:
static bool CanCreatePrefab();
static void CreatePrefab();
static void CreatePrefabFromActors(const TArray<AActor*>& Actors);
static void CreatePrefabFromActors(const TArray<AActor*>& InActors);

static void CreatePrefabOnZeroPivot();
static void CreatePrefabFromActorsOnZeroPivot(const TArray<AActor*>& Actors);

static void AssignAssetUserData(AActor* InActor, const FGuid& InItemID, APrefabActor* Prefab);

static void SaveStateToPrefabAsset(APrefabActor* PrefabActor);
Expand All @@ -43,6 +47,9 @@ class PREFABRICATORRUNTIME_API FPrefabTools {
static int32 GetRandomSeed(const FRandomStream& Random);

static void IterateChildrenRecursive(APrefabActor* Actor, TFunction<void(AActor*)> Visit);

static void SetAllowOnlyPrefabSelection();
static bool GetAllowOnlyPrefabSelection();
};

class PREFABRICATORRUNTIME_API FPrefabVersionControl {
Expand Down
3 changes: 3 additions & 0 deletions Source/PrefabricatorRuntime/Public/PrefabricatorSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class PREFABRICATORRUNTIME_API UPrefabricatorSettings : public UDeveloperSetting
UPROPERTY(EditAnywhere, BlueprintReadOnly, config, Category = "Settings")
bool bAllowDynamicUpdate;

UPROPERTY(EditAnywhere, BlueprintReadOnly, config, Category = "Settings")
bool bSelectOnlyPrefabs;

public:
UPrefabricatorSettings();

Expand Down