#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime { using Opsive.GraphDesigner.Runtime; using Opsive.GraphDesigner.Runtime.Variables; using System; using UnityEngine; /// /// The behavior tree stored on a Scriptable Object. /// [CreateAssetMenu(fileName = "Subtree", menuName = "Opsive/Behavior Designer/Subtree", order = 1)] public class Subtree : ScriptableObject, IGraph, ISharedVariableContainer { [Tooltip("The behavior tree data.")] [SerializeField] private BehaviorTreeData m_Data = new BehaviorTreeData(); public string Name { get => name; set => name = value; } public SharedVariable.SharingScope VariableScope { get => SharedVariable.SharingScope.Graph; } public BehaviorTreeData Data { get => m_Data; } public UnityEngine.Object Parent { get => this; } public ILogicNode[] LogicNodes { get => m_Data.LogicNodes; set => m_Data.LogicNodes = value; } public IEventNode[] EventNodes { get => m_Data.EventNodes; set => m_Data.EventNodes = value; } public SharedVariable[] SharedVariables { get => m_Data.SharedVariables; set => m_Data.SharedVariables = value; } public ushort[] DisabledLogicNodes { get => m_Data.DisabledLogicNodes; set => m_Data.DisabledLogicNodes = value; } public ushort[] DisabledEventNodes { get => m_Data.DisabledEventNodes; set => m_Data.DisabledEventNodes = value; } public LogicNodeProperties[] LogicNodeProperties { #if UNITY_EDITOR get => m_Data.LogicNodeProperties; set => m_Data.LogicNodeProperties = value; #else get => null; set { } #endif } public NodeProperties[] EventNodeProperties { #if UNITY_EDITOR get => m_Data.EventNodeProperties; set => m_Data.EventNodeProperties = value; #else get => null; set { } #endif } public GroupProperties[] GroupProperties { #if UNITY_EDITOR get => m_Data.GroupProperties; set => m_Data.GroupProperties = value; #else get => null; set { } #endif } public int UniqueID { get => m_Data.UniqueID; } /// /// Serializes the behavior tree. /// public void Serialize() { m_Data.Serialize(); } /// /// Deserialize the behavior tree. /// /// Should the behavior tree be force deserialized? /// True if the tree was deserialized. public bool Deserialize(bool force = false) { return Deserialize(null, force, false, true, null); } /// /// Deserialize the behavior tree. /// /// Should the behavior tree be force deserialized? /// Should the subtrees be injected into the behavior tree? /// Can the SharedVariables be deep copied? /// True if the tree was deserialized. public bool Deserialize(bool force, bool injectSubtrees, bool canDeepCopyVariables = true) { return Deserialize(null, force, injectSubtrees, canDeepCopyVariables, null); } /// /// Deserialize the behavior tree. /// /// The component that the graph is being deserialized from. /// Should the behavior tree be force deserialized? /// Should the subtrees be injected into the behavior tree? /// Can the SharedVariables be deep copied? /// A list of SharedVariables that should override the current SharedVariable value. /// True if the tree was deserialized. public bool Deserialize(IGraphComponent graphComponent, bool force, bool injectSubtrees, bool canDeepCopyVariables, SharedVariableOverride[] sharedVariableOverrides) { if (m_Data == null) { return false; } return m_Data.Deserialize(graphComponent, this, force, injectSubtrees, canDeepCopyVariables, sharedVariableOverrides); } /// /// Deserializes the SharedVariables. This allows the SharedVariables to be deserialized independently. /// /// Should the variables be forced deserialized? /// True if the SharedVariables were deserialized. public bool DeserializeSharedVariables(bool force) { if (m_Data == null) { return false; } return m_Data.DeserializeSharedVariables(force); } /// /// Adds the specified logic node. /// /// The node that should be added. public void AddNode(ILogicNode node) { m_Data.AddNode(node); } /// /// Removes the specified logic node. /// /// The node that should be removed. /// True if the node was removed. public bool RemoveNode(ILogicNode node) { return m_Data.RemoveNode(node); } /// /// Adds the specified event node. /// /// The event node that should be added. public void AddNode(IEventNode eventNode) { m_Data.AddNode(eventNode); } /// /// Removes the specified event node. /// /// The event node that should be removed. /// True if the event node was removed. public bool RemoveNode(IEventNode eventNode) { return m_Data.RemoveNode(eventNode); } /// /// Returns the Node of the specified type. /// /// The type of Node that should be retrieved. /// The Node of the specified type (can be null). public ILogicNode GetNode(Type type) { return m_Data.GetNode(type); } /// /// Returns the EventNode of the specified type. /// /// The type of EventNode that should be retrieved. /// The EventNode of the specified type (can be null). If the node is found the index will also be returned. public (IEventNode, ushort) GetEventNode(Type type) { return m_Data.GetEventNode(type); } /// /// Returns the SharedVariable with the specified name. /// /// The name of the SharedVariable that should be retrieved. /// The SharedVariable with the specified name (can be null). public SharedVariable GetVariable(string name) { return m_Data.GetVariable(this, name, SharedVariable.SharingScope.Graph); } /// /// Returns the SharedVariable of the specified name. /// /// The name of the SharedVariable that should be retrieved. /// The SharedVariable with the specified name (can be null). public SharedVariable GetVariable(string name) { return m_Data.GetVariable(this, name, SharedVariable.SharingScope.Graph); } /// /// Sets the value of the SharedVariable. /// /// The type of SharedVarible. /// The name of the SharedVariable. /// The value of the SharedVariable. public void SetVariableValue(string name, T value) { m_Data.SetVariableValue(this, name, value, SharedVariable.SharingScope.Graph); } /// /// Is the node with the specified index enabled? /// /// Is the node a LogicNode? /// The index of the node. /// True if the node with the specified index is enabled. public bool IsNodeEnabled(bool logicNode, int index) { return m_Data.IsNodeEnabled(logicNode, index); } /// /// Is the node with the specified index active? /// /// Is the node a LogicNode? /// The index of the node. /// True if the node with the specified index is active. public bool IsNodeActive(bool logicNode, int index) { return false; // The subtree node itself is never active. } /// /// Copies the graph onto the current graph. /// /// The graph that should be copied. public void Clone(IGraph other) { m_Data = new BehaviorTreeData(); m_Data.EventNodes = other.EventNodes; m_Data.LogicNodes = other.LogicNodes; m_Data.SharedVariables = other.SharedVariables; #if UNITY_EDITOR m_Data.EventNodeProperties = other.EventNodeProperties; m_Data.LogicNodeProperties = other.LogicNodeProperties; m_Data.GroupProperties = other.GroupProperties; #endif m_Data.Serialize(); } /// /// Overrides ToString. /// /// The desired string value. public override string ToString() { return name; } } /// /// Attribute indicating that a ReorderableList should be used for the Subtree array. /// [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public class SubtreeListAttribute : System.Attribute { } } #endif