x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Behavior tree appears to call function after unpossess and destroy of AI

Hi All

I'm using standard unpossess and destroy actor nodes in blueprints to remove ai control from a character that I'm about to possess with the player controller. The editor crashes very soon after those nodes have successfully completed (when I say that, I don't know if they worked, but they ran, with breakpoints, and no error messages). The stack and break messages show that the crash is due to a C++ AI function being called by the blackboard/behavior tree blueprint.

I have initialized the blackboard and behavior tree in the possess function of the AI class, in C++. Should I have a custom unpossess function that deactivates these things? Any ideas about what I've done wrong here would be massively appreciated!

Thanks!

 UE4Editor-RRDevelop-Win64-DebugGame.dll!TArray<FQueryKVPair * __ptr64,FDefaultAllocator>::FindByPredicate<bool <lambda>(FQueryKVPair *) >(ARRAIController::IsPlayerInRange::__l7::bool <lambda>(FQueryKVPair *) Pred) Line 1047    C++
  UE4Editor-RRDevelop-Win64-DebugGame.dll!ARRAIController::IsPlayerInRange() Line 171    C++
  UE4Editor-RRDevelop-Win64-DebugGame.dll!ARRAIController::execIsPlayerInRange(FFrame & Stack, void * const Result) Line 18    C++
  UE4Editor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Result) Line 3699    C++
  UE4Editor-CoreUObject.dll!UObject::CallFunction(FFrame & Stack, void * const Result, UFunction * Function) Line 395    C++
  UE4Editor-CoreUObject.dll!UObject::ProcessContextOpcode(FFrame & Stack, void * const Result, bool bCanFailSilently) Line 1451    C++
  UE4Editor-CoreUObject.dll!UObject::execLetBool(FFrame & Stack, void * const Result) Line 1370    C++
  UE4Editor-CoreUObject.dll!UObject::ProcessInternal(FFrame & Stack, void * const Result) Line 602    C++
  UE4Editor-CoreUObject.dll!UObject::CallFunction(FFrame & Stack, void * const Result, UFunction * Function) Line 516    C++
  UE4Editor-CoreUObject.dll!UObject::execVirtualFunction(FFrame & Stack, void * const Result) Line 1530    C++
  UE4Editor-CoreUObject.dll!UObject::ProcessInternal(FFrame & Stack, void * const Result) Line 602    C++
  UE4Editor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Result) Line 3699    C++
  UE4Editor-CoreUObject.dll!UObject::ProcessEvent(UFunction * Function, void * Parms) Line 924    C++
  UE4Editor-AIModule.dll!UBTService_BlueprintBase::ReceiveTick(AActor * OwnerActor, float DeltaSeconds) Line 703    C++
  UE4Editor-AIModule.dll!UBTCompositeNode::OnNodeActivation(FBehaviorTreeSearchData & SearchData) Line 129    C++
  UE4Editor-AIModule.dll!UBehaviorTreeComponent::ProcessExecutionRequest() Line 879    C++
  UE4Editor-AIModule.dll!UBehaviorTreeComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction) Line 792    C++
  UE4Editor-Engine.dll!UActorComponent::ConditionalTickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction & ThisTickFunction) Line 906    C++
  UE4Editor-Engine.dll!FActorComponentTickFunction::ExecuteTick(float DeltaTime, ELevelTick TickType, ENamedThreads::Type CurrentThread, const TRefCountPtr<FGraphEvent> & MyCompletionGraphEvent) Line 470    C++
  UE4Editor-Engine.dll!FTickTaskSequencer::FTickFunctionTask::DoTask(ENamedThreads::Type CurrentThread, const TRefCountPtr<FGraphEvent> & MyCompletionGraphEvent) Line 322    C++
  UE4Editor-Engine.dll!TGraphTask<FTickTaskSequencer::FTickFunctionTask>::ExecuteTask(TArray<FBaseGraphTask *,FDefaultAllocator> & NewTasks, ENamedThreads::Type CurrentThread) Line 671    C++
  UE4Editor-Core.dll!FTaskThread::ProcessTasks(int QueueIndex, bool bAllowStall) Line 428    C++
  UE4Editor-Core.dll!FTaskThread::ProcessTasksUntilQuit(int QueueIndex) Line 271    C++
  UE4Editor-Core.dll!FTaskGraphImplementation::WaitUntilTasksComplete(const TArray<TRefCountPtr<FGraphEvent>,TInlineAllocator<4,FDefaultAllocator> > & Tasks, ENamedThreads::Type CurrentThreadIfKnown) Line 984    C++
  UE4Editor-Engine.dll!FTaskGraphInterface::WaitUntilTaskCompletes(const TRefCountPtr<FGraphEvent> & Task, ENamedThreads::Type CurrentThreadIfKnown) Line 188    C++
  UE4Editor-Engine.dll!FTickTaskSequencer::ReleaseTickGroup(ETickingGroup WorldTickGroup, bool bBlockTillComplete) Line 187    C++
  UE4Editor-Engine.dll!FTickTaskManager::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 722    C++
  UE4Editor-Engine.dll!UWorld::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 693    C++
  UE4Editor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1116    C++
  UE4Editor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1227    C++
  UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 307    C++
  UE4Editor.exe!FEngineLoop::Tick() Line 2214    C++
  UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 131    C++
  UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 191    C++
  [External Code]    
