add possession in selection window

This commit is contained in:
Arnaud Jamin
2023-10-10 17:24:27 -04:00
parent 87acfc5a94
commit 83d756252a
43 changed files with 374 additions and 276 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -14,37 +14,6 @@ void FCogAbilityModule::ShutdownModule()
{
}
//--------------------------------------------------------------------------------------------------------------------------
ACogAbilityReplicator* FCogAbilityModule::GetLocalReplicator()
{
return LocalReplicator;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityModule::SetLocalReplicator(ACogAbilityReplicator* Value)
{
LocalReplicator = Value;
}
//--------------------------------------------------------------------------------------------------------------------------
ACogAbilityReplicator* FCogAbilityModule::GetRemoteReplicator(const APlayerController* PlayerController)
{
for (ACogAbilityReplicator* Replicator : RemoteReplicators)
{
if (Replicator->GetPlayerController() == PlayerController)
{
return Replicator;
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityModule::AddRemoteReplicator(ACogAbilityReplicator* Value)
{
RemoteReplicators.Add(Value);
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FCogAbilityModule, CogAbility)
@@ -9,13 +9,37 @@
#include "Net/UnrealNetwork.h"
//--------------------------------------------------------------------------------------------------------------------------
void ACogAbilityReplicator::Create(APlayerController* Controller)
ACogAbilityReplicator* ACogAbilityReplicator::Spawn(APlayerController* Controller)
{
if (Controller->GetWorld()->GetNetMode() != NM_Client)
if (Controller->GetWorld()->GetNetMode() == NM_Client)
{
FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = Controller;
Controller->GetWorld()->SpawnActor<ACogAbilityReplicator>(SpawnInfo);
return nullptr;
}
FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = Controller;
return Controller->GetWorld()->SpawnActor<ACogAbilityReplicator>(SpawnInfo);
}
//--------------------------------------------------------------------------------------------------------------------------
ACogAbilityReplicator* ACogAbilityReplicator::GetLocalReplicator(UWorld& World)
{
for (TActorIterator<ACogAbilityReplicator> It(&World, ACogAbilityReplicator::StaticClass()); It; ++It)
{
ACogAbilityReplicator* Replicator = *It;
return Replicator;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogAbilityReplicator::GetRemoteReplicators(UWorld& World, TArray<ACogAbilityReplicator*>& Replicators)
{
for (TActorIterator<ACogAbilityReplicator> It(&World, ACogAbilityReplicator::StaticClass()); It; ++It)
{
ACogAbilityReplicator* Replicator = Cast<ACogAbilityReplicator>(*It);
Replicators.Add(Replicator);
}
}
@@ -50,18 +74,6 @@ void ACogAbilityReplicator::BeginPlay()
Super::BeginPlay();
OwnerPlayerController = Cast<APlayerController>(GetOwner());
if (OwnerPlayerController != nullptr)
{
if (OwnerPlayerController->IsLocalController())
{
FCogAbilityModule::Get().SetLocalReplicator(this);
}
else
{
FCogAbilityModule::Get().AddRemoteReplicator(this);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -117,8 +117,7 @@ void UCogAbilityWindow_Abilities::RenderAbiltiesMenu(AActor* Selection)
if (ImGui::MenuItem(TCHAR_TO_ANSI(*GetNameSafe(AbilityClass))))
{
FCogAbilityModule& Module = FCogAbilityModule::Get();
if (ACogAbilityReplicator* Replicator = Module.GetLocalReplicator())
if (ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->GiveAbility(Selection, AbilityClass);
}
@@ -431,8 +430,7 @@ void UCogAbilityWindow_Abilities::GameTick(float DeltaTime)
{
if (AActor* Selection = GetSelection())
{
FCogAbilityModule& Module = FCogAbilityModule::Get();
if (ACogAbilityReplicator* Replicator = Module.GetLocalReplicator())
if (ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->RemoveAbility(Selection, AbilityHandleToRemove);
}
@@ -59,8 +59,7 @@ void UCogAbilityWindow_Cheats::SetCheatsAsset(const UCogAbilityDataAsset_Cheats*
return;
}
FCogAbilityModule& Module = FCogAbilityModule::Get();
ACogAbilityReplicator* Replicator = Module.GetLocalReplicator();
ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{
return;
@@ -274,8 +273,7 @@ void UCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* Sel
Actors.Add(SelectedActor);
}
FCogAbilityModule& Module = FCogAbilityModule::Get();
if (ACogAbilityReplicator* Replicator = Module.GetLocalReplicator())
if (ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->ApplyCheat(ControlledActor, Actors, Cheat);
}
@@ -23,8 +23,7 @@ void UCogAbilityWindow_Tweaks::RenderContent()
return;
}
FCogAbilityModule& Module = FCogAbilityModule::Get();
ACogAbilityReplicator* Replicator = Module.GetLocalReplicator();
ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{
return;
@@ -3,28 +3,15 @@
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class ACogAbilityReplicator;
class APlayerController;
class COGABILITY_API FCogAbilityModule : public IModuleInterface
{
public:
static inline FCogAbilityModule& Get()
{
return FModuleManager::LoadModuleChecked<FCogAbilityModule>("CogAbility");
}
static inline FCogAbilityModule& Get() { return FModuleManager::LoadModuleChecked<FCogAbilityModule>("CogAbility"); }
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
ACogAbilityReplicator* GetLocalReplicator();
void SetLocalReplicator(ACogAbilityReplicator* Value);
ACogAbilityReplicator* GetRemoteReplicator(const APlayerController* PlayerController);
void AddRemoteReplicator(ACogAbilityReplicator* Value);
private:
TObjectPtr<ACogAbilityReplicator> LocalReplicator;
TArray<TObjectPtr<ACogAbilityReplicator>> RemoteReplicators;
};
@@ -18,7 +18,11 @@ class COGABILITY_API ACogAbilityReplicator : public AActor
public:
static void Create(APlayerController* Controller);
static ACogAbilityReplicator* Spawn(APlayerController* Controller);
static ACogAbilityReplicator* GetLocalReplicator(UWorld& World);
static void GetRemoteReplicators(UWorld& World, TArray<ACogAbilityReplicator*>& Replicators);
virtual void BeginPlay() override;
@@ -4,6 +4,7 @@
#include "CogWindow.h"
#include "CogAbilityWindow_Tweaks.generated.h"
class ACogAbilityReplicator;
class UCogAbilityDataAsset_Tweaks;
UCLASS()
@@ -516,7 +516,7 @@ void FCogDebugDraw::ReplicateShape(const UObject* WorldContextObject, const FCog
if (NetMode == NM_DedicatedServer || NetMode == NM_ListenServer)
{
TArray<ACogDebugReplicator*> Replicators;
FCogDebugModule::Get().GetRemoteReplicators(*World, Replicators);
ACogDebugReplicator::GetRemoteReplicators(*World, Replicators);
for (ACogDebugReplicator* Replicator : Replicators)
{
@@ -98,7 +98,7 @@ ELogVerbosity::Type FCogDebugLog::GetServerVerbosity(FName CategoryName)
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLog::SetServerVerbosity(UWorld& World, FName CategoryName, ELogVerbosity::Type Verbosity)
{
if (ACogDebugReplicator* Replicator = FCogDebugModule::Get().GetLocalReplicator(World))
if (ACogDebugReplicator* Replicator = ACogDebugReplicator::GetLocalReplicator(World))
{
Replicator->Server_SetCategoryVerbosity(CategoryName, (ECogLogVerbosity)Verbosity);
}
@@ -1,8 +1,5 @@
#include "CogDebugModule.h"
#include "CogDebugReplicator.h"
#include "EngineUtils.h"
#define LOCTEXT_NAMESPACE "FCogDebugModule"
//--------------------------------------------------------------------------------------------------------------------------
@@ -15,28 +12,6 @@ void FCogDebugModule::ShutdownModule()
{
}
//--------------------------------------------------------------------------------------------------------------------------
ACogDebugReplicator* FCogDebugModule::GetLocalReplicator(UWorld& World)
{
for (TActorIterator<ACogDebugReplicator> It(&World, ACogDebugReplicator::StaticClass()); It; ++It)
{
ACogDebugReplicator* Replicator = *It;
return Replicator;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugModule::GetRemoteReplicators(UWorld& World, TArray<ACogDebugReplicator*>& Replicators)
{
for (TActorIterator<ACogDebugReplicator> It(&World, ACogDebugReplicator::StaticClass()); It; ++It)
{
ACogDebugReplicator* Replicator = Cast<ACogDebugReplicator>(*It);
Replicators.Add(Replicator);
}
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FCogDebugModule, CogDebug)
@@ -1,105 +1,46 @@
#include "CogDebugReplicator.h"
#include "CogDebugDraw.h"
#include "EngineUtils.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/WorldSettings.h"
#include "Net/Core/PushModel/PushModel.h"
#include "Net/UnrealNetwork.h"
//--------------------------------------------------------------------------------------------------------------------------
// FCogReplicatorNetPack
// ACogDebugReplicator
//--------------------------------------------------------------------------------------------------------------------------
class FCogReplicatorNetState : public INetDeltaBaseState
ACogDebugReplicator* ACogDebugReplicator::Spawn(APlayerController* Controller)
{
public:
virtual bool IsStateEqual(INetDeltaBaseState* OtherState) override
if (Controller->GetWorld()->GetNetMode() == NM_Client)
{
FCogReplicatorNetState* Other = static_cast<FCogReplicatorNetState*>(OtherState);
return (ShapesRepCounter == Other->ShapesRepCounter);
return nullptr;
}
int32 ShapesRepCounter = 0;
};
//--------------------------------------------------------------------------------------------------------------------------
// FCogReplicatorNetPack
//--------------------------------------------------------------------------------------------------------------------------
bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
{
if (DeltaParms.bUpdateUnmappedObjects || Owner == nullptr)
{
return true;
}
if (DeltaParms.Writer)
{
const bool bIsOwnerClient = !Owner->bHasAuthority;
if (bIsOwnerClient)
{
return false;
}
FCogReplicatorNetState* OldState = static_cast<FCogReplicatorNetState*>(DeltaParms.OldState);
FCogReplicatorNetState* NewState = new FCogReplicatorNetState();
check(DeltaParms.NewState);
*DeltaParms.NewState = TSharedPtr<INetDeltaBaseState>(NewState);
//------------------------------------------------------------------------------------------------------------------
// Find delta to replicate
//------------------------------------------------------------------------------------------------------------------
{
const bool bMissingOldState = (OldState == nullptr);
const bool bShapesChanged = (SavedShapes != Owner->ReplicatedShapes);
NewState->ShapesRepCounter = (bMissingOldState ? 0 : OldState->ShapesRepCounter) + (bShapesChanged ? 1 : 0);
if (bShapesChanged)
{
SavedShapes = Owner->ReplicatedShapes;
Owner->ReplicatedShapes.Empty();
}
}
//------------------------------------------------------------------------------------------------------------------
// Write
//------------------------------------------------------------------------------------------------------------------
{
const bool bMissingOldState = (OldState == nullptr);
const uint8 ShouldUpdateShapes = bMissingOldState || (OldState->ShapesRepCounter != NewState->ShapesRepCounter);
FBitWriter& Writer = *DeltaParms.Writer;
Writer.WriteBit(ShouldUpdateShapes);
if (ShouldUpdateShapes)
{
Writer << SavedShapes;
}
}
}
else if (DeltaParms.Reader)
{
//------------------------------------------------------------------------------------------------------------------
// Read
//------------------------------------------------------------------------------------------------------------------
FBitReader& Reader = *DeltaParms.Reader;
const uint8 ShouldUpdateShapes = Reader.ReadBit();
if (ShouldUpdateShapes)
{
Reader << Owner->ReplicatedShapes;
}
}
return true;
FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = Controller;
return Controller->GetWorld()->SpawnActor<ACogDebugReplicator>(SpawnInfo);
}
//--------------------------------------------------------------------------------------------------------------------------
// ACogDebugReplicator
//--------------------------------------------------------------------------------------------------------------------------
void ACogDebugReplicator::Create(APlayerController* Controller)
ACogDebugReplicator* ACogDebugReplicator::GetLocalReplicator(UWorld& World)
{
if (Controller->GetWorld()->GetNetMode() != NM_Client)
for (TActorIterator<ACogDebugReplicator> It(&World, ACogDebugReplicator::StaticClass()); It; ++It)
{
FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = Controller;
Controller->GetWorld()->SpawnActor<ACogDebugReplicator>(SpawnInfo);
ACogDebugReplicator* Replicator = *It;
return Replicator;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogDebugReplicator::GetRemoteReplicators(UWorld& World, TArray<ACogDebugReplicator*>& Replicators)
{
for (TActorIterator<ACogDebugReplicator> It(&World, ACogDebugReplicator::StaticClass()); It; ++It)
{
ACogDebugReplicator* Replicator = Cast<ACogDebugReplicator>(*It);
Replicators.Add(Replicator);
}
}
@@ -254,3 +195,86 @@ void ACogDebugReplicator::Server_RequestAllCategoriesVerbosity_Implementation()
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
// FCogReplicatorNetPack
//--------------------------------------------------------------------------------------------------------------------------
class FCogReplicatorNetState : public INetDeltaBaseState
{
public:
virtual bool IsStateEqual(INetDeltaBaseState* OtherState) override
{
FCogReplicatorNetState* Other = static_cast<FCogReplicatorNetState*>(OtherState);
return (ShapesRepCounter == Other->ShapesRepCounter);
}
int32 ShapesRepCounter = 0;
};
//--------------------------------------------------------------------------------------------------------------------------
// FCogReplicatorNetPack
//--------------------------------------------------------------------------------------------------------------------------
bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
{
if (DeltaParms.bUpdateUnmappedObjects || Owner == nullptr)
{
return true;
}
if (DeltaParms.Writer)
{
const bool bIsOwnerClient = !Owner->bHasAuthority;
if (bIsOwnerClient)
{
return false;
}
FCogReplicatorNetState* OldState = static_cast<FCogReplicatorNetState*>(DeltaParms.OldState);
FCogReplicatorNetState* NewState = new FCogReplicatorNetState();
check(DeltaParms.NewState);
*DeltaParms.NewState = TSharedPtr<INetDeltaBaseState>(NewState);
//------------------------------------------------------------------------------------------------------------------
// Find delta to replicate
//------------------------------------------------------------------------------------------------------------------
{
const bool bMissingOldState = (OldState == nullptr);
const bool bShapesChanged = (SavedShapes != Owner->ReplicatedShapes);
NewState->ShapesRepCounter = (bMissingOldState ? 0 : OldState->ShapesRepCounter) + (bShapesChanged ? 1 : 0);
if (bShapesChanged)
{
SavedShapes = Owner->ReplicatedShapes;
Owner->ReplicatedShapes.Empty();
}
}
//------------------------------------------------------------------------------------------------------------------
// Write
//------------------------------------------------------------------------------------------------------------------
{
const bool bMissingOldState = (OldState == nullptr);
const uint8 ShouldUpdateShapes = bMissingOldState || (OldState->ShapesRepCounter != NewState->ShapesRepCounter);
FBitWriter& Writer = *DeltaParms.Writer;
Writer.WriteBit(ShouldUpdateShapes);
if (ShouldUpdateShapes)
{
Writer << SavedShapes;
}
}
}
else if (DeltaParms.Reader)
{
//------------------------------------------------------------------------------------------------------------------
// Read
//------------------------------------------------------------------------------------------------------------------
FBitReader& Reader = *DeltaParms.Reader;
const uint8 ShouldUpdateShapes = Reader.ReadBit();
if (ShouldUpdateShapes)
{
Reader << Owner->ReplicatedShapes;
}
}
return true;
}
@@ -16,10 +16,6 @@ public:
virtual void ShutdownModule() override;
ACogDebugReplicator* GetLocalReplicator(UWorld& World);
void GetRemoteReplicators(UWorld& World, TArray<ACogDebugReplicator*>& Replicators);
private:
};
@@ -58,9 +58,15 @@ class COGDEBUG_API ACogDebugReplicator : public AActor
GENERATED_UCLASS_BODY()
public:
static void Create(APlayerController* Controller);
static ACogDebugReplicator* Spawn(APlayerController* Controller);
static ACogDebugReplicator* GetLocalReplicator(UWorld& World);
static void GetRemoteReplicators(UWorld& World, TArray<ACogDebugReplicator*>& Replicators);
virtual void BeginPlay() override;
virtual void TickActor(float DeltaTime, enum ELevelTick TickType, FActorTickFunction& ThisTickFunction) override;
APlayerController* GetPlayerController() const { return OwnerPlayerController.Get(); }
@@ -22,6 +22,7 @@ public class CogEngine : ModuleRules
new string[]
{
"Core",
"CogInterface",
"CogImgui",
"CogDebug",
"CogWindow",
@@ -12,24 +12,6 @@ void FCogEngineModule::ShutdownModule()
{
}
//--------------------------------------------------------------------------------------------------------------------------
ACogEngineReplicator* FCogEngineModule::GetLocalReplicator()
{
return LocalReplicator;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineModule::SetLocalReplicator(ACogEngineReplicator* Value)
{
LocalReplicator = Value;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineModule::AddRemoteReplicator(ACogEngineReplicator* Value)
{
RemoteReplicators.Add(Value);
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FCogEngineModule, CogEngine)
@@ -1,21 +1,53 @@
#include "CogEngineReplicator.h"
#include "CogDebugLogMacros.h"
#include "CogInterfacePossessor.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/WorldSettings.h"
#include "EngineUtils.h"
#include "Net/Core/PushModel/PushModel.h"
#include "Net/UnrealNetwork.h"
DEFINE_LOG_CATEGORY(LogCogEngine);
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineReplicator::Create(APlayerController* Controller)
ACogEngineReplicator* ACogEngineReplicator::Spawn(APlayerController* Controller)
{
if (Controller->GetWorld()->GetNetMode() != NM_Client)
if (Controller->GetWorld()->GetNetMode() == NM_Client)
{
FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = Controller;
Controller->GetWorld()->SpawnActor<ACogEngineReplicator>(SpawnInfo);
return nullptr;
}
FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = Controller;
ACogEngineReplicator* Replicator = Controller->GetWorld()->SpawnActor<ACogEngineReplicator>(SpawnInfo);
return Replicator;
}
//--------------------------------------------------------------------------------------------------------------------------
ACogEngineReplicator* ACogEngineReplicator::GetLocalReplicator(UWorld& World)
{
for (TActorIterator<ACogEngineReplicator> It(&World, ACogEngineReplicator::StaticClass()); It; ++It)
{
ACogEngineReplicator* Replicator = *It;
return Replicator;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineReplicator::GetRemoteReplicators(UWorld& World, TArray<ACogEngineReplicator*>& Replicators)
{
for (TActorIterator<ACogEngineReplicator> It(&World, ACogEngineReplicator::StaticClass()); It; ++It)
{
ACogEngineReplicator* Replicator = Cast<ACogEngineReplicator>(*It);
Replicators.Add(Replicator);
}
}
//--------------------------------------------------------------------------------------------------------------------------
ACogEngineReplicator::ACogEngineReplicator(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
@@ -33,6 +65,8 @@ ACogEngineReplicator::ACogEngineReplicator(const FObjectInitializer& ObjectIniti
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineReplicator::BeginPlay()
{
COG_LOG_OBJECT(LogCogEngine, ELogVerbosity::Verbose, this, TEXT(""));
Super::BeginPlay();
UWorld* World = GetWorld();
@@ -42,15 +76,6 @@ void ACogEngineReplicator::BeginPlay()
bIsLocal = NetMode != NM_DedicatedServer;
OwnerPlayerController = Cast<APlayerController>(GetOwner());
if (OwnerPlayerController->IsLocalController())
{
FCogEngineModule::Get().SetLocalReplicator(this);
}
else
{
FCogEngineModule::Get().AddRemoteReplicator(this);
}
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -129,3 +154,28 @@ void ACogEngineReplicator::OnRep_TimeDilation()
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineReplicator::Server_Possess_Implementation(APawn* Pawn)
{
#if !UE_BUILD_SHIPPING
if (ICogInterfacePossessor* Possessor = Cast<ICogInterfacePossessor>(OwnerPlayerController))
{
Possessor->SetPossession(Pawn);
}
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineReplicator::Server_ResetPossession_Implementation()
{
#if !UE_BUILD_SHIPPING
if (ICogInterfacePossessor* Possessor = Cast<ICogInterfacePossessor>(OwnerPlayerController))
{
Possessor->ResetPossession();
}
#endif // !UE_BUILD_SHIPPING
}
@@ -144,7 +144,7 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo()
//------------------------
// Actor List
//------------------------
//ImGui::BeginChild("ActorList", ImVec2(-1, -1), false);
ImGui::BeginChild("ActorList", ImVec2(-1, -1), false);
TArray<AActor*> Actors;
for (TActorIterator<AActor> It(GetWorld(), SelectedSubClass); It; ++It)
@@ -194,7 +194,7 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo()
}
}
Clipper.End();
//ImGui::EndChild();
ImGui::EndChild();
return SelectionChanged;
}
@@ -220,6 +220,34 @@ void UCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor)
ImGui::SetTooltip("Reset the selection to the controlled actor.");
}
if (APawn* Pawn = Cast<APawn>(Actor))
{
if (ImGui::Button("Possess", ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->Server_Possess(Pawn);
}
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Possess this pawn.");
}
if (ImGui::Button("Reset Possession", ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->Server_ResetPossession();
}
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Reset pawn.");
}
}
ImGui::EndPopup();
}
@@ -90,7 +90,7 @@ bool UCogEngineWindow_Spawns::RenderSpawnAsset(const FCogEngineSpawnEntry& Spawn
if (ImGui::Button(TCHAR_TO_ANSI(*EntryName), ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = FCogEngineModule::Get().GetLocalReplicator())
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->Server_Spawn(SpawnEntry);
}
@@ -31,7 +31,13 @@ void UCogEngineWindow_TimeScale::RenderContent()
{
Super::RenderContent();
ACogEngineReplicator* Replicator = FCogEngineModule::Get().GetLocalReplicator();
UWorld* World = GetWorld();
if (World == nullptr)
{
return;
}
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*World);
if (Replicator == nullptr)
{
return;
@@ -3,9 +3,6 @@
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class ACogEngineReplicator;
class APlayerController;
class COGENGINE_API FCogEngineModule : public IModuleInterface
{
public:
@@ -16,15 +13,5 @@ public:
virtual void ShutdownModule() override;
ACogEngineReplicator* GetLocalReplicator();
void SetLocalReplicator(ACogEngineReplicator* Value);
TArray<TObjectPtr<ACogEngineReplicator>> GetRemoteReplicators() const { return RemoteReplicators; }
void AddRemoteReplicator(ACogEngineReplicator* Value);
private:
TObjectPtr<ACogEngineReplicator> LocalReplicator;
TArray<TObjectPtr<ACogEngineReplicator>> RemoteReplicators;
};
@@ -6,6 +6,8 @@
#include "UObject/ObjectMacros.h"
#include "CogEngineReplicator.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogCogEngine, Verbose, All);
class APlayerController;
using FCogEnineSpawnFunction = TFunction<void(const FCogEngineSpawnEntry& SpawnEntry)>;
@@ -17,7 +19,12 @@ class COGENGINE_API ACogEngineReplicator : public AActor
GENERATED_UCLASS_BODY()
public:
static void Create(APlayerController* Controller);
static ACogEngineReplicator* Spawn(APlayerController* Controller);
static ACogEngineReplicator* GetLocalReplicator(UWorld& World);
static void GetRemoteReplicators(UWorld& World, TArray<ACogEngineReplicator*>& Replicators);
virtual void BeginPlay() override;
@@ -35,6 +42,12 @@ public:
UFUNCTION(Server, Reliable)
void Server_SetTimeDilation(float Value);
UFUNCTION(Server, Reliable)
void Server_Possess(APawn* Pawn);
UFUNCTION(Server, Reliable)
void Server_ResetPossession();
protected:
UFUNCTION()
@@ -4,6 +4,8 @@
#include "CogWindow.h"
#include "CogEngineWindow_TimeScale.generated.h"
class ACogEngineReplicator;
UCLASS()
class COGENGINE_API UCogEngineWindow_TimeScale : public UCogWindow
{
@@ -26,13 +26,17 @@ public:
TSharedPtr<SCogImguiWidget> CreateImGuiViewport(UGameViewportClient* GameViewport, FCogImguiRenderFunction Render, ImFontAtlas* FontAtlas = nullptr);
FCogImguiTextureManager& GetTextureManager() { return TextureManager; }
ImFontAtlas& GetDefaultFontAtlas() { return DefaultFontAtlas; }
bool GetEnableInput() const { return bEnabledInput; }
void SetEnableInput(bool Value) { bEnabledInput = Value; }
void ToggleEnableInput() { bEnabledInput = !bEnabledInput; }
const FCogImGuiKeyInfo& GetToggleInputKey() const { return ToggleInputKey; }
void SetToggleInputKey(const FCogImGuiKeyInfo& Value) { ToggleInputKey = Value; }
private:
@@ -0,0 +1,23 @@
#pragma once
#include "CoreMinimal.h"
#include "CogInterfacePossessor.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
UINTERFACE(MinimalAPI, Blueprintable)
class UCogInterfacePossessor : public UInterface
{
GENERATED_BODY()
};
//--------------------------------------------------------------------------------------------------------------------------
class ICogInterfacePossessor
{
GENERATED_BODY()
public:
virtual void SetPossession(APawn* Pawn) = 0;
virtual void ResetPossession() = 0;
};
+19
View File
@@ -136,6 +136,8 @@ void ACogSampleGameState::TickCog(float DeltaSeconds)
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleGameState::InitializeCog()
{
RegisterCommand(TEXT("Cog.ToggleInput"), TEXT(""), FConsoleCommandWithArgsDelegate::CreateUObject(this, &ACogSampleGameState::CogToggleInput));
TSharedPtr<SCogImguiWidget> Widget = FCogImguiModule::Get().CreateImGuiViewport(GEngine->GameViewport, [this](float DeltaTime) { RenderCog(DeltaTime); });
FCogImguiModule::Get().SetToggleInputKey(FCogImGuiKeyInfo(EKeys::Insert));
@@ -225,4 +227,21 @@ void ACogSampleGameState::RenderCog(float DeltaTime)
FCogDebugDrawImGui::Draw();
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleGameState::RegisterCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithArgsDelegate& Command)
{
IConsoleManager& ConsoleManager = IConsoleManager::Get();
if (!ConsoleManager.FindConsoleObject(Name))
{
ConsoleManager.RegisterConsoleCommand(Name, Help, Command, ECVF_Cheat);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleGameState::CogToggleInput(const TArray<FString>& Args)
{
FCogImguiModule::Get().ToggleEnableInput();
}
#endif //USE_COG
+11
View File
@@ -13,8 +13,11 @@ class ACogSampleGameState : public AGameStateBase
GENERATED_BODY()
ACogSampleGameState(const FObjectInitializer& ObjectInitializer);
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void Tick(float DeltaSeconds) override;
private:
@@ -23,10 +26,18 @@ private:
TObjectPtr<UObject> CogWindowManagerRef = nullptr;
#if USE_COG
void InitializeCog();
void TickCog(float DeltaTime);
void RenderCog(float DeltaTime);
void RegisterCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithArgsDelegate& Command);
void CogToggleInput(const TArray<FString>& Args);
TObjectPtr<UCogWindowManager> CogWindowManager = nullptr;
#endif //USE_COG
};
+2 -2
View File
@@ -29,9 +29,9 @@ namespace CogSampleLog
FCogDebugLog::AddLogCategory(LogCogAbility, "Ability");
FCogDebugLog::AddLogCategory(LogAbilitySystem, "Ability System");
FCogDebugLog::AddLogCategory(LogCogBaseAimRotation, "BaseAimRotation");
FCogDebugLog::AddLogCategory(LogCogBaseAimRotation, "Base Aim Rotation");
FCogDebugLog::AddLogCategory(LogCogCollision, "Collision");
FCogDebugLog::AddLogCategory(LogCogControlRotation, "ControlRotation");
FCogDebugLog::AddLogCategory(LogCogControlRotation, "Control Rotation");
FCogDebugLog::AddLogCategory(LogCogInput, "Input");
FCogDebugLog::AddLogCategory(LogCogPosition, "Position");
FCogDebugLog::AddLogCategory(LogCogPossession, "Possession");
+24 -24
View File
@@ -26,9 +26,9 @@ void ACogSamplePlayerController::BeginPlay()
Super::BeginPlay();
#if USE_COG
ACogDebugReplicator::Create(this);
ACogAbilityReplicator::Create(this);
ACogEngineReplicator::Create(this);
ACogDebugReplicator::Spawn(this);
ACogAbilityReplicator::Spawn(this);
ACogEngineReplicator::Spawn(this);
#endif //USE_COG
}
@@ -59,14 +59,14 @@ void ACogSamplePlayerController::OnPossess(APawn* InPawn)
}
}
ControlledCharacter = Cast<ACogSampleCharacter>(InPawn);
PossessedCharacter = Cast<ACogSampleCharacter>(InPawn);
if (InitialControlledCharacter == nullptr)
if (InitialPossessedCharacter == nullptr)
{
InitialControlledCharacter = ControlledCharacter;
InitialPossessedCharacter = PossessedCharacter;
}
OnControlledCharacterChanged.Broadcast(this, ControlledCharacter.Get(), OldControlledCharacter);
OnControlledCharacterChanged.Broadcast(this, PossessedCharacter.Get(), OldControlledCharacter);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -78,26 +78,26 @@ void ACogSamplePlayerController::AcknowledgePossession(APawn* NewPawn)
Super::AcknowledgePossession(NewPawn);
if (InitialControlledCharacter == nullptr)
if (InitialPossessedCharacter == nullptr)
{
InitialControlledCharacter = Cast<ACogSampleCharacter>(NewPawn);
InitialPossessedCharacter = Cast<ACogSampleCharacter>(NewPawn);
}
if (ControlledCharacter != nullptr)
if (PossessedCharacter != nullptr)
{
ControlledCharacter->AcknowledgeUnpossession();
PossessedCharacter->AcknowledgeUnpossession();
}
ControlledCharacter = Cast<ACogSampleCharacter>(NewPawn);
ControlledCharacter->AcknowledgePossession(this);
PossessedCharacter = Cast<ACogSampleCharacter>(NewPawn);
PossessedCharacter->AcknowledgePossession(this);
OnControlledCharacterChanged.Broadcast(this, ControlledCharacter.Get(), OldControlledCharacter);
OnControlledCharacterChanged.Broadcast(this, PossessedCharacter.Get(), OldControlledCharacter);
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSamplePlayerController::ControlCharacter(ACogSampleCharacter* NewCharacter)
void ACogSamplePlayerController::SetPossession(APawn* NewPawn)
{
if (NewCharacter == nullptr || GetPawn() == NewCharacter)
if (NewPawn == nullptr || GetPawn() == NewPawn)
{
return;
}
@@ -105,10 +105,10 @@ void ACogSamplePlayerController::ControlCharacter(ACogSampleCharacter* NewCharac
//-------------------------------------------------------------------------------------------
// Unplug the current controller so it doesn't conflict with the newly assigned controller
//-------------------------------------------------------------------------------------------
AController* OldController = NewCharacter->GetController();
AController* OldController = NewPawn->GetController();
if (OldController != nullptr)
{
COG_LOG_OBJECT(LogCogPossession, ELogVerbosity::Verbose, this, TEXT("%s unpossess %s"), *GetNameSafe(OldController), *GetNameSafe(NewCharacter));
COG_LOG_OBJECT(LogCogPossession, ELogVerbosity::Verbose, this, TEXT("%s unpossess %s"), *GetNameSafe(OldController), *GetNameSafe(NewPawn));
OldController->UnPossess();
}
@@ -123,8 +123,8 @@ void ACogSamplePlayerController::ControlCharacter(ACogSampleCharacter* NewCharac
COG_LOG_OBJECT(LogCogPossession, ELogVerbosity::Verbose, this, TEXT("%s unpossess %s"), *GetNameSafe(this), *GetNameSafe(GetPawn()));
UnPossess();
COG_LOG_OBJECT(LogCogPossession, ELogVerbosity::Verbose, this, TEXT("%s possess %s"), *GetNameSafe(this), *GetNameSafe(NewCharacter));
Possess(NewCharacter);
COG_LOG_OBJECT(LogCogPossession, ELogVerbosity::Verbose, this, TEXT("%s possess %s"), *GetNameSafe(this), *GetNameSafe(NewPawn));
Possess(NewPawn);
//-------------------------------------------------------------------------------------------
// Replug the initial controller on the old character. For example, replug the initial
@@ -139,9 +139,9 @@ void ACogSamplePlayerController::ControlCharacter(ACogSampleCharacter* NewCharac
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSamplePlayerController::ResetControlledPawn()
void ACogSamplePlayerController::ResetPossession()
{
ControlCharacter(InitialControlledCharacter.Get());
SetPossession(InitialPossessedCharacter.Get());
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -170,9 +170,9 @@ void ACogSamplePlayerController::TickTargeting(float DeltaSeconds)
}
#if USE_COG
if (Target != nullptr && ControlledCharacter != nullptr)
if (Target != nullptr && PossessedCharacter != nullptr)
{
FCogDebugDraw::Segment(LogCogTargetAcquisition, ControlledCharacter.Get(), ControlledCharacter->GetActorLocation(), Target->GetActorLocation(), FColor::White, false);
FCogDebugDraw::Segment(LogCogTargetAcquisition, PossessedCharacter.Get(), PossessedCharacter->GetActorLocation(), Target->GetActorLocation(), FColor::White, false);
}
#endif //USE_COG
}
+14 -11
View File
@@ -2,6 +2,7 @@
#include "CoreMinimal.h"
#include "AbilitySystemInterface.h"
#include "CogInterfacePossessor.h"
#include "GameFramework/PlayerController.h"
#include "CogSamplePlayerController.generated.h"
@@ -15,7 +16,9 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FCogSampleControlledCharacterChan
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(config=Game)
class ACogSamplePlayerController : public APlayerController
class ACogSamplePlayerController
: public APlayerController
, public ICogInterfacePossessor
{
GENERATED_BODY()
@@ -28,18 +31,18 @@ public:
virtual void Tick(float DeltaSeconds) override;
//----------------------------------------------------------------------------------------------------------------------
// Control
// Possession
//----------------------------------------------------------------------------------------------------------------------
UFUNCTION(BlueprintCallable)
virtual void SetPossession(APawn* NewPawn) override;
UFUNCTION(BlueprintCallable)
virtual void ResetPossession() override;
virtual void OnPossess(APawn* NewPawn) override;
virtual void AcknowledgePossession(APawn* NewPawn) override;
UFUNCTION(BlueprintCallable)
void ControlCharacter(ACogSampleCharacter* NewCharacter);
UFUNCTION(BlueprintCallable)
void ResetControlledPawn();
UPROPERTY(BlueprintAssignable)
FCogSampleControlledCharacterChangedEventDelegate OnControlledCharacterChanged;
@@ -57,14 +60,14 @@ public:
private:
//----------------------------------------------------------------------------------------------------------------------
// Control
// Possession
//----------------------------------------------------------------------------------------------------------------------
UPROPERTY(BlueprintReadonly, meta = (AllowPrivateAccess = "true"))
TWeakObjectPtr<ACogSampleCharacter> ControlledCharacter = nullptr;
TWeakObjectPtr<ACogSampleCharacter> PossessedCharacter = nullptr;
UPROPERTY(BlueprintReadonly, meta = (AllowPrivateAccess = "true"))
TWeakObjectPtr<ACogSampleCharacter> InitialControlledCharacter = nullptr;
TWeakObjectPtr<ACogSampleCharacter> InitialPossessedCharacter = nullptr;
//----------------------------------------------------------------------------------------------------------------------
// Targeting