/// <summary> /// Renders the currently selected step /// </summary> /// <param name="rStep"></param> private bool DrawActionDetailItem(NodeLinkAction rItem) { bool lIsDirty = false; if (rItem == null) { EditorGUILayout.LabelField("NULL"); return(false); } string lDescription = BaseDescriptionAttribute.GetDescription(rItem.GetType()); if (lDescription.Length > 0) { NodeEditorStyle.DrawInspectorDescription(lDescription, MessageType.None); } // Render out the action specific inspectors bool lIsActionDirty = rItem.OnInspectorGUI(mTarget); if (lIsActionDirty) { lIsDirty = true; } if (lIsDirty) { EditorUtility.SetDirty(rItem); } return(lIsDirty); }
/// <summary> /// Allows us to add to a list /// </summary> /// <param name="rList"></param> private void OnActionListItemAdd(ReorderableList rList) { if (mActionIndex >= mActionTypes.Count) { return; } NodeLinkAction lItem = ScriptableObject.CreateInstance(mActionTypes[mActionIndex]) as NodeLinkAction; lItem._Link = mTarget; mTarget.Actions.Add(lItem); mActionList.index = mTarget.Actions.Count - 1; OnActionListItemSelect(rList); // Add the action as an asset. However, we have to name it this: // http://answers.unity3d.com/questions/1164341/can-a-scriptableobject-contain-a-list-of-scriptabl.html lItem.name = "zzzz NodeListAction " + mTarget.Actions.Count.ToString("D4"); lItem.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(lItem, mTarget.StartNode.Canvas.RootAsset); EditorUtility.SetDirty(lItem); EditorUtility.SetDirty(mTarget); mTarget.StartNode.Canvas.SetDirty(); mIsDirty = true; }
/// <summary> /// Allows us to stop before removing the item /// </summary> /// <param name="rList"></param> private void OnActionListItemRemove(ReorderableList rList) { if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to delete the item?", "Yes", "No")) { int rIndex = rList.index; rList.index--; NodeLinkAction lAction = mTarget.Actions[rIndex]; lAction._Link = null; mTarget.Actions.RemoveAt(rIndex); OnActionListItemSelect(rList); // Remove the asset that represents the action UnityEngine.Object.DestroyImmediate(lAction, true); mIsDirty = true; } }
/// <summary> /// Allows us to draw each item in the list /// </summary> /// <param name="rRect"></param> /// <param name="rIndex"></param> /// <param name="rIsActive"></param> /// <param name="rIsFocused"></param> private void DrawActionListItem(Rect rRect, int rIndex, bool rIsActive, bool rIsFocused) { if (rIndex < mTarget.Actions.Count) { NodeLinkAction lItem = mTarget.Actions[rIndex]; if (lItem == null) { EditorGUI.LabelField(rRect, "NULL"); return; } rRect.y += 2; string lName = lItem.Name; if (lName.Length == 0) { lName = BaseNameAttribute.GetName(lItem.GetType()); } Rect lNameRect = new Rect(rRect.x, rRect.y, rRect.width, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(lNameRect, lName); } }
/// <summary> /// Activate the node contents and flag the node as working /// </summary> /// <param name="rNode">Node to activate</param> public void ActivateNode(Node rNode, object rData = null) { Node lNode = rNode; // If the node isn't immediate, we'll create an instance of it so we can // loop over and over as needed. This instance is a shallow copy. So, we're not // creating new instances of children. //if (!lNode.IsImmediate) { // Create an instance of the node. lNode = ScriptableObject.Instantiate <Node>(rNode); lNode.ID = rNode.ID; // Tell all the node links that this is the start node. We shallow copy them // as well so the StartNode can be different each instance for (int i = 0; i < lNode.Links.Count; i++) { NodeLink lLink = ScriptableObject.Instantiate <NodeLink>(lNode.Links[i]); lLink.StartNode = lNode; // Creates instances for each of the actions if (lLink.Actions != null && lLink.Actions.Count > 0) { for (int j = 0; j < lLink.Actions.Count; j++) { NodeLinkAction lLinkAction = ScriptableObject.Instantiate <NodeLinkAction>(lLink.Actions[j]); lLinkAction._Link = lLink; lLink.Actions[j] = lLinkAction; } } lNode.Links[i] = lLink; } // We do want a deep copy of the content. lNode.Content = ScriptableObjectPool.DeepCopy(lNode.Content, true); if (ShowDebug) { Utilities.Debug.Log.FileWrite(string.Format("Spell[{0}].ActivateNode() - Instance created for", Name, lNode.Content.GetType().Name)); } } // If we're dealing with a spell action, activate SpellAction lAction = lNode.Content as SpellAction; if (lAction != null) { lNode.State = EnumNodeState.WORKING; lAction.Spell = this; lAction.Node = lNode; lAction.Activate(0, rData); if (ShowDebug) { Utilities.Debug.Log.FileWrite(string.Format("Spell[{0}].ActivateNode() - Activated: {1}", Name, lAction.GetType().Name)); } // If the action takes time, add it to your queue if (lNode.State == EnumNodeState.WORKING) { if (!mActiveNodes.Contains(lNode)) { mActiveNodes.Add(lNode); if (ShowDebug) { Utilities.Debug.Log.FileWrite(string.Format("Spell[{0}].ActivateNode() - Added to active nodes: {1}", Name, lAction.GetType().Name)); } } } // if it's an instant action, we want to move to the next node else { if (ShowDebug) { Utilities.Debug.Log.FileWrite(string.Format("Spell[{0}].ActivateNode() - Testing links: {1}", Name, lAction.GetType().Name)); } // Process the node links to see if they should be activated for (int i = 0; i < lNode.Links.Count; i++) { bool lActivate = lNode.Links[i].TestActivate(); if (lActivate) { ActivateLink(lNode.Links[i], lNode.Data); } } } } // We may still have links that need to process else { lNode.State = EnumNodeState.SUCCEEDED; if (ShowDebug) { Utilities.Debug.Log.FileWrite(string.Format("Spell[{0}].ActivateNode() - No action, testing links: {1}", Name, lAction.GetType().Name)); } // Process the node links to see if they should be activated for (int i = 0; i < lNode.Links.Count; i++) { bool lActivate = lNode.Links[i].TestActivate(); if (lActivate) { ActivateLink(lNode.Links[i], lNode.Data); } } } }