我遇到绑定OnAudioFinished委托的问题。
搜索了一段时间但尚未找到好的答案。我已经关注了answer!
我的代码编译完全没有任何错误,但是当我的项目加载时,它会因此错误而崩溃:
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"));
}
答案 0 :(得分:1)
在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);
}
编辑:由于您使用 Controller 后缀命名了您的类,我认为这将是该级别中此actor的单次出现。所以你不需要有静态指针(它可能会被破坏 - 再次,这是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所述,使用动态代表时,您的SoundFinished
方法必须使用UFUNCTION()
宏标记。