Product Version: Not Selected
Tags:
more ▼

asked Dec 15 '14 at 02:35 PM in Blueprint Scripting

avatar image

robbiecooper
756 79 60 233

avatar image MieszkoZ STAFF Dec 15 '14 at 02:53 PM

The stack and break messages show that the crash is due to a C++ AI function being called by the blackboard/behavior tree blueprint.

It would be very helpful if you attached log or callstack to your question.

--mieszko

avatar image robbiecooper Dec 15 '14 at 03:03 PM

Hi Mieszko, I have added to question, thanks...

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

Ok, I see what's going on. So you've encountered a deeper engine level issue (meaning it's not AI-specific) of ticking components of actors that have been already destroyed. This should not be happening.

However, there's an easy remedy for you. You should not be calling Destroy on actors, ever (unless you really, really know what your doing). Yeah, I know it's available in blueprints, and should be safe. I probably should start an internal thread regarding this as well.

Regardless, when dealing with AI, unpossesing should be enough. Once an AIController is no longer being used it should get automatically garbage-collected at some point. If it doesn't then that's a bug and please report it.

Cheers,

--mieszko

more ▼

answered Dec 15 '14 at 03:40 PM

avatar image

MieszkoZ STAFF
7.3k 223 57 412

avatar image robbiecooper Dec 15 '14 at 03:43 PM

Great, thanks for the swift response...

avatar image robbiecooper Dec 15 '14 at 03:46 PM

Oops. No dice. I removed the destroy node, and I'm still getting the same issue.

avatar image robbiecooper Dec 15 '14 at 03:49 PM

I'll report this as a bug, as you suggest, but I can't believe it is. There must be loads of people doing this and not getting crashes...

avatar image zoid Dec 15 '14 at 04:27 PM

If it's any help I specifically stop my brain component in the controller before destroying.

@MieszkoZ can you elaborate on why you should never call Destroy on an actor? What if I want to remove them from the world? This seems to work well for me. I also don't see anywhere in the engine where an AIController with no pawn gets cleaned up, a controller is just an AActor so I'd like to know where/how that's supposed to automatically get collected? Thanks.

avatar image robbiecooper Dec 15 '14 at 04:34 PM

Hi Zoid. I have no brain component- if by that you mean a sensing component or something like that. I'm referring to my project here, obvs ;)

The AI is using arrays in the character class to know if something is in range. If you do something to shut down the behavior tree, I'd love to know what that is- that was kind of what I was thinking needed to be done.

avatar image MieszkoZ STAFF Dec 15 '14 at 04:43 PM

@robbiecooper UBehaviorTreeComponent is a BrainComponent, and that's what's in your callstack.

@zoid Regarding destroying actors, all actors get garbage-collected when there are no references to them, or their owner got/is going to be destroyed. Calling destroy directly is not a good practice since it may bypass multiple mechanisms under the hood that observe different state changes of an actor. As a generic rule destroying actors should be left to GC, "unless you know what you're doing"(tm) ;)

avatar image robbiecooper Dec 15 '14 at 04:48 PM

Ahhhh. StopTree(). I hope this is the solution. If I don't comment again then it is. Thanks!

avatar image zoid Dec 15 '14 at 05:51 PM

@MieszoZ I do see where a controller attaches itself to the pawn's root component, but I don't see who owns the controller.

What happens when you spawn an actor (SpawnActor) with a null owner? Will that actor get reclaimed automatically? How do you spawn temp actors that don't get GCed?

avatar image shopkins May 12 '16 at 07:10 AM

@MieszkoZ I posted a similar problem here: https://answers.unrealengine.com/questions/417853/proper-way-to-destroy-pawn-with-behavior-tree.html

In Blueprints, how do you remove the AI from the world without calling destroy actor? In my case it seems like the AI is in the middle of execution of a tick event when destroy actor is called, and then the tick event in the task reports an error when accessing its controlled pawn.

avatar image zoid Dec 15 '14 at 07:22 PM

@MieszkoZ I've dug into the code more on this: ULevel collects references to all spawned actors in the reference collector path, see Line 281 of Level.cpp. SpawnActor adds the AActor to this array. Currently setting an Owner to null doesn't affect GC that I can see.

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question