Add spawning window

This commit is contained in:
Arnaud Jamin
2023-10-02 15:28:35 -04:00
parent 1aabdb5c4e
commit 28cef19935
81 changed files with 325 additions and 131 deletions
@@ -22,12 +22,6 @@ ACogEngineReplicator::ACogEngineReplicator(const FObjectInitializer& ObjectIniti
{
#if !UE_BUILD_SHIPPING
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bAllowTickOnDedicatedServer = true;
PrimaryActorTick.bTickEvenWhenPaused = true;
PrimaryActorTick.bStartWithTickEnabled = true;
PrimaryActorTick.TickGroup = TG_PrePhysics;
bHasAuthority = false;
bIsLocal = false;
bReplicates = true;
@@ -65,26 +59,42 @@ void ACogEngineReplicator::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>&
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
#if !UE_BUILD_SHIPPING
FDoRepLifetimeParams Params;
Params.bIsPushBased = true;
DOREPLIFETIME_WITH_PARAMS_FAST(ACogEngineReplicator, TimeDilation, Params);
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineReplicator::TickSpawnActions()
void ACogEngineReplicator::Server_Spawn_Implementation(const FCogEngineSpawnEntry& SpawnEntry)
{
#if !UE_BUILD_SHIPPING
if (OwnerPlayerController == nullptr)
if (GetWorld() == nullptr)
{
return;
}
for (int32 i = SpawnActions.Num() - 1; i >= 0; --i)
if (SpawnFunction)
{
const FCogEngineReplicatorSpawnAction& SpawnInfo = SpawnActions[i];
SpawnActions.RemoveAt(i);
SpawnFunction(SpawnEntry);
}
else
{
FTransform Transform(FTransform::Identity);
if (APawn* Pawn = GetPlayerController()->GetPawn())
{
Transform = Pawn->GetTransform();
Transform.SetLocation(Transform.GetLocation() + Transform.GetUnitAxis(EAxis::X) * 200.0f);
Transform.SetScale3D(FVector(1.0f));
}
FActorSpawnParameters Params;
Params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
GetWorld()->SpawnActor(SpawnEntry.Class, &Transform, Params);
}
#endif // !UE_BUILD_SHIPPING
@@ -118,3 +128,4 @@ void ACogEngineReplicator::OnRep_TimeDilation()
#endif // !UE_BUILD_SHIPPING
}
@@ -0,0 +1,99 @@
#include "CogEngineWindow_Spawn.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Spawn::PreRender(ImGuiWindowFlags& WindowFlags)
{
Super::PreRender(WindowFlags);
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Spawn::RenderContent()
{
Super::RenderContent();
if (Asset == nullptr)
{
return;
}
for (const FCogEngineSpawnGroup& SpawnGroup : Asset->SpawnGroups)
{
RenderSpawnGroup(SpawnGroup);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Spawn::RenderSpawnGroup(const FCogEngineSpawnGroup& SpawnGroup)
{
int32 GroupIndex = 0;
ImGui::PushStyleColor(ImGuiCol_Header, IM_COL32(66, 66, 66, 79));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, IM_COL32(62, 62, 62, 204));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, IM_COL32(86, 86, 86, 255));
if (ImGui::CollapsingHeader(TCHAR_TO_ANSI(*SpawnGroup.Name), ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::PushID(GroupIndex);
const bool PushColor = (SpawnGroup.Color != FColor::Transparent);
if (PushColor)
{
FCogWindowWidgets::PushBackColor(FCogImguiHelper::ToImVec4(SpawnGroup.Color));
}
static int32 SelectedAssetIndex = -1;
int32 AssetIndex = 0;
for (const FCogEngineSpawnEntry& SpawnEntry : SpawnGroup.Spawns)
{
if (RenderSpawnAsset(SpawnEntry, SelectedAssetIndex == GroupIndex))
{
SelectedAssetIndex = AssetIndex;
}
AssetIndex++;
}
if (PushColor)
{
FCogWindowWidgets::PopBackColor();
}
ImGui::PopID();
GroupIndex++;
}
ImGui::PopStyleColor(3);
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogEngineWindow_Spawn::RenderSpawnAsset(const FCogEngineSpawnEntry& SpawnEntry, bool IsLastSelected)
{
bool IsPressed = false;
ImGui::PushStyleColor(ImGuiCol_Button, IsLastSelected ? ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive) : ImGui::GetStyleColorVec4(ImGuiCol_Button));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
FString EntryName;
if (SpawnEntry.Asset != nullptr)
{
EntryName = SpawnEntry.Asset->GetName();
}
else
{
EntryName = GetNameSafe(SpawnEntry.Class);
}
if (ImGui::Button(TCHAR_TO_ANSI(*EntryName), ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = FCogEngineModule::Get().GetLocalReplicator())
{
Replicator->Server_Spawn(SpawnEntry);
}
}
ImGui::PopStyleVar(1);
ImGui::PopStyleColor(1);
return IsPressed;
}
@@ -0,0 +1,46 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "CogEngineDataAsset_Spawns.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT()
struct COGENGINE_API FCogEngineSpawnEntry
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
TSubclassOf<AActor> Class;
UPROPERTY(EditAnywhere)
TObjectPtr<const UObject> Asset = nullptr;
};
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT()
struct COGENGINE_API FCogEngineSpawnGroup
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
FString Name;
UPROPERTY(EditAnywhere)
FLinearColor Color = FLinearColor(0.5f, 0.5f, 0.5f, 1.0f);
UPROPERTY(EditAnywhere)
TArray<FCogEngineSpawnEntry> Spawns;
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(Blueprintable)
class COGENGINE_API UCogEngineDataAsset_Spawns : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Name"))
TArray<FCogEngineSpawnGroup> SpawnGroups;
};
@@ -8,15 +8,7 @@
class APlayerController;
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT()
struct FCogEngineReplicatorSpawnAction
{
GENERATED_USTRUCT_BODY()
bool Control = false;
bool Select = false;
};
using FCogEnineSpawnFunction = TFunction<void(const FCogEngineSpawnEntry& SpawnEntry)>;
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(NotBlueprintable, NotBlueprintType, notplaceable, noteditinlinenew, hidedropdown, Transient)
@@ -31,30 +23,32 @@ public:
APlayerController* GetPlayerController() const { return OwnerPlayerController.Get(); }
bool IsLocal() const { return bIsLocal; }
FCogEnineSpawnFunction GetSpawnFunction() const { return SpawnFunction; }
void SetSpawnFunction(FCogEnineSpawnFunction Value) { SpawnFunction = Value; }
UFUNCTION(Server, Reliable)
void Server_Spawn(const FCogEngineSpawnEntry& SpawnEntry);
float GetTimeDilation() const { return TimeDilation; }
UFUNCTION(Server, Reliable)
void Server_SetTimeDilation(float Value);
float GetTimeDilation() const { return TimeDilation; }
protected:
void TickSpawnActions();
UFUNCTION()
void OnRep_TimeDilation();
UPROPERTY()
TArray<FCogEngineReplicatorSpawnAction> SpawnActions;
TObjectPtr<APlayerController> OwnerPlayerController;
uint32 bHasAuthority : 1;
uint32 bIsLocal : 1;
private:
UPROPERTY(ReplicatedUsing = OnRep_TimeDilation)
float TimeDilation = 1.0f;
FCogEnineSpawnFunction SpawnFunction;
};
@@ -0,0 +1,34 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
#include "CogEngineWindow_Spawn.generated.h"
class UCogEngineDataAsset_Spawns;
struct FCogEngineSpawnGroup;
UCLASS()
class COGENGINE_API UCogEngineWindow_Spawn : public UCogWindow
{
GENERATED_BODY()
public:
const UCogEngineDataAsset_Spawns* GetSpawnsAsset() const { return Asset; }
void SetSpawnsAsset(const UCogEngineDataAsset_Spawns* Value) { Asset = Value; }
protected:
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
virtual void RenderContent() override;
virtual void RenderSpawnGroup(const FCogEngineSpawnGroup& SpawnGroup);
virtual bool RenderSpawnAsset(const FCogEngineSpawnEntry& SpawnEntry, bool IsLastSelected);
private:
const UCogEngineDataAsset_Spawns* Asset = nullptr;
};