Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashes - Nested behavior trees #7

Open
Fantastick-svg opened this issue Feb 15, 2024 · 3 comments
Open

Crashes - Nested behavior trees #7

Fantastick-svg opened this issue Feb 15, 2024 · 3 comments

Comments

@Fantastick-svg
Copy link

Fantastick-svg commented Feb 15, 2024

The memory management of utility nodes does not take into account the nested behavioral trees of "RunBehaviorDynamic" tasks within the UBehaviorTreeComponent. It only tries to access the RootTree memory, causing various crashes.

@mastercoms
Copy link
Member

Hi, thanks for the report! Could you let us know more about how to set this up/reproduce that with an example tree?

@Fantastick-svg
Copy link
Author

Fantastick-svg commented Feb 16, 2024

Hi, sure no problem. Just create new BehaviorTree asset which has selector under the root node. That selector can for example run EQS to perceive player using perception system. In my case I have two sub nodes of the selector. Each if them is sequence which contains a decorator. One should be run if TargetActor is set and second should run if TargetActor is not set.

image

In AIController OnPossess I run my default BehaviorTree which can be seen on the screenshot above. We also need to set the subtree which will find the RunBehaviorDynamic node within the default BehaviorTree using the GameplayTag.

if(RunBehaviorTree(DefaultBT))
	{
		const TSoftObjectPtr<UBehaviorTree> BehaviorSoftPtr = AIConfig->ActiveBehaviors.FindRef(MyGameplayTags::AI_Role_Active);

		if(IsValid(BehaviorSoftPtr.LoadSynchronous()))
		{
			if(UBehaviorTreeComponent* BTC = Cast<UBehaviorTreeComponent>(GetBrainComponent()))
			{
				BTC->SetDynamicSubtree(MyGameplayTags::AI_Role_Active, BehaviorSoftPtr.Get());
			}
		}
	}

Now, the Active Behavior looks like for example this..

image

Once the UtilityDecorator is reach, we got Crash at

void UIAUSBTDecorator_Utility::InitializeMemory(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory,
                                                EBTMemoryInit::Type InitType) const

Directly at the line

Memory->MemoryUtilityComposite->BehaviorMemories.Empty();

with output warning: `this' is not accessible (substituting 0)

I don't know if it's because the data is on another thread... are behavior trees multithreaded? Unfortunately I don't have much time to dig deeper. In my opinion, the decorator is trying to access the memory of the node at incorrect instance index "OwnerComp.GetActiveInstanceIdx()", which returns the memory of the node to the RunBehaviorDynamic task in the RootTree? Which might not be accessible that way? I hope this helps at least a little bit.

EDIT:
I also noticed a crash even if the UtilitySelector with the UtilityDecorator is located below the classic selector and the "TargetSelector" as shown on the screen receives an abort and move to another lower priority node. At the moment when it is currently scoring considerations from some Behaviors, it sometimes happens that a crash occurs.

FIAUSBehaviorContext IAUSEvaluator::ChooseBehavior(AAIController* AIController, const TArray<AActor*> Targets, bool bCheckTeamAttitude /*= true*/)

	for (const auto& Consideration : Behaviors[Idx].Considerations)
			{
				const float Score = Consideration->Score(Context); // Crash happens right here in the middle of the loop
				if (Score <= 0)
				{
					Context.TotalScore = 0;
					break;
				}

				const float Modification = (1.0 - Score) * Behaviors[Idx].CompensationFactor;
				Context.TotalScore *= Score + (Modification * Score);
			}

@mastercoms
Copy link
Member

Thanks for the report, we're looking into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants