這個教程是從UE4 Wiki上整理而來.git
在C++中直接使用Interface你們應該很熟悉。只是簡單先定義一個個有虛函數的基類,而後在子類中實現相應的虛函數。像這樣的虛函數的基類通常概念上叫接口。那接下來看看UE4中怎樣在C++中定義接口的。github
.h編輯器
#pragma once #include "TargetInterface.generated.h" UINTERFACE(MinimalAPI) class UTargetInterface : public UInterface { GENERATED_UINTERFACE_BODY() }; class ITargetInterface{ GENERATED_IINTERFACE_BODY() public: UFUNCTION(BlueprintImplementableEvent, meta=(FriendlyName = "On Interact")) void OnInteract(bool bNewOpen); virtual float GetHealth(); };
.cppide
#include "YourProject.h" #include "TargetInterface.h" UTargetInterface::UTargetInterface(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{ } // Give GetHealth a default implementation float ITargetInterface::GetHealth(){ return 0.0f; }
首先定義一個UTargetInterface這個是給引擎內部模塊用的,通常不會用到,可是要定義。函數
ITargetInterface是你要使用的類,你要聲明的函數接口都放在這裏面。若是是定義函數給C++用的,那麼你就直接按標準的C++聲明一個虛函數就OK了,而後你要實現這個接口的子類繼承ITargetInterface實現GetHealth函數就能夠了。若是是給Blueprint用的,就要在函數前一行聲明的UFUNCTION內加上BlueprintImplementableEvent,這樣藍圖就能夠實現這個接口了,藍圖中就像普通事件同樣實現。ui
.hspa
#pragma once #include "GameFramework/Actor.h" #include "TargetInterface.h" #include "NPCActor.generated.h" UCLASS() class MMWORLD_API NPCActor
: public AActor , public ITargetInterface
{ GENERATED_BODY() public: AInteractiveTargetActor();
virtual float GetHealth() override;
protected:
float Health;
};
.cppcode
#include "YourProject.h" #include "NPCActor.h" NPCActor::NPCActor() { Health = 100.0f; } float NPCActor::GetHealth() { return Health; }
在C++代碼中這樣調用.若是是你知道Actor類的實際類型,直接調用就能夠了。你不知道Actor的類型時候Interface纔有實際的用處。對象
auto MyInterface = Cast<ITargetInterface>(ActorInstance); if (MyInterface) { float ActorHealth = MyInterface->GetHealth(); }
可是這樣的接口藍圖中是沒法使用的,藍圖徹底沒法知道它的存在。你能夠再用Blueprint Function Library的方式再包裝一層,可是我以爲這不是很好。blog
在藍圖中實現Event接口:
以前的NPCActor由於已經繼承了ITargetInterface因此,你在藍圖編輯器裏能夠直接實現OnInteract接口事件。
那若是你純藍圖的Actor怎麼辦。
進入藍圖編輯點Class Settings
在Interfaces面板點Add加入Target Interface就行了
那怎調用這個藍圖實現的接口在C++裏?
看下面的代碼
if (ActorInstance->GetClass()->ImplementsInterface(ITargetInterface::StaticClass())) { ITargetInterface::Execute_OnInteract(ActorInstance, true); }
ActorInstance->GetClass()->ImplementsInterface(ITargetInterface::StaticClass())) 是用來判斷這個Actor是否實現了TargetInterface,無論是在藍圖仍是C++中均可以正確的判斷(可是隻有BlueprintImplementableEvent和BlueprintNativeEvent(這個後面再介紹)的函數才能夠被藍圖實現)。Execute_OnInteract執行藍圖事件,第一個參數是UObject對象(接口調用的執行目標對象),後面的參數就是OnInteract函數的參數。這個函數是UHT自動生成的。其實這個函數本質上就是調用的UObject的ProcessEvent,具體你能夠看生成的代碼。(你到這個目錄下的文件看看就知道了,Yourproject\Intermediate\Build\Win64\Inc\Yourproject\Yourproject.generated.cpp,Yourproject是你的項目名稱)
最後一個問題,那若是想要這個函數接口既能夠被C++實現又要被Blueprint實現怎麼辦?
你只要簡單的把BlueprintImplementableEvent改爲BlueprintNativeEvent就能夠了。
.h
#pragma once #include "InteractionsInterface.generated.h" UINTERFACE() class MMWORLD_API UInteractionsInterface : public UInterface { GENERATED_UINTERFACE_BODY() }; class MMWORLD_API IInteractionsInterface { GENERATED_IINTERFACE_BODY() public: UFUNCTION(BlueprintNativeEvent) void SwitchTurned(bool bNewOnOrOff, int32 CustomParam); };
.cpp
#include "MMWorld.h" #include "InteractionsInterface.h" UInteractionsInterface::UInteractionsInterface(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { }
實現的Actor
.h
#pragma once #include "GameFramework/Actor.h" #include "InteractionsInterface.h" #include "InteractiveTargetActor.generated.h" UCLASS() class MMWORLD_API AInteractiveTargetActor : public AActor , public IInteractionsInterface { GENERATED_BODY() public: AInteractiveTargetActor(); virtual void SwitchTurned_Implementation(bool bNewOnOrOff, int32 CustomParam) override; UFUNCTION(BlueprintImplementableEvent, Category = Interactive) void SwitchAllTurnedOnOrOff(bool bOnOrOff); UFUNCTION(BlueprintCallable, Category = Interactive) bool IsSwitchTurned(int32 Index); UFUNCTION(BlueprintCallable, Category = Interactive) bool IsSwitchAllTurnedOn(); UFUNCTION(BlueprintCallable, Category = Interactive) bool IsSwitchAllTurnedOff(); protected: UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (ClampMin = "1", ClampMax = "32", UIMin = "1", UIMax = "32")) int32 NeedSwitchTurnedNum; uint32 SwitchTurnedStates; };
SwitchTurned在C++中要實現的函數是virtual void SwitchTurned_Implementation(bool bNewOnOrOff, int32 CustomParam) override; (BlueprintNativeEvent的函數名字_Implementation)。這個函數也是UHT自動生成的。
若是是你在Blueprint中是實現了SwitchTurned接口,那麼C++的實現就會被覆蓋隱藏掉。
那若是你的藍圖又要掉用C++接口實現怎麼辦?
UE4中沒有直接實現這樣的機制。可是你能夠把SwitchTurned_Implementation實現提取出來一個新函數,而後把這個函數定義成UFUNCTION(BlueprintCallable, Category = Interactive),而後在藍圖中調用這個函數就解決了。
好了就介紹到這裏,第一次寫關於UE4的東西,不對的地方但願你們指正。但願這個對你有幫助。
參考例子:
https://github.com/henrya2/MMWorld
參考文章: