[英]Unreal Engine crash with AddDynamic
我在綁定OnAudioFinished委托時遇到問題。
搜索了一段時間,但尚未找到好的答案。 我已經遵循了這個答案 !
我的代碼完全沒有任何錯誤地編譯,但是當我的項目正在加載時,它會因以下錯誤而崩潰:
UE4Editor_!TBaseDynamicMulticastDelegate<FWeakObjectPtr,void>::__Internal_AddDynamic<UAudioController>() [d:\path\delegates\delegatesignatureimpl.inl:1140]
UE4Editor_Project!UAudioController::UAudioController() [d:\path\private\audiocontroller.cpp:17]
UE4Editor_Project!InternalConstructor<UAudioController>()
我真正理解的是構造函數使我的引擎崩潰,但是我不知道為什么會這樣。 這是負責此綁定的代碼。
。H
static UAudioComponent* AudioComponent;
public:
UAudioController();
void SoundFinished();
.cpp
UAudioController::UAudioController()
{
AudioComponent->OnAudioFinished.AddDynamic(this, &UAudioController::SoundFinished);
}
void UAudioController::SoundFinished()
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("Audio Finished trigger"));
}
在UE中,構造函數運行期間屬性未正確初始化。 它們是在PostInitProperties
時(從CDO加載后)。
另外,您應該問自己是否需要靜態類。 如果您需要Singleton,可以將其存儲在GameInstance中 。 它更安全,尤其是在UE環境中(您不能具有靜態UPROPERTY()字段等)。
我認為在BeginPlay
期間綁定此事件就足夠了。 刪除是一個好習慣,盡管使用動態綁定時不必刪除
// AudioController.h
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReasonType) override;
// AudioController.cpp
void UAudioController::BeginPlay() {
Super::BeginPlay();
AudioComponent->OnAudioFinished.AddDynamic(this, &UAudioController::SoundFinished);
}
void UAudioController::EndPlay(const EEndPlayReason::Type EndPlayReasonType) {
AudioComponent->OnAudioFinished.RemoveDynamic(this, &UAudioController::SoundFinished);
Super::EndPlay(EndPlayReasonType);
}
編輯:由於您使用控制器后綴命名了類,所以我想這將是該角色在級別中的一次出現。 因此,您無需具有靜態指針(它可能會被破壞-再次,這是UE的特殊性),只需將AudioComponent作為控制器中的公共成員即可:
// AudioController.h
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "My Audio Conmponent", meta = (AllowPrivateAccess = "true"))
UAudioComponent* AudioComponent;
然后在構造函數中正確初始化它:
UAudioController::UAudioController()
: Super()
{
AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("MyAudioComponent"));
}
要么
UAudioController::UAudioController(const class FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("MyAudioComponent"));
}
您的組件將被正確創建,綁定的函數將按預期執行。
另外,正如@JKovalsky所提到的,在使用動態委托時,必須用UFUNCTION()
宏標記您的SoundFinished
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.