서로간의 종속성을 떼어내기 위해선 여러가지 방법이 있다.
인터페이스 통한 호출, 모델-뷰-뷰모델 등으로 역할 구분하기....
나도 마찬가지로 이벤트 시스템을 만들었다. 서로 공방시스템을 만들다가 공격자와 방어자가 서로에게 직접 접근하는게 너무 괴로웠기 때문.
암것도 안되있을 떄 이런걸 만들어놔야 쭉쭉 쳐내니까..~
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 통해 그것의 스탯 가져오고
그 내부에서 계산에 따라 결과를 낸 뒤
다시 한 번 이벤트 시스템을 통해서 방어자에게 전달하면
방어자 내부에서 사망 판정을 할 수 있겠다..
일단은 그렇게 짜기 위한 초석!
'Unreal > 개인플젝' 카테고리의 다른 글
| 11.25 애님비피, 캐릭터스테이트, 클래스 쪼개기 (0) | 2023.11.25 |
|---|---|
| 업데이트 (0) | 2023.11.24 |
| 언리얼버그속상해 - ActorComponent가 BeginPlay 에서 null일때 (2) | 2023.09.07 |
| 인풋컨포넌트 분리함 (0) | 2023.09.04 |
| [언리얼] 3번째. 스포너 (0) | 2023.09.02 |