繁体   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