private void LoadData(string filePath = null)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                filePath = EditorUtility.OpenFilePanel(
                    "Select BehaviorTree Graph data file",
                    Application.dataPath,
                    "asset"
                    );
            }

            if (!string.IsNullOrEmpty(filePath))
            {
                filePath = filePath.Replace(Application.dataPath, "Assets");
                BTGraphData data = AssetDatabase.LoadAssetAtPath <BTGraphData>(filePath);

                if (data != null)
                {
                    ResetGraphView();

                    EditorPrefs.SetString(EditorPreference_LastLoadedBehaviorTreeGraph, filePath);
                    lblFilePath.text = filePath;

                    foreach (BTGraphNodeData nodeData in data.nodes)
                    {
                        BTGraphNode restoredNode = graphView.CreateBTNode(nodeData);
                        restoredNode.Id       = nodeData.id;
                        restoredNode.title    = nodeData.title;
                        restoredNode.NodeType = nodeData.nodeType;
                        graphView.AddElement(restoredNode);
                    }

                    foreach (BTGraphEdgeData edgeData in data.edges)
                    {
                        BTGraphNode fromNode = edgeData.fromId == null ? null : (BTGraphNode)graphView.nodes.ToList().Find((n) => ((BTGraphNode)n).Id == edgeData.fromId);
                        BTGraphNode toNode   = edgeData.toId == null ? null : (BTGraphNode)graphView.nodes.ToList().Find((n) => ((BTGraphNode)n).Id == edgeData.toId);

                        if (fromNode != null && toNode != null)
                        {
                            Edge restoredEdge = new Edge()
                            {
                                output = (Port)fromNode.outputContainer.ElementAt(0),
                                input  = (Port)toNode.inputContainer.ElementAt(0)
                            };
                            restoredEdge.input.Connect(restoredEdge);
                            restoredEdge.output.Connect(restoredEdge);

                            graphView.AddElement(restoredEdge);
                        }
                    }
                }
                else
                {
                    EditorPrefs.SetString(EditorPreference_LastLoadedBehaviorTreeGraph, "");
                }
            }
        }
        private void SaveData(string filePath = null)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                filePath = EditorUtility.SaveFilePanel(
                    "Save BehaviorTree Graph data file",
                    Application.dataPath,
                    "New BehaviorTree Graph",
                    "asset"
                    );
            }

            if (!string.IsNullOrEmpty(filePath))
            {
                BTGraphData data = ScriptableObject.CreateInstance <BTGraphData>();
                foreach (Edge edge in graphView.edges.ToList())
                {
                    BTGraphNode outputNode = edge.output.node as BTGraphNode;
                    BTGraphNode inputNode  = edge.input.node as BTGraphNode;

                    data.edges.Add(new BTGraphEdgeData()
                    {
                        fromId = outputNode.Id,
                        toId   = inputNode.Id
                    });
                }

                List <Node> nodes = graphView.nodes.ToList();
                for (int i = 0; i < nodes.Count; ++i)
                {
                    BTGraphNode node = (BTGraphNode)nodes[i];

                    data.nodes.Add(new BTGraphNodeData()
                    {
                        id         = node.Id,
                        isRootNode = node.IsRootNode,
                        title      = node.title,
                        nodeType   = node.NodeType,
                        position   = node.GetPosition().position
                    });

                    if (node.IsRootNode)
                    {
                        data.rootNode = data.nodes[data.nodes.Count - 1];
                    }
                }

                filePath = filePath.Replace(Application.dataPath, "Assets");
                AssetDatabase.CreateAsset(data, filePath);
                AssetDatabase.SaveAssets();

                EditorPrefs.SetString(EditorPreference_LastLoadedBehaviorTreeGraph, filePath);
                lblFilePath.text = filePath;
            }
        }