This commit is contained in:
SoulliesOfficial
2026-01-03 18:19:39 -05:00
parent 3bcd7c1cf8
commit 33b1795c1f
7387 changed files with 2762819 additions and 716926 deletions

View File

@@ -76,11 +76,12 @@ namespace Opsive.BehaviorDesigner.Runtime
return;
}
var active = IsActive();
ClearTree();
m_Subtree = value as Subtree;
m_SubtreeOverride = false;
InheritSubtree(false);
if (IsActive() && !IsPaused()) {
if (active && !IsPaused()) {
StartBehavior();
}
#if UNITY_EDITOR
@@ -260,24 +261,38 @@ namespace Opsive.BehaviorDesigner.Runtime
}
// The local behavior tree variables should be used.
m_Data.DeserializeSharedVariables(force);
if (m_Subtree.DeserializeSharedVariables(force) && Application.isPlaying && !m_SubtreeOverride && m_Data.SharedVariables != null) {
m_Data.DeserializeSharedVariables(this, force, false);
if (m_Subtree.DeserializeSharedVariables(force || (Application.isPlaying && !m_SubtreeOverride)) && Application.isPlaying && !m_SubtreeOverride && m_Data.SharedVariables != null) {
// Set the binding on the subtree before the tasks are loaded. This is necessary because a new SharedVariable instance may need to be created.
for (int i = 0; i < m_Data.SharedVariables.Length; ++i) {
m_Subtree.Data.OverrideVariableBinding(this, m_Data.SharedVariables[i]);
}
}
// Subtrees will not have access to GameObject or Scene variables. Copy the reference from the parent tree in order to allow the subtree to correctly load all of the SharedVariables.
if (Application.isPlaying && !m_SubtreeOverride && m_Data.VariableByNameMap != null) {
foreach (var variableMap in m_Data.VariableByNameMap) {
var sharedVariable = variableMap.Value;
if (sharedVariable.Scope == SharedVariable.SharingScope.GameObject || sharedVariable.Scope == SharedVariable.SharingScope.Scene) {
var variableAssignment = new BehaviorTreeData.VariableAssignment(sharedVariable.Name, sharedVariable.Scope);
if (m_Subtree.Data.VariableByNameMap.ContainsKey(variableAssignment)) {
continue;
}
m_Subtree.Data.VariableByNameMap.Add(variableAssignment, sharedVariable);
}
}
}
if (!m_Subtree.Deserialize(force, false, Application.isPlaying, false)) {
if (!m_Subtree.Deserialize(force || (Application.isPlaying && !m_Subtree.Pooled && !m_SubtreeOverride), false, Application.isPlaying, false)) {
return false;
}
// Copy the deserialized objects at runtime to ensure each object is unique.
if (Application.isPlaying && !m_SubtreeOverride) {
m_Data.OverrideData(this, m_Subtree.Data, m_Data.SharedVariables);
m_Data.OverrideData(this, m_Subtree.Data, m_Data.SharedVariables, m_Subtree.Pooled);
m_GameObject = gameObject;
m_SubtreeOverride = true;
}
return true;
}
@@ -527,7 +542,7 @@ namespace Opsive.BehaviorDesigner.Runtime
branchComponents = world.EntityManager.AddBuffer<BranchComponent>(entity);
}
var startBranchIndex = (ushort)branchComponents.Length;
branchComponents.Add(new BranchComponent() { ActiveIndex = ushort.MaxValue, NextIndex = ushort.MaxValue, LastActiveIndex = ushort.MaxValue });
branchComponents.Add(new BranchComponent() { ActiveIndex = ushort.MaxValue, NextIndex = ushort.MaxValue, LastActiveIndex = ushort.MaxValue, CanExecute = true });
ComponentUtility.AddEvaluationComponent(world, entity, m_Data.LogicNodes.Length, m_EvaluationType, m_MaxEvaluationCount);
world.EntityManager.AddComponent<EnabledFlag>(entity);
@@ -543,6 +558,11 @@ namespace Opsive.BehaviorDesigner.Runtime
var reevaluateTaskSystemGroup = world.GetOrCreateSystemManaged<ReevaluateTaskSystemGroup>();
var interruptTaskSystemGroup = world.GetOrCreateSystemManaged<InterruptTaskSystemGroup>();
// Add the necessary cleanup systems.
var behaviorTreeSystemGroup = world.GetOrCreateSystemManaged<BehaviorTreeSystemGroup>();
behaviorTreeSystemGroup.AddSystemToUpdateList(world.GetOrCreateSystem<EvaluationCleanupSystem>());
behaviorTreeSystemGroup.AddSystemToUpdateList(world.GetOrCreateSystem<InterruptedCleanupSystem>());
var taskComponents = world.EntityManager.GetBuffer<TaskComponent>(entity);
var taskOffset = (ushort)(eventTask.ConnectedIndex - taskComponents.Length);
for (int i = eventTask.ConnectedIndex; i < m_Data.LogicNodes.Length; ++i) {
@@ -566,7 +586,7 @@ namespace Opsive.BehaviorDesigner.Runtime
// A new branch component may need to be added to keep track of the active task index for that branch.
if (branchIndex >= branchComponents.Length) {
branchComponents.Add(new BranchComponent() { ActiveIndex = ushort.MaxValue, NextIndex = ushort.MaxValue, LastActiveIndex = ushort.MaxValue });
branchComponents.Add(new BranchComponent() { ActiveIndex = ushort.MaxValue, NextIndex = ushort.MaxValue, LastActiveIndex = ushort.MaxValue, CanExecute = true });
}
}
@@ -918,12 +938,12 @@ namespace Opsive.BehaviorDesigner.Runtime
if (m_Data.LogicNodes[i] is T task) {
return task;
}
if (m_Data.LogicNodes[i] is IStackedNode stackedNode) {
if (stackedNode.Nodes == null) {
if (m_Data.LogicNodes[i] is IContainerNode containerNode) {
if (containerNode.Nodes == null) {
continue;
}
for (int j = 0; j < stackedNode.Nodes.Length; ++j) {
if (stackedNode.Nodes[j] is T stackedTask) {
for (int j = 0; j < containerNode.Nodes.Length; ++j) {
if (containerNode.Nodes[j] is T stackedTask) {
return stackedTask;
}
}
@@ -959,12 +979,12 @@ namespace Opsive.BehaviorDesigner.Runtime
return count;
}
}
if (m_Data.LogicNodes[i] is IStackedNode stackedNode) {
if (stackedNode.Nodes == null) {
if (m_Data.LogicNodes[i] is IContainerNode containerNode) {
if (containerNode.Nodes == null) {
continue;
}
for (int j = 0; j < stackedNode.Nodes.Length; ++j) {
if (stackedNode.Nodes[j] is T stackedTask) {
for (int j = 0; j < containerNode.Nodes.Length; ++j) {
if (containerNode.Nodes[j] is T stackedTask) {
foundTasks[count] = stackedTask;
count++;
if (count == foundTasks.Length) {
@@ -1097,7 +1117,7 @@ namespace Opsive.BehaviorDesigner.Runtime
continue;
}
pausableTask.Pause(world, entity);
} else if (m_Data.LogicNodes[i] is Task task) {
} else if (tasks[i] is Task task) {
task.OnEnd();
}
}
@@ -1188,8 +1208,6 @@ namespace Opsive.BehaviorDesigner.Runtime
/// <summary>
/// Clears all of the tree components.
/// </summary>
/// <param name="world">The world that the entity exists in.</param>
/// <param name="entity">The entity that contains the behavior tree.</param>
private void ClearTree()
{
ClearTree(m_World, m_Entity);
@@ -1232,8 +1250,8 @@ namespace Opsive.BehaviorDesigner.Runtime
world.EntityManager.RemoveComponent(entity, reevaluateTask.ReevaluateFlag);
}
}
} else if (m_Data.LogicNodes[i] is Task monoTask) {
monoTask.ClearBufferElement(world, entity);
} else if (m_Data.LogicNodes[i] is Task task) {
task.ClearBufferElement(world, entity);
if (m_Data.LogicNodes[i] is IConditional) {
if (world.EntityManager.HasComponent(entity, typeof(TaskObjectReevaluateFlag))) {
world.EntityManager.RemoveComponent(entity, typeof(TaskObjectReevaluateFlag));