fix scale replication and other fixes

This commit is contained in:
Arnaud Jamin
2023-10-13 00:37:07 -04:00
parent 762167e3c2
commit 7b0ed3d05f
14 changed files with 477 additions and 119 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,10 @@
#include "CogAbilityHelper.h"
#include "GameplayEffect.h"
#include "CogAbilityDataAsset.h"
#include "CogImguiHelper.h"
#include "imgui.h"
//--------------------------------------------------------------------------------------------------------------------------
FString FCogAbilityHelper::CleanupName(FString Str)
{
@@ -7,3 +12,116 @@ FString FCogAbilityHelper::CleanupName(FString Str)
Str.RemoveFromEnd(TEXT("_c"));
return Str;
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 FCogAbilityHelper::GetAttributeColor(const UCogAbilityDataAsset* Asset, float BaseValue, float CurrentValue)
{
FLinearColor Color = FLinearColor::White;
if (Asset != nullptr)
{
if (CurrentValue > BaseValue)
{
Color = Asset->PositiveEffectColor;
}
else if (CurrentValue < BaseValue)
{
Color = Asset->NegativeEffectColor;
}
else
{
Color = Asset->NeutralEffectColor;
}
}
return FCogImguiHelper::ToImVec4(Color);
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 FCogAbilityHelper::GetEffectColor(const UCogAbilityDataAsset* Asset, const UGameplayEffect& Effect)
{
FLinearColor Color = FLinearColor::White;
if (Asset != nullptr)
{
const FGameplayTagContainer& Tags = Effect.InheritableGameplayEffectTags.CombinedTags;
if (Tags.HasTag(Asset->NegativeEffectTag))
{
Color = Asset->NegativeEffectColor;
}
else if (Tags.HasTag(Asset->PositiveEffectTag))
{
Color = Asset->PositiveEffectColor;
}
else
{
Color = Asset->NeutralEffectColor;
}
}
return FCogImguiHelper::ToImVec4(Color);
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 FCogAbilityHelper::GetEffectModifierColor(const UCogAbilityDataAsset* Asset, float ModifierValue, EGameplayModOp::Type ModifierOp, float BaseValue)
{
FLinearColor Color = Asset->NeutralEffectColor;
switch (ModifierOp)
{
case EGameplayModOp::Additive:
{
if (ModifierValue > 0.0f)
{
Color = Asset->PositiveEffectColor;
}
else if (ModifierValue < 0.0f)
{
Color = Asset->NegativeEffectColor;
}
break;
}
case EGameplayModOp::Multiplicitive:
{
if (ModifierValue > 1.0f)
{
Color = Asset->PositiveEffectColor;
}
else if (ModifierValue < 1.0f)
{
Color = Asset->NegativeEffectColor;
}
break;
}
case EGameplayModOp::Division:
{
if (ModifierValue < 1.0f)
{
Color = Asset->PositiveEffectColor;
}
else if (ModifierValue > 1.0f)
{
Color = Asset->NegativeEffectColor;
}
break;
}
case EGameplayModOp::Override:
{
if (ModifierValue > BaseValue)
{
Color = Asset->PositiveEffectColor;
}
else if (ModifierValue < BaseValue)
{
Color = Asset->NegativeEffectColor;
}
break;
}
}
return FCogImguiHelper::ToImVec4(Color);
}
@@ -281,7 +281,6 @@ void UCogAbilityWindow_Attributes::RenderContent()
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Attributes::DrawAttributeInfo(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayAttribute& Attribute)
{
@@ -295,23 +294,6 @@ void UCogAbilityWindow_Attributes::DrawAttributeInfo(const UAbilitySystemCompone
const float BaseValue = AbilitySystemComponent.GetNumericAttributeBase(Attribute);
const float CurrentValue = AbilitySystemComponent.GetNumericAttribute(Attribute);
FLinearColor Color = FLinearColor::White;
if (Asset != nullptr)
{
if (CurrentValue > BaseValue)
{
Color = Asset->PositiveEffectColor;
}
else if (CurrentValue < BaseValue)
{
Color = Asset->NegativeEffectColor;
}
else
{
Color = Asset->NeutralEffectColor;
}
}
//------------------------
// Name
//------------------------
@@ -337,7 +319,7 @@ void UCogAbilityWindow_Attributes::DrawAttributeInfo(const UAbilitySystemCompone
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, "Current Value");
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Text, FCogImguiHelper::ToImVec4(Color));
ImGui::PushStyleColor(ImGuiCol_Text, GetAttributeColor(AbilitySystemComponent, Attribute));
ImGui::Text("%0.2f", CurrentValue);
ImGui::PopStyleColor(1);
@@ -357,68 +339,6 @@ void UCogAbilityWindow_Attributes::DrawAttributeInfo(const UAbilitySystemCompone
{
const FModifierSpec& ModSpec = ActiveEffect->Spec.Modifiers[i];
const FGameplayModifierInfo& ModInfo = ActiveEffect->Spec.Def->Modifiers[i];
const float ModValue = ModSpec.GetEvaluatedMagnitude();
FLinearColor ModColor = FLinearColor::White;
if (Asset != nullptr)
{
ModColor = Asset->NeutralEffectColor;
switch (ModInfo.ModifierOp)
{
case EGameplayModOp::Additive:
{
if (ModValue > 0.0f)
{
ModColor = Asset->PositiveEffectColor;
}
else if (ModValue < 0.0f)
{
ModColor = Asset->NegativeEffectColor;
}
break;
}
case EGameplayModOp::Multiplicitive:
{
if (ModValue > 1.0f)
{
ModColor = Asset->PositiveEffectColor;
}
else if (ModValue < 1.0f)
{
ModColor = Asset->NegativeEffectColor;
}
break;
}
case EGameplayModOp::Division:
{
if (ModValue < 1.0f)
{
ModColor = Asset->PositiveEffectColor;
}
else if (ModValue > 1.0f)
{
ModColor = Asset->NegativeEffectColor;
}
break;
}
case EGameplayModOp::Override:
{
if (ModValue > BaseValue)
{
ModColor = Asset->PositiveEffectColor;
}
else if (ModValue < BaseValue)
{
ModColor = Asset->NegativeEffectColor;
}
break;
}
}
}
if (ModInfo.Attribute == Attribute)
{
@@ -430,7 +350,7 @@ void UCogAbilityWindow_Attributes::DrawAttributeInfo(const UAbilitySystemCompone
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(*FCogAbilityHelper::CleanupName(GetNameSafe(ActiveEffect->Spec.Def))));
ImGui::Text("%s", TCHAR_TO_ANSI(*EGameplayModOpToString(ModInfo.ModifierOp)));
ImGui::TextColored(FCogImguiHelper::ToImVec4(ModColor), "%0.2f", ModSpec.GetEvaluatedMagnitude());
ImGui::TextColored(GetEffectModifierColor(ModSpec, ModInfo, BaseValue), "%0.2f", ModSpec.GetEvaluatedMagnitude());
}
}
}
@@ -438,3 +358,19 @@ void UCogAbilityWindow_Attributes::DrawAttributeInfo(const UAbilitySystemCompone
ImGui::EndTable();
}
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 UCogAbilityWindow_Attributes::GetAttributeColor(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayAttribute& Attribute) const
{
const float BaseValue = AbilitySystemComponent.GetNumericAttributeBase(Attribute);
const float CurrentValue = AbilitySystemComponent.GetNumericAttribute(Attribute);
ImVec4 Color = FCogAbilityHelper::GetAttributeColor(Asset.Get(), BaseValue, CurrentValue);
return Color;
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 UCogAbilityWindow_Attributes::GetEffectModifierColor(const FModifierSpec& ModSpec, const FGameplayModifierInfo& ModInfo, float BaseValue) const
{
const float ModValue = ModSpec.GetEvaluatedMagnitude();
return FCogAbilityHelper::GetEffectModifierColor(Asset.Get(), ModSpec.GetEvaluatedMagnitude(), ModInfo.ModifierOp, BaseValue);
}
@@ -88,26 +88,7 @@ void UCogAbilityWindow_Effects::RenderEffectRow(const UAbilitySystemComponent& A
//------------------------
ImGui::TableNextColumn();
const FGameplayTagContainer& Tags = Effect.InheritableGameplayEffectTags.CombinedTags;
FLinearColor Color = FLinearColor::White;
if (Asset != nullptr)
{
if (Tags.HasTag(Asset->NegativeEffectTag))
{
Color = Asset->NegativeEffectColor;
}
else if (Tags.HasTag(Asset->PositiveEffectTag))
{
Color = Asset->PositiveEffectColor;
}
else
{
Color = Asset->NeutralEffectColor;
}
}
ImGui::PushStyleColor(ImGuiCol_Text, FCogImguiHelper::ToImVec4(Color));
ImGui::PushStyleColor(ImGuiCol_Text, GetEffectColor(Effect));
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetEffectName(Effect)), Selected == Index, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap | ImGuiSelectableFlags_AllowDoubleClick))
{
@@ -263,6 +244,7 @@ void UCogAbilityWindow_Effects::RenderEffectInfo(const UAbilitySystemComponent&
{
const FModifierSpec& ModSpec = ActiveEffect.Spec.Modifiers[i];
const FGameplayModifierInfo& ModInfo = ActiveEffect.Spec.Def->Modifiers[i];
const float AttributeBaseValue = AbilitySystemComponent.GetNumericAttributeBase(ModInfo.Attribute);
ImGui::TableNextRow();
ImGui::TableNextColumn();
@@ -272,7 +254,7 @@ void UCogAbilityWindow_Effects::RenderEffectInfo(const UAbilitySystemComponent&
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(*ModInfo.Attribute.GetName()));
ImGui::Text("%s", TCHAR_TO_ANSI(*EGameplayModOpToString(ModInfo.ModifierOp)));
ImGui::Text("%0.2f", ModSpec.GetEvaluatedMagnitude());
ImGui::TextColored(GetEffectModifierColor(ModSpec, ModInfo, AttributeBaseValue), "%0.2f", ModSpec.GetEvaluatedMagnitude());
}
ImGui::EndTable();
@@ -355,3 +337,17 @@ void UCogAbilityWindow_Effects::RenderPrediction(const FActiveGameplayEffect& Ac
ImGui::Text("%s", TCHAR_TO_ANSI(*PredictionString));
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 UCogAbilityWindow_Effects::GetEffectColor(const UGameplayEffect& Effect) const
{
return FCogAbilityHelper::GetEffectColor(Asset.Get(), Effect);
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 UCogAbilityWindow_Effects::GetEffectModifierColor(const FModifierSpec& ModSpec, const FGameplayModifierInfo& ModInfo, float BaseValue) const
{
const float ModValue = ModSpec.GetEvaluatedMagnitude();
return FCogAbilityHelper::GetEffectModifierColor(Asset.Get(), ModSpec.GetEvaluatedMagnitude(), ModInfo.ModifierOp, BaseValue);
}
@@ -1,10 +1,21 @@
#pragma once
#include "CoreMinimal.h"
#include "imgui.h"
class UCogAbilityDataAsset;
class UGameplayEffect;
namespace EGameplayModOp { enum Type; }
class COGABILITY_API FCogAbilityHelper
{
public:
static FString CleanupName(FString Str);
static ImVec4 GetAttributeColor(const UCogAbilityDataAsset* Asset, float BaseValue, float CurrentValue);
static ImVec4 GetEffectColor(const UCogAbilityDataAsset* Asset, const UGameplayEffect& Effect);
static ImVec4 GetEffectModifierColor(const UCogAbilityDataAsset* Asset, float ModifierValue, EGameplayModOp::Type ModifierOp, float BaseValue);
};
@@ -7,6 +7,8 @@
class UAbilitySystemComponent;
class UCogAbilityDataAsset;
struct FGameplayAttribute;
struct FModifierSpec;
struct FGameplayModifierInfo;
UCLASS(Config = Cog)
class COGABILITY_API UCogAbilityWindow_Attributes : public UCogWindow
@@ -31,6 +33,10 @@ protected:
virtual void DrawAttributeInfo(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayAttribute& Attribute);
virtual ImVec4 GetEffectModifierColor(const FModifierSpec& ModSpec, const FGameplayModifierInfo& ModInfo, float BaseValue) const;
virtual ImVec4 GetAttributeColor(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayAttribute& Attribute) const;
private:
UPROPERTY(Config)
@@ -3,6 +3,7 @@
#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
#include "CogWindow.h"
#include "imgui.h"
#include "CogAbilityWindow_Effects.generated.h"
class UAbilitySystemComponent;
@@ -10,6 +11,9 @@ class UCogAbilityDataAsset;
class UGameplayEffect;
struct FActiveGameplayEffect;
struct FActiveGameplayEffectHandle;
struct FGameplayModifierInfo;
struct FModifierSpec;
namespace EGameplayModOp { enum Type; };
UCLASS()
class COGABILITY_API UCogAbilityWindow_Effects : public UCogWindow
@@ -46,6 +50,10 @@ protected:
virtual FString GetEffectName(const UGameplayEffect& Effect);
ImVec4 GetEffectColor(const UGameplayEffect& Effect) const;
ImVec4 GetEffectModifierColor(const FModifierSpec& ModSpec, const FGameplayModifierInfo& ModInfo, float BaseValue) const;
UPROPERTY()
TWeakObjectPtr<const UCogAbilityDataAsset> Asset = nullptr;
};
@@ -82,20 +82,20 @@ void UCogWindow::Render(float DeltaTime)
}
}
if (bHasMenu)
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::BeginPopupContextWindow())
if (bHasMenu)
{
ImGui::Checkbox("Hide Menu", &bHideMenu);
if (ImGui::Button("Reset"))
{
ResetConfig();
}
ImGui::EndPopup();
}
}
if (ImGui::Button("Reset"))
{
ResetConfig();
}
ImGui::EndPopup();
}
RenderContent();
ImGui::End();
@@ -24,12 +24,6 @@ void UCogWindow_Settings::PostInitProperties()
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow_Settings::RenderContent()
{
ImGui::Checkbox("Compact Mode", &GetOwner()->bCompactMode);
ImGui::Checkbox("Show Windows In Main Menu", &GetOwner()->bShowWindowsInMainMenu);
ImGui::Checkbox("Show Window Help", &GetOwner()->bShowHelp);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("DPI Scale", &GetOwner()->DPIScale, 0.5f, 2.0f, "%.1f");
if (ImGui::IsItemDeactivatedAfterEdit())
@@ -37,6 +31,12 @@ void UCogWindow_Settings::RenderContent()
GetOwner()->bRefreshDPIScale = true;
}
ImGui::Checkbox("Compact Mode", &GetOwner()->bCompactMode);
ImGui::Checkbox("Show Windows In Main Menu", &GetOwner()->bShowWindowsInMainMenu);
ImGui::Checkbox("Show Window Help", &GetOwner()->bShowHelp);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
+8 -1
View File
@@ -625,7 +625,14 @@ void ACogSampleCharacter::OnGhostTagNewOrRemoved(const FGameplayTag InTag, int32
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::OnScaleAttributeChanged(const FOnAttributeChangeData& Data)
{
Scale = Data.NewValue;
//----------------------------------------------------------------------------------
// 'Data.NewValue' is not used because it seems to only corresponds to the changes
// of the BaseValue which do not account for the temporary modifiers.
//----------------------------------------------------------------------------------
const float CurrentScaleValue = AbilitySystem->GetNumericAttribute(Data.Attribute);
Scale = CurrentScaleValue;
MARK_PROPERTY_DIRTY_FROM_NAME(ACogSampleCharacter, Scale, this);
OnRep_Scale();
}
@@ -0,0 +1,102 @@
#include "CogWindow_Settings.h"
#include "CogImguiModule.h"
#include "InputCoreTypes.h"
//--------------------------------------------------------------------------------------------------------------------------
UCogWindow_Settings::UCogWindow_Settings()
{
bHasMenu = false;
ToggleInputKey.Key = EKeys::Tab;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow_Settings::PostInitProperties()
{
Super::PostInitProperties();
if (ToggleInputKey.Key != EKeys::Invalid)
{
FCogImguiModule::Get().SetToggleInputKey(ToggleInputKey);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow_Settings::RenderContent()
{
ImGui::Checkbox("Compact Mode", &GetOwner()->bCompactMode);
ImGui::Checkbox("Show Windows In Main Menu", &GetOwner()->bShowWindowsInMainMenu);
ImGui::Checkbox("Show Window Help", &GetOwner()->bShowHelp);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("DPI Scale", &GetOwner()->DPIScale, 0.5f, 2.0f, "%.1f");
if (ImGui::IsItemDeactivatedAfterEdit())
{
GetOwner()->bRefreshDPIScale = true;
}
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::TextUnformatted("Change DPi Scale [Mouse Wheel]");
ImGui::TextUnformatted("Reset DPi Scale [Middle Mouse]");
ImGui::EndTooltip();
}
ImGui::Separator();
ImGui::Text("Toggle Input Key");
TArray<FKey> Keys;
EKeys::GetAllKeys(Keys);
bool HasKeyChanged = false;
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("Key", TCHAR_TO_ANSI(*ToggleInputKey.Key.ToString())))
{
for (int32 i = 0; i < Keys.Num(); ++i)
{
const FKey Key = Keys[i];
if (Key.IsDigital() == false || Key.IsDeprecated())
{
continue;
}
bool IsSelected = ToggleInputKey.Key == Key;
if (ImGui::Selectable(TCHAR_TO_ANSI(*Key.ToString()), IsSelected))
{
ToggleInputKey.Key = Key;
HasKeyChanged = true;
}
}
ImGui::EndCombo();
}
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Ctrl", ToggleInputKey.Ctrl);
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Shift", ToggleInputKey.Shift);
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Alt", ToggleInputKey.Alt);
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Cmd", ToggleInputKey.Cmd);
if (HasKeyChanged)
{
FCogImguiModule::Get().SetToggleInputKey(ToggleInputKey);
}
ImGui::Separator();
ImGui::Spacing();
ImGui::Spacing();
if (ImGui::Button("Reset All Windows Config"))
{
GetOwner()->ResetAllWindowsConfig();
}
}
@@ -0,0 +1,174 @@
#include "CogWindow.h"
#include "CogDebugDraw.h"
#include "CogDebugSettings.h"
#include "CogWindowManager.h"
#include "CogWindowWidgets.h"
#include "Engine/World.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::SetFullName(const FString& InFullName)
{
FullName = InFullName;
TArray<FString> Path;
int CharIndex = 0;
if (FullName.FindLastChar(TEXT('.'), CharIndex))
{
Name = FullName.RightChop(CharIndex + 1);
}
else
{
Name = FullName;
}
ID = ImHashStr(TCHAR_TO_ANSI(*FullName));
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogWindow::CheckEditorVisibility()
{
const UWorld* World = GetWorld();
if (World == nullptr)
{
return false;
}
if (World->WorldType != EWorldType::Game)
{
return false;
}
if (World->WorldType == EWorldType::PIE)
{
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::Render(float DeltaTime)
{
ImGuiWindowFlags WindowFlags = 0;
PreRender(WindowFlags);
const FString WindowTitle = GetTitle() + "##" + Name;
if (bHasMenu && bHideMenu == false)
{
WindowFlags |= ImGuiWindowFlags_MenuBar;
}
if (ImGui::Begin(TCHAR_TO_ANSI(*WindowTitle), &bIsVisible, WindowFlags))
{
if (Owner->GetShowHelp())
{
if (ImGui::IsItemHovered())
{
ImGui::PushStyleColor(ImGuiCol_PopupBg, IM_COL32(29, 42, 62, 240));
const float HelpWidth = FCogWindowWidgets::GetFontWidth() * 80;
ImGui::SetNextWindowSizeConstraints(ImVec2(HelpWidth / 2.0f, 0.0f),
ImVec2(HelpWidth, FLT_MAX));
if (ImGui::BeginTooltip())
{
ImGui::PushTextWrapPos(HelpWidth - 1 * FCogWindowWidgets::GetFontWidth());
RenderHelp();
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
ImGui::PopStyleColor();
}
}
if (ImGui::BeginPopupContextWindow())
{
if (bHasMenu)
{
ImGui::Checkbox("Hide Menu", &bHideMenu);
if (ImGui::Button("Reset"))
{
ResetConfig();
}
}
ImGui::EndPopup();
}
RenderContent();
ImGui::End();
}
PostRender();
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::RenderHelp()
{
ImGui::Text("No help available.");
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::RenderTick(float DeltaTime)
{
SetSelection(FCogDebugSettings::GetSelection());
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::GameTick(float DeltaTime)
{
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::SetSelection(AActor* NewSelection)
{
if (CurrentSelection == NewSelection)
{
return;
}
AActor* OldActor = CurrentSelection.Get();
CurrentSelection = NewSelection;
OnSelectionChanged(OldActor, NewSelection);
}
//--------------------------------------------------------------------------------------------------------------------------
APawn* UCogWindow::GetLocalPlayerPawn()
{
APlayerController* LocalPlayerController = GetLocalPlayerController();
if (LocalPlayerController == nullptr)
{
return nullptr;
}
APawn* Pawn = LocalPlayerController->GetPawn();
return Pawn;
}
//--------------------------------------------------------------------------------------------------------------------------
APlayerController* UCogWindow::GetLocalPlayerController()
{
ULocalPlayer* LocalPlayer = GetLocalPlayer();
if (LocalPlayer == nullptr)
{
return nullptr;
}
return LocalPlayer->PlayerController;
}
//--------------------------------------------------------------------------------------------------------------------------
ULocalPlayer* UCogWindow::GetLocalPlayer()
{
const UWorld* World = GetWorld();
if (World == nullptr)
{
return nullptr;
}
return World->GetFirstLocalPlayerFromController();
}