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