본문 바로가기

Unreal/개인플젝

이벤트시스템

서로간의 종속성을 떼어내기 위해선 여러가지 방법이 있다.

인터페이스 통한 호출, 모델-뷰-뷰모델 등으로 역할 구분하기....

 

나도 마찬가지로 이벤트 시스템을 만들었다. 서로 공방시스템을 만들다가 공격자와 방어자가 서로에게 직접 접근하는게 너무 괴로웠기 때문.

 

암것도 안되있을 떄 이런걸 만들어놔야 쭉쭉 쳐내니까..~

 

 

 A캐릭터가 B 캐릭터를 공격할 때

- 오버랩 이벤트 발생

 

 - 공격자의 공격량 체크(스텟)

- 방어자의 방어량 체크(스텟)

- 공방계산

- 죽음 계산

 

이런게 다 A나 B 내부에서 이뤄지면 별로니까...

 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once


#include "Subsystems/GameInstanceSubsystem.h"
#include "MLEventSystem.generated.h"

class UMLCharacterManagerPool;

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FAttackEvent, FGuid, AttackerID, FGuid, DefenderID);

UCLASS()
class CROPOUTSAMPLEPROJECT_API UMLEventSystem : public UGameInstanceSubsystem
{
	GENERATED_BODY()
public:
	UMLEventSystem();
	FAttackEvent OnAttackEvent;
public:
	static UMLEventSystem* Get(const UWorld* WorldObject);
	static UMLEventSystem* GetEventSystem(const UObject* WorldObject);
private:
	UFUNCTION()
	void OnAttack(FGuid InAttackerID, FGuid InDefenderID);
private:
	virtual void Initialize(FSubsystemCollectionBase& Collection) override;
	virtual void Deinitialize() override;
private:
	TWeakPtr<UMLCharacterManagerPool> CharacterManagerPool;
};

 

 

// Fill out your copyright notice in the Description page of Project Settings.
#include "MLEventSystem.h"
#include "GameFrameWork/MLCharacterPoolManager.h"
#include "Character/MLCharacter.h"
UMLEventSystem::UMLEventSystem()
{

	OnAttackEvent.AddDynamic(this, &UMLEventSystem::OnAttack);
}

UMLEventSystem* UMLEventSystem::Get(const UWorld* World)
{
	if (World)
	{
		return UGameInstance::GetSubsystem<UMLEventSystem>(World->GetGameInstance());
	}
	return nullptr;
}

UMLEventSystem* UMLEventSystem::GetEventSystem(const UObject* WorldObject)
{
	if (UWorld* World = GEngine->GetWorldFromContextObject(WorldObject, EGetWorldErrorMode::LogAndReturnNull))
	{
		return UMLEventSystem::Get(World);
	}

	return nullptr;
}

void UMLEventSystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);
}

void UMLEventSystem::Deinitialize()
{
	Super::Deinitialize();
}

void UMLEventSystem::OnAttack(FGuid InAttackerID, FGuid InDefenderID)
{
	UMLCharacterPoolManager* CharacterPool = this->GetGameInstance()->GetSubsystem<UMLCharacterPoolManager>();
	if (CharacterPool == nullptr)
	{
		return;
	}

	TWeakObjectPtr<AMLCharacter> Attacker = CharacterPool->GetCharacterByUID(InAttackerID);
	TWeakObjectPtr<AMLCharacter> Defender = CharacterPool->GetCharacterByUID(InDefenderID);
	if (Attacker.IsValid() == false || Defender.IsValid() == false)
	{
		return;
	}

	bool IsFriend = Attacker->GetTeamType() == Defender->GetTeamType();
	if (IsFriend == true)
	{
		return;
	}

	Defender->BeAttacked(999);
}

 

 

물론 이렇게 대충짜두면 이벤트 시스템 안에 모든게 덕지덕지 붙어버린다.

공방시스템을 따로 빼서 처리할 수 있으면 좋을것이다.

 

공방시스템내에서

공격자의 UID 통해 그것의 스탯 가져오고,

방어자의 uid 통해 그것의 스탯 가져오고

 

그 내부에서 계산에 따라 결과를 낸 뒤

다시 한 번 이벤트 시스템을 통해서 방어자에게 전달하면

방어자 내부에서 사망 판정을 할 수 있겠다..

 

일단은 그렇게 짜기 위한 초석!