/// <summary> /// Update the ID of the node /// </summary> /// <param name="graph"></param> static void UpdateChainBehaviorNodeID(ChainGraph graph) { for (int i = 0; i < graph.nodes.Count; i++) { graph.nodes[i].id = i; } }
/// <summary> /// Draw ActorModel GUI /// </summary> /// <param name="graph"></param> private void DrawActorModelGUI(ChainGraph graph) { // Draw Model Object Field GUILayout.BeginHorizontal(); GUILayout.Space(10); EditorGUIUtility.labelWidth = viewRect.width; GUILayout.Label("Model Reference", GUILayout.ExpandWidth(true)); GUILayout.EndHorizontal(); EditorGUIUtility.labelWidth = viewRect.width / 5; EditorGUIUtility.fieldWidth = viewRect.width / 3; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); graph.model = (ActorModel)EditorGUILayout.ObjectField("Model", graph.model, typeof(ActorModel), false); if (GUILayout.Button("New", _buttonOffsetStyle, GUILayout.Width(46))) { //todo create new scriptable object } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); }
/// <summary> /// A static method to load existing graph into Chain Editor /// </summary> public static void LoadGraph() { string graphPath = EditorUtility.OpenFilePanel("Load Graph", cachedPath, "asset"); if (string.IsNullOrWhiteSpace(graphPath)) { return; } int appPathLen = Application.dataPath.Length; string finalPath = graphPath.Substring(appPathLen - 6); ChainGraph graph = AssetDatabase.LoadAssetAtPath(finalPath, typeof(ChainGraph)) as ChainGraph; if (graph != null) { ChainEditorWindow win = EditorWindow.GetWindow <ChainEditorWindow>(); if (win != null) { win.graph = graph; } } else { EditorUtility.DisplayDialog("Node Message", "Unable to load selected graph!", "OK"); } }
/// <summary> /// A method to draw everything in Graph /// </summary> /// <param name="e"></param> /// <param name="graph"></param> void DrawZoomableGraph(Event e, ChainGraph graph) { ChainEditorUtilities.BeginZoomArea(zoom, viewRect); viewRect.size /= zoom; graph.UpdateGraphGUI(e, viewRect, skin); ChainEditorUtilities.EndZoomArea(); }
/// <summary> /// A method to draw the toolbar /// </summary> /// <param name="graph"></param> void DrawStateToolBar(ChainGraph graph) { if (graph.model != null) { DrawHeader(viewTitle + " Graph - " + graph.model.name, zoom); } else { DrawHeader(viewTitle + " Graph", zoom); } }
/// <summary> /// Init the Node /// </summary> /// <param name="parentGraph"></param> public override void InitNode(ChainGraph parentGraph) { output = new NodeOutput(); behavior = parentGraph.model.GetBehavior("Default"); id = 0; priority = 0; outPortSkin = new GUIStyle("Button"); outPortSkin.overflow.top = 10; nodeType = NodeType.RootBehaviorNode; nodeRect = new Rect(10, 10, 100, 100); }
public int behaviorIndex; // the current index /// <summary> /// Init the Node /// </summary> /// <param name="parentGraph"></param> public virtual void InitNode(ChainGraph parentGraph) { output = new NodeOutput(); input = new NodeInput(); inPortSkin = new GUIStyle("Button"); outPortSkin = new GUIStyle("Button"); inPortSkin.overflow.bottom = 10; outPortSkin.overflow.top = 10; nodeType = NodeType.ChainBehaviorNode; nodeRect = new Rect(10, 10, 100, 100); }
public static void UpdateGraphToModel(ChainGraph graph) { if (EditorUtility.DisplayDialog("Confirm Dialogue", "Do you really want to update this graph data to the " + graph.model.name + " ActorModel data?", "Yes", "No")) { graph.model.chainBehaviors.Clear(); for (int i = 0; i < graph.nodes.Count; i++) { graph.model.chainBehaviors.Add(new ChainBehavior(graph.nodes[i].id, graph.nodes[i].behavior, graph.nodes[i].followUps, graph.nodes[i].priority)); } EditorUtility.SetDirty(graph.model); Debug.Log("Saved Chains Successfully"); } }
/// <summary> /// A static method to remove the node from graph's nodes list and clean up /// </summary> /// <param name="graph"></param> /// <param name="deleteNode"></param> static void RemoveNodeAndCleanUp(ChainGraph graph, ChainBehaviorNode deleteNode) { foreach (ChainBehaviorNode n in graph.nodes) { if (n.output.nodes != null) { if (n.output.nodes.Contains(deleteNode)) { n.output.nodes.Remove(deleteNode); } } } graph.nodes.Remove(deleteNode); }
/// <summary> /// A static method to update the followups of the nodes /// </summary> /// <param name="graph"></param> public static void UpdateFollowUps(ChainGraph graph) { foreach (ChainBehaviorNode n in graph.nodes) { if (n.output.nodes != null) { //ReorderByPriority(n); n.followUps.Clear(); for (int i = 0; i < n.output.nodes.Count; i++) { n.followUps.Add(n.output.nodes[i].id); } } } }
/// <summary> /// A virtual method to update the visualization /// </summary> /// <param name="editorRect"></param> /// <param name="percentageRect"></param> /// <param name="e"></param> /// <param name="graph"></param> public virtual void UpdateView(Rect editorRect, Rect percentageRect, Event e, ChainGraph graph) { // set the current graph this.graph = graph; if (skin == null) { GetEditorSkin(); return; } // update viewTitle viewTitle = (graph != null) ? graph.name : "No Graph"; // Update ViewRect viewRect = new Rect(editorRect.x * percentageRect.x, editorRect.y * percentageRect.y, editorRect.width * percentageRect.width, editorRect.height * percentageRect.height); }
/// <summary> /// A static method to delete the node in the graph /// </summary> /// <param name="nodeIndex"></param> /// <param name="graph"></param> public static void DeleteNode(int nodeIndex, ChainGraph graph) { if (graph != null) { if (graph.nodes.Count >= nodeIndex) { ChainBehaviorNode deleteNode = (ChainBehaviorNode)graph.nodes[nodeIndex]; if (deleteNode != null) { RemoveNodeAndCleanUp(graph, deleteNode); UpdateChainBehaviorNodeID(graph); UpdateFollowUps(graph); UnityEngine.Object.DestroyImmediate(deleteNode, true); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } } }
/// <summary> /// A static method to create a new graph into Chain Editor based on a ActorModel /// </summary> /// <param name="model"></param> public static void CreateNewGraph(ActorModel model) { cachedPath = cachedPath == null ? Application.dataPath: cachedPath; string graphPath = EditorUtility.SaveFilePanelInProject("Create Graph", "NewGraph", "", "Please enter a file name to save", cachedPath); if (string.IsNullOrWhiteSpace(graphPath)) { return; } cachedPath = PathUtilities.GetLeafDirectories(graphPath).ToString(); ChainGraph graph = ScriptableObject.CreateInstance <ChainGraph>(); // create a scriptableObject if (graph == null) { EditorUtility.DisplayDialog("Node Message", "Unable to create a new graph", "Ok"); } if (!graphPath.Contains(".asset")) { graphPath += ".asset"; } graph.InitGraph(model); AssetDatabase.CreateAsset(graph, graphPath); // create the asset AssetDatabase.SaveAssets(); // save the asset AssetDatabase.Refresh(); // after saving refresh to update ChainEditorWindow win = EditorWindow.GetWindow <ChainEditorWindow>(); if (win != null) { win.graph = graph; } Vector2 rootNodePos = new Vector2(win._workView.viewRect.width / 2 - 50, win._workView.viewRect.height / 2 + 50); CreateNode(graph, NodeType.RootBehaviorNode, rootNodePos); }
/// <summary> /// A static method to create a node in graph /// </summary> /// <param name="graph"></param> /// <param name="nodeType"></param> /// <param name="pos"></param> public static void CreateNode(ChainGraph graph, NodeType nodeType, Vector2 pos) { if (graph != null) { ChainBehaviorNode node = null; switch (nodeType) { case NodeType.ChainBehaviorNode: node = ScriptableObject.CreateInstance <ChainBehaviorNode>(); node.nodeName = "Chain Behavior"; break; case NodeType.RootBehaviorNode: node = ScriptableObject.CreateInstance <RootBehaviorNode>(); node.nodeName = "Root Behavior"; break; default: break; } if (node != null) { node.InitNode(graph); node.nodeRect.x = pos.x; node.nodeRect.y = pos.y; node.parentGraph = graph; graph.nodes.Add(node); UpdateChainBehaviorNodeID(graph); node.name = node.nodeName; AssetDatabase.AddObjectToAsset(node, graph); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } }
/// <summary> /// Update Property GUI /// </summary> /// <param name="editorRect"> the entire editor window rect </param> /// <param name="percentageRect"> the percentage of this view occupied </param> /// <param name="e"> mouse key event </param> /// <param name="graph"> the graph reference </param> public override void UpdateView(Rect editorRect, Rect percentageRect, Event e, ChainGraph graph) { base.UpdateView(editorRect, percentageRect, e, graph); GUI.Box(viewRect, "", "Box"); DrawHeader(viewTitle + " Property", 1); GUILayout.Space(16); if (graph != null) { GUILayout.BeginArea(viewRect); //DrawActorModelGUI(graph); GUILayout.Space(10); if (graph.model != null) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.BeginVertical(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Add Node", GUILayout.Width(160), GUILayout.Height(30))) { //todo create new scriptable object } if (GUILayout.Button("Delete Node", GUILayout.Width(160), GUILayout.Height(30))) { //todo create new scriptable object } if (GUILayout.Button("Clear Nodes", GUILayout.Width(160), GUILayout.Height(30))) { //todo create new scriptable object } GUILayout.EndVertical(); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.BeginVertical(); if (GUILayout.Button("Load Graph", GUILayout.Height(50))) { // todo load graph from model data } if (GUILayout.Button("Update Graph", GUILayout.Height(50))) { if (EditorUtility.DisplayDialog("Confirm Dialogue", "Do you really want to update this graph data to the " + graph.model.name + " ActorModel data?", "Yes", "No")) { graph.model.chainBehaviors.Clear(); for (int i = 0; i < graph.nodes.Count; i++) { graph.model.chainBehaviors.Add(new ChainBehavior(graph.nodes[i].id, graph.nodes[i].behavior, graph.nodes[i].followUps, graph.nodes[i].priority)); } EditorUtility.SetDirty(graph.model); } } GUILayout.EndVertical(); GUILayout.BeginHorizontal(); _redStyle.fontStyle = FontStyle.Bold; _redStyle.alignment = TextAnchor.MiddleCenter; _pressed = GUILayout.Toggle(_pressed, "Runtime\n\n Update", _redStyle, GUILayout.Width(100), GUILayout.Height(100)); // todo runtime editing GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); GUILayout.Space(100); } GUILayout.EndArea(); } ProcessEvent(e); }
public override void UpdateView(Rect editorRect, Rect percentageRect, Event e, ChainGraph graph) { base.UpdateView(editorRect, percentageRect, e, graph); GUILayout.BeginHorizontal(EditorStyles.toolbar); DrawToolStrip(); GUILayout.EndHorizontal(); }
/// <summary> /// A method to update the the view aspect of the /// </summary> /// <param name="editorRect"></param> /// <param name="percentageRect"></param> /// <param name="e"></param> /// <param name="graph"></param> public override void UpdateView(Rect editorRect, Rect percentageRect, Event e, ChainGraph graph) { base.UpdateView(editorRect, percentageRect, e, graph); // Draw the Node workspace background GUI.Box(viewRect, "", skin.GetStyle("ViewBG")); ChainEditorUtilities.DrawGrid(viewRect, 50f, 0.25f, Color.white); ChainEditorUtilities.DrawGrid(viewRect, 10f, 0.15f, Color.white); if (graph != null) { DrawZoomableGraph(e, graph); GUILayout.BeginArea(new Rect(viewRect.x, viewRect.y, viewRect.width * zoom, viewRect.height)); DrawStateToolBar(graph); GUILayout.EndArea(); } // Update mouse and keyboard event ProcessEvent(e); }