2017-04-24 3 views
0

Ich habe ein Problem mit der Bindung von OnAudioFinished Delegaten.Unreal Engine Absturz mit AddDynamic

Gesucht seit einiger Zeit, aber habe noch keine gute Antwort gefunden. Ich bin diesem answer gefolgt!

Mein Code kompiliert ohne Fehler überhaupt, aber wenn mein Projekt wird geladen es mit diesem Fehler abstürzt:

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>() 

Was ich verstehe, ist, dass Konstruktor meinen Motor zermalmt, aber ich weiß nicht, warum ist das passiert. Hier ist mein Code, der für diese Bindung verantwortlich ist.

.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")); 
} 
+3

Ihr Debugger wird Ihr bester Freund für solche Probleme sein. Das heißt, ich vermute, dass AudioComponent beim Aufruf von AddDynamic noch nicht initialisiert ist. – Sneftel

+1

Stellen Sie außerdem sicher, dass Ihre Funktion 'SoundFinished' UFUNCTION ist. – JKovalsky

+0

Überprüfen Sie meine bearbeitete Antwort. Verwenden von 'NewObject <...>()' (wie Sie im Kommentar unten erwähnt) ist definitiv nicht eine richtige Art, mit Komponenten zu arbeiten. –

Antwort

1

In UE, Eigenschaften nicht ordnungsgemäß während Konstruktor Lauf initialisiert. Sie sind, wenn PostInitProperties aufgerufen wird (nach dem Laden von CDO).

Auch Sie sollten sich fragen, ob eine statische Klasse notwendig ist. Wenn Sie Singleton benötigen, können Sie dies in GameInstance speichern. Es ist sicherer, besonders in der UE-Umgebung (Sie können kein statisches UPROPERTY() Feld usw. haben)

Ich glaube, dass das Binden dieses Ereignisses während BeginPlay ausreichend sein sollte. Entfernen gute Praxis ist, wenn auch nicht necesarry wenn Dynamische Bindung

// 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); 
} 

EDIT: Da Sie Ihre Klasse mit -Controller Suffix genannt, nehme ich an, dass diese einzelne Vorkommen dieser Schauspieler in Ebene sein wird. So müssen Sie nicht statisch Zeiger haben müssen (es könnte zerstört werden - auch dies UE Spezialität ist), einfach nur AudioComponent als öffentlichen Mitglied in Ihrem Controller haben:

// AudioController.h 
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "My Audio Conmponent", meta = (AllowPrivateAccess = "true")) 
    UAudioComponent* AudioComponent; 

und dann richtig initialisieren es in Konstruktor:

UAudioController::UAudioController() 
    : Super() 
{ 
    AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("MyAudioComponent")); 
} 

oder

UAudioController::UAudioController(const class FObjectInitializer& ObjectInitializer) 
    : Super(ObjectInitializer) 
{ 
    AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("MyAudioComponent")); 
} 

Ihre Komponente korrekt erstellt und binded Funktion wird wie erwartet ausgeführt.

Auch als @JKovalsky erwähnt, Ihre SoundFinished Methode muss mit UFUNCTION() Makro markiert werden, wenn Dynamische Delegierten verwenden.

+0

Ich werde es jetzt testen und Feedback geben, wie es geht! : 3 Danke für die große Resonanz. –

+0

Die von Ihnen bereitgestellten virtuellen Funktionen scheinen nicht zu funktionieren. Sie generieren folgende Fehler: 'Klasse" UObject "hat kein Mitglied" BeginPlay " Member-Funktion mit 'überschreiben' überschreibt nicht eine Basisklasse Mitglied. Ich suchte nach einer Lösung, die mich dazu führte, Actor.h jedoch zu integrieren Es hat nichts verändert. Ohne sie kompiliert ich kein Problem, jedoch bekomme ich diese SoundFinished noch nicht einmal mit Bind im Konstruktor feuern. Meine Basisklasse erbt Formular UObject –

+1

@AdrianRozlach Was ist das Basisobjekt für 'UAudioController'? Ich nehme an, dass es "AActor" ist, aber es scheint, als wäre es direkt von "UObject" geerbt ... Wenn es das letztere ist, gibt es dafür einen Grund? –

Verwandte Themen