본문 바로가기

카테고리 없음

캐릭터풀 만들었다~

캐릭터들에게 서로 이벤트를 전달해 줄 떄

서로가 서로의 포인터로 직접 호출하는게 아니라 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();
}

 

 

추가로 해야하는건 캐릭터 풀.

 

이렇게 많이 스폰하는 게임에서는 최적화를 위해서 캐릭터를 무조건 돌려써야한다!