[UE4]代理事件(C++)


用宏定義類似格式:

DECLARE_DELEGATE   //普通代理
DECLARE_DYNAMIC_DELEGATE_TwoParams   //動態代理
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams   //動態多廣播代理
 
//多出的兩個關鍵字的作用
In the case of multicast delegates,
 any number of entities within your code base can respond to the same event and receive the inputs and use them.

In the case of dynamic delegates,
 the delegate can be saved/loaded within a Blueprint graph (they're called Events/Event Dispatcher in BP).

DYNAMIC:可以在藍圖里被序列化后定義和綁定操作。

MULTICAST:可實現一個事件類型多函數廣播(事件類型必須聲明為藍圖類型)

XXXParams:(使用DYNAMIC時)參數個數,宏定義參數里一個參數類型對應一個參數名字。

 

//聲明位置(鞏固下C++基礎)

如果用到了靜態事件類型的變量,因為需要在類外部聲明這個變量,所以宏定義代理需要放在類外部。否則,隨便放哪都行(在使用之前)。

 

注意:

1.當使用MULTICAST時,聲明的代理事件類型需要聲明為藍圖類型。不然報錯,如:

//聲明代理
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FLoadDesignsDelegateEvent, const TArray<FDesignInfo>&,
 _designsInfo, const bool, _result);
 
//聲明代理事件類型
static FLoadDesignsDelegateEvent m_OnLoadDesignsEve;
 
//調用代理事件
UFUNCTION(BlueprintCallable, Category = "BZone|SaveGameSystem")
static
 void GetOneDesignFromServer(const FString &_userId, const FString& _desingId,const FLoadDesignDelegateEvent& _eve);
 
//報錯
F:/UE4_Projects/CGroupSystem_Server/Plugins/SaveGamePlugin/Source/SaveGamePlugin/SaveGame/Public/SaveGameBPLibrary.h(75)
 : Type '{multicast delegate type}' is not supported by blueprint. Function: GetAllDesignsFromServer Parameter _event

2.調用時先檢查下是否綁定了代理

RamaMeleeWeapon_OnHit.IsBound() 

新版本的:m_DelegateEvent.ExecuteIfBound(params...);

3.UObject和C++的不同綁定

 不是MULTICAST:

//UObject
RamaMeleeWeaponComp->RamaMeleeWeapon_OnHit.BindUObject(this,&USomeClass::RespondToMeleeDamageTaken);
//C++
RamaMeleeWeaponComp->RamaMeleeWeapon_OnHit.BindRaw(this,&FSomeRawCPPClass::RespondToMeleeDamageTaken);

是MULTICAST:

TScriptDelegate<> t_de1;

t_de1.BindUFunction(this, STATIC_FUNCTION_FNAME(TEXT("ADrawHouseManager::Mouse_LeftOneClick")));

m_leftOneClickEvents.Add(t_de1);

並且Mouse_LeftOneClickDown();需要UFUNCTION()修飾,否則事件可以添加進代理,但不會進入函數(不在UE的函數列表里所以無法找到並執行)。

 封裝后的:

TMap<TMulticastScriptDelegate<>*, TScriptDelegate<>> m_bindEvents;

void ADrawHouseManager::AddBindEvent(TMulticastScriptDelegate<>* const _dele, const FString& _functionName)  
{     
    if (_dele!=nullptr&&!_functionName.IsEmpty())  
    {  
        TScriptDelegate<> t_de;  
        FString t_str = "ADrawHouseManager::" + _functionName;  
        t_de.BindUFunction(this, STATIC_FUNCTION_FNAME(*t_str));  
        _dele->Add(t_de);  
        m_bindEvents.Add(_dele, t_de);  
    }     
}  

別忘記對象銷毀時在析構函數里調用解綁!!!

void ADrawHouseManager::UnBindAllInputEventsFromPC()  
{  
    if (m_bindEvents.Num()>0)  
    {  
        for (auto it:m_bindEvents)  
        {  
            TMulticastScriptDelegate<>* t_dele = it.Key;  
            if (t_dele!=nullptr)  
            {  
                t_dele->Remove(it.Value);  
            }             
        }  
    }  
}  
ADrawHouseManager::~ADrawHouseManager()  
{  
    UnBindAllInputEventsFromPC();  
}  

其余細節見:

https://wiki.unrealengine.com/Delegates_In_UE4,_Raw_Cpp_and_BP_Exposed  //C++代理事件

https://docs.unrealengine.com/latest/CHN/Programming/UnrealArchitecture/Delegates/index.html  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM