함수와 Delegate
12강. 함수와 Delegate
1. 이번 강의에서 해결할 문제
체력이 바뀔 때 HealthComponent가 Widget을 직접 찾고 갱신하면 UI가 없는 테스트나 다른 Widget에서 Component를 재사용하기 어렵습니다. 상태 변경자는 사실만 알리고 관심 있는 객체가 구독하게 합니다.
2. 학습 목표
3. 핵심 개념
Delegate는 함수를 값처럼 연결해 발행자가 구독자의 구체 타입을 몰라도 이벤트를 전달하게 합니다. Dynamic Delegate는 Reflection을 사용해 Blueprint 바인딩과 직렬화 기능을 제공하는 대신 일반 C++ delegate보다 추가 비용이 있습니다. 체력 변경처럼 빈도가 낮고 Blueprint UI가 구독할 이벤트에 적합합니다.
Delegate가 모든 호출을 대체하지는 않습니다. 즉시 결과가 필요하거나 호출 대상이 하나로 명확한 계산은 함수 호출이 더 단순합니다.
4. 단계별 실습
파일 경로: Source/TopDownSurvival/Components/SurvivalHealthComponent.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "SurvivalHealthComponent.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(
FOnHealthChanged, float, CurrentHealth, float, MaxHealth);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDeath);
UCLASS(ClassGroup = "Survival", meta = (BlueprintSpawnableComponent))
class TOPDOWNSURVIVAL_API USurvivalHealthComponent : public UActorComponent
{
GENERATED_BODY()
public:
USurvivalHealthComponent();
UFUNCTION(BlueprintCallable, Category = "Health")
void SetCurrentHealth(float NewHealth);
UPROPERTY(BlueprintAssignable, Category = "Health")
FOnHealthChanged OnHealthChanged;
UPROPERTY(BlueprintAssignable, Category = "Health")
FOnDeath OnDeath;
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Health",
meta = (ClampMin = "1.0"))
float MaxHealth = 100.0f;
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Health")
float CurrentHealth = 100.0f;
};
파일 경로: Source/TopDownSurvival/Components/SurvivalHealthComponent.cpp
#include "Components/SurvivalHealthComponent.h"
USurvivalHealthComponent::USurvivalHealthComponent()
{
PrimaryComponentTick.bCanEverTick = false;
}
void USurvivalHealthComponent::SetCurrentHealth(float NewHealth)
{
const float Previous = CurrentHealth;
CurrentHealth = FMath::Clamp(NewHealth, 0.0f, MaxHealth);
if (!FMath::IsNearlyEqual(Previous, CurrentHealth))
{
OnHealthChanged.Broadcast(CurrentHealth, MaxHealth);
}
if (Previous > 0.0f && CurrentHealth <= 0.0f)
{
OnDeath.Broadcast();
}
}
구독자는 다음 형태의 함수를 갖습니다.
UFUNCTION()
void HandleHealthChanged(float CurrentHealth, float MaxHealth);
5. 코드가 동작하는 이유
Component는 Widget이나 EnemyBase를 include하지 않고 두 숫자와 사망 사실만 Broadcast합니다. 이전 체력이 0보다 클 때만 사망 이벤트를 보내 중복 Game Over를 막습니다. Clamp는 음수 체력과 최대치 초과를 방지합니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
함수와 Delegate 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.