簡體   English   中英

AddDynamic導致虛幻引擎崩潰

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM