Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- c++
- 알고리즘
- c#
- 유한상태기계
- 언리얼
- upper_bound
- 시리얼라이제이션
- 개발일지
- 재귀
- 프로그래머스
- 안드로이드
- binary_search
- 인프런
- 백준
- 게임개발공모전
- 너비우선탐색
- 이득우
- 유니티
- BFS
- UI 자동화
- unity
- lower_bound
- fsm
- 운영체제
- DFS
- unreal
- 이분탐색
- 웅진씽크빅
- 구현
- 게임개발
Archives
- Today
- Total
초고교급 희망
[9강] 언리얼 C++ 설계 3 - 델리게이트 본문
728x90
인프런에서 이득우의 언리얼 프로그래밍 Part 1을 수강하고 작성한 글 입니다.
강의 내용
언리얼 델리게이트를 사용해 클래스 간의 느슨한 결합을 구현하기
강의 목표
- 느슨한 결합의 장점과 이를 편리하게 구현하도록 도와주는 델리게이트의 이해
- 발행 구독 디자인 패턴의 이해
- 언리얼 델리게이트를 활용한 느슨한 결합의 설계와 구현의 학습
강한 결합과 느슨한 결합
- 강한 결합(Tigth Coupling)
- 클래스들이 서로 의존성을 가지는 경우
- 느슨한 결합(Loose Coupling)
- 실물에 의존하지 말고 추상적 설계에 의존하라. (DIP 원칙)
- 느슨한 결합 구조는 유지 보수를 손쉽게 만들어줌.
느슨한 결합의 간편한 구현 - 델리게이트(Delegate)
- 함수를 오브젝트처럼 관리하면 어떨까?
- 함수를 다루는 방법
- 함수 포인터를 활용한 콜백(callback) 함수의 구현
- 가능은 하나 이를 정의하고 사용하는 과정이 꽤나 복잡함
- 안정성을 스스로 검증해주어야 함
- C++ 17 규약의 std::bing와 std::function 활용은 느림
- C#의 델리게이트(delegate) 키워드
- 함수를 마치 객체처럼 다룰 수 있음
- 안정적이고 간편한 선언
- 언리얼 C++도 델리게이트를 지원함
- 느슨한 결합 구조를 간편하고 안정적으로 구현할 수 있음
발행 구독 디자인 패턴
- 푸시(Push)형태의 알림(Notification)을 구현하는데 적합한 디자인 패턴
- 발행자(Publisher)와 구독자(Subscriber)로 구분된다.
- 콘텐츠 제작자는 콘텐츠를 생산
- 발행자는 콘텐츠를 배포
- 구독자는 배포된 콘텐츠를 받아 소비
- 제작자와 구독자가 서로를 몰라도, 발행자를 통해 콘텐츠 생산하고 전달할 수 있다. (느슨한 결합)
- 발행 구독 디자인 패턴의 장점
- 제작자와 구독자는 서로를 모르기 때문에 느슨한 결합으로 구성된다.
- 유지 보수(Maintenance)가 쉽고, 유연하게 활용될 수 있으며(Flexibility), 테스트가 쉬워진다.
- 시스템 스케일을 유연하게 조절할 수 있으며(Scalability), 기능 확장(Extensibility)이 용이하다.
언리얼 델리게이트(Delegate)
- 언리얼 엔진은 발행 구독 패턴 구현을 위해 델리게이트 기능을 제공함.
- 델리게이트의 사전적 의미는 대리자.
- 예시) 학사정보의 구독과 알림을 대리해주는 객체
- 시나리오 구현을 위한 설계
- 학사 정보는 구독과 알림을 대행할 델리게이트를 선언
- 학생은 학사 정보의 델리게이트를 통해 알림을 구독
- 학사 정보는 내용 변경 시 델리게이트를 사용해 등록한 학생들에게 알림
언리얼 델리게이트 선언 매크로
DECLARE_{델리게이트유형}_DELEGATE{함수정보}
- 델리게이트 유형 : 어떤 유형의 델리게이트인지
- DECLARE_DELEGATE : 일대일 형태로 C++만 지원한다면 유형은 공란으로 둔다.
- DECLARE_MUTICASE : 일대다 형태로 C++만 지원
- DECLARE_DYNAMIC : 일대일 형태로 블루프린트 지원
- DECLARE_DYNAMIC_MULTICAST : 일대다 형태로 블루프린트 지원
- 함수 정보 : 연동 될 함수 형태 지정
- DECLARE_DELEGATE : 인자가 없고 반환값도 없음
- DECLARE_DELEGATE_OnreParam : 인자 1개, 반환값 없음
- DECLARE_DELEGATE _RetVal_ThreeParams : 인자 3개, 반환값 있음 (MUTICAST는 반환값을 지원하지 않음)
- 파라미터는 최대 9개까지만 지원함
실습 예제
CourseInfo.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "CourseInfo.generated.h"
DECLARE_MULTICAST_DELEGATE_TwoParams(FCourseInfoOnChangedSignature, const FString&, const FString&);
/**
*
*/
UCLASS()
class UNREALDELEGATE_API UCourseInfo : public UObject
{
GENERATED_BODY()
public:
UCourseInfo();
FCourseInfoOnChangedSignature OnChanged;
void ChangeCourseInfo(const FString& InSchoolName, const FString& InNewContents);
private:
FString Contents;
};
CourseInfo.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "CourseInfo.h"
UCourseInfo::UCourseInfo()
{
Contents = TEXT("기존 학사 정보");
}
void UCourseInfo::ChangeCourseInfo(const FString& InSchoolName, const FString& InNewContents)
{
Contents = InNewContents;
UE_LOG(LogTemp, Log, TEXT("[CourseInfo] 학사 정보가 변경되어 알림을 발송합니다."));
OnChanged.Broadcast(InSchoolName, Contents);
}
MyGameInstance.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MyGameInstance.generated.h"
/**
*
*/
UCLASS()
class UNREALDELEGATE_API UMyGameInstance : public UGameInstance
{
GENERATED_BODY()
public:
UMyGameInstance();
virtual void Init() override;
private:
UPROPERTY()
TObjectPtr<class UCourseInfo> CourseInfo;
UPROPERTY()
FString SchoolName;
};
MyGameInstance.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameInstance.h"
#include "Student.h"
#include "Teacher.h"
#include "Staff.h"
#include "Card.h"
#include "CourseInfo.h"
UMyGameInstance::UMyGameInstance()
{
SchoolName = TEXT("학교");
}
void UMyGameInstance::Init()
{
Super::Init();
CourseInfo = NewObject<UCourseInfo>(this);
UE_LOG(LogTemp, Log, TEXT("==================="));
UStudent* Student1 = NewObject<UStudent>();
Student1->SetName(TEXT("학생1"));
UStudent* Student2 = NewObject<UStudent>();
Student2->SetName(TEXT("학생2"));
UStudent* Student3 = NewObject<UStudent>();
Student3->SetName(TEXT("학생3"));
CourseInfo->OnChanged.AddUObject(Student1, &UStudent::GetNotification);
CourseInfo->OnChanged.AddUObject(Student2, &UStudent::GetNotification);
CourseInfo->OnChanged.AddUObject(Student3, &UStudent::GetNotification);
CourseInfo->ChangeCourseInfo(SchoolName, TEXT("변경된 학사 정보"));
UE_LOG(LogTemp, Log, TEXT("==================="));
}
728x90
'Game > Unreal' 카테고리의 다른 글
[13강] 언리얼 직렬화 (0) | 2024.02.08 |
---|---|
[10강] 언리얼 컨테이너 라이브러리 1 - Array와 Set (1) | 2024.01.14 |
[8강] 언리얼 C++ 설계 2 - 컴포지션 (1) | 2023.12.27 |