캐릭터들에게 서로 이벤트를 전달해 줄 떄
서로가 서로의 포인터로 직접 호출하는게 아니라 UID만 가지고 이벤트를 전달 할 수 있도록
캐릭터풀을 만들었다.
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Subsystems/GameInstanceSubsystem.h"
#include "MLBattleDefine.h"
#include "MLCharacterPoolManager.generated.h"
class AMLCharacter;
enum class EMLTeamType : uint8;
UCLASS()
class CROPOUTSAMPLEPROJECT_API UMLCharacterPoolManager : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
static UMLCharacterPoolManager* Get(const UWorld* WorldObject);
static UMLCharacterPoolManager* GetCharacterPoolSystem(const UObject* WorldObject);
public:
template< class T >
bool SpawnCharacter(EMLTeamType InTeamType, UClass* Class, FTransform const& Transform, const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters())
{
if (AMLCharacter* ChildCharacter = GetWorld()->SpawnActor<T>(Class, Transform, SpawnParameters))
{
FGuid NewID = MakeUniqueID();
SpawnedCharacterList.Emplace(NewID, ChildCharacter);
ChildCharacter->InitCharacter(NewID, InTeamType);
return true;
}
return false;
}
void OnDestroyCharacter(FGuid InDestroyGUID);
AMLCharacter* GetCharacterByUID(FGuid InUID);
private:
UMLCharacterPoolManager();
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
FGuid MakeUniqueID();
UPROPERTY()
TMap<FGuid, AMLCharacter*> SpawnedCharacterList;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MLCharacterPoolManager.h"
#include "Character/MLCharacter.h"
#include "Kismet/KismetGuidLibrary.h"
UMLCharacterPoolManager* UMLCharacterPoolManager::Get(const UWorld* WorldObject)
{
if (WorldObject)
{
return UGameInstance::GetSubsystem<UMLCharacterPoolManager>(WorldObject->GetGameInstance());
}
return nullptr;
}
UMLCharacterPoolManager* UMLCharacterPoolManager::GetCharacterPoolSystem(const UObject* WorldObject)
{
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldObject, EGetWorldErrorMode::LogAndReturnNull))
{
return UMLCharacterPoolManager::Get(World);
}
return nullptr;
}
void UMLCharacterPoolManager::OnDestroyCharacter(FGuid InDestroyGUID)
{
if (SpawnedCharacterList.Contains(InDestroyGUID) == false)
{
UE_LOG(LogTemp, Error, TEXT("Guid Is Invalid."));
return;
}
SpawnedCharacterList[InDestroyGUID] = nullptr;
SpawnedCharacterList.Remove(InDestroyGUID);
}
AMLCharacter* UMLCharacterPoolManager::GetCharacterByUID(FGuid InUID)
{
return *SpawnedCharacterList.Find(InUID);
//return nullptr;
}
UMLCharacterPoolManager::UMLCharacterPoolManager()
{
}
void UMLCharacterPoolManager::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
}
void UMLCharacterPoolManager::Deinitialize()
{
Super::Deinitialize();
for (auto& SpawnEntry : SpawnedCharacterList)
{
if (SpawnEntry.Value != nullptr)
{
SpawnEntry.Value->Destroy();
SpawnEntry.Value = nullptr;
}
}
SpawnedCharacterList.Empty();
}
FGuid UMLCharacterPoolManager::MakeUniqueID()
{
// 디스폰 된 얘를 재활용 할 수 있는......
return UKismetGuidLibrary::NewGuid();
}
추가로 해야하는건 캐릭터 풀.
이렇게 많이 스폰하는 게임에서는 최적화를 위해서 캐릭터를 무조건 돌려써야한다!