관리 메뉴

Mini

[UE5] 체력변화가생길시 즉시 업데이트 구현 // 바인딩 버그?(auto vs 직접호출), 의존성점검(뷰->컨트롤러->모델) 본문

UE5/UI

[UE5] 체력변화가생길시 즉시 업데이트 구현 // 바인딩 버그?(auto vs 직접호출), 의존성점검(뷰->컨트롤러->모델)

Mini_96 2024. 5. 28. 02:27

1. 바인딩연결

델리게이트(Data type 속성)를 얻고, 그 속성이 변경될때마다 실행할 오브젝트(실행할함수)를 등록하면 된다.

void UOverlayWidgetController::BindCallbacksToDependencies()
{
	const UAuraAttributeSet* AuraAttributeSet = CastChecked<UAuraAttributeSet>(AttributeSet);

	auto deligate = AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AuraAttributeSet->GetHealthAttribute());
	deligate.AddUObject(this,&UOverlayWidgetController::HealthChanged);

	auto deligate2 = AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AuraAttributeSet->GetMaxHealthAttribute());
	deligate2.AddUObject(this,&UOverlayWidgetController::MaxHealthChanged);
	
} //this dont` work

* 이슈 : 위의 코드는 작동X

밑의 코드는 정상작동한다.

AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
		AuraAttributeSet->GetHealthAttribute()).AddUObject(this, &UOverlayWidgetController::HealthChanged);
	
	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
		AuraAttributeSet->GetMaxHealthAttribute()).AddUObject(this, &UOverlayWidgetController::MaxHealthChanged);

* 이유 : 

  • 로컬 변수: 'auto'를 사용하면 함수가 끝난 후 소멸되는 로컬 변수가 생성되어 대리자 바인딩이 손실됩니다.
  • 직접 호출: 호출을 직접 연결하면 위임 바인딩이 그대로 유지되고 작동합니다.

* 결론

직접호출을 이용하도록하자..

 

※ GetGameplayAttributeValueChangeDelegate(속성)

속성값이 변경될때 등록됨

FOnGameplayAttributeValueChange & GetGameplayAttributeValueChangeDelegate
(
    FGameplayAttribute Attribute
)

위젯컨트롤러의 공통부이므로 -> 부모인 Aura위젯컨트롤러에 virtual 로선언함이 올바르다.

virtual void BindCallbacksToDependencies();

 

2. 구체적 함수구현

Data가 변경될때마다 아래 함수가 실행된다.

Data안에 있는 newVal을 방송해주기만 하면된다!

지금은 마나통, 체력통이 구독중이다!

void UOverlayWidgetController::HealthChanged(const FOnAttributeChangeData& Data) const
{
	//OnHealthChanged.Broadcast(AuraAttributeSet->GetHealth()); Data 에 값이있음!
	OnHealthChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::MaxHealthChanged(const FOnAttributeChangeData& Data) const
{
	OnMaxHealthChanged.Broadcast(Data.NewValue);
}

유튜버(위젯컨트롤러)가 방송을하면, 구독자(마나통)가 newval을 가지고 할일을 함!

 

3. 바인딩함수의 실행위치?

변수들이 모두 set된 이후에 실행하는게 올바르다.

hud의 getter 내부

UOverlayWidgetController* AAuraHUD::GetOverlayWidgetController(const FWidgetControllerParams& WCParams)
{
	if(OverlayWidgetController == nullptr)
	{
		//(연결될클래스 , 생성될타입)
		//Outer : 생성될 오브젝트를 소유하는 UObject 객체
		//Class : 생성될 오브젝트의 클래스를 나타내는 UClass 정보
		OverlayWidgetController=NewObject<UOverlayWidgetController>(this,OverlayWidgetControllerClass);
		OverlayWidgetController->SetWidgetControllerParams(WCParams);
		OverlayWidgetController->BindCallbacksToDependencies();
		
		return OverlayWidgetController;
	}
	return OverlayWidgetController;
}

 

4. 결과

 

5. 의존성점검

Widget -> WidgetController -> ASC // 위젯컨트롤러는 위젯을 모름, ASC는 위젯컨트롤러를 모름

뷰 -> 컨트롤러 -> 모델(data)