private SpeechNode CreateSpeechNode(EditableSpeechNode editableNode) { SpeechNode speech = new SpeechNode(); speech.Name = editableNode.Name; speech.Text = editableNode.Text; speech.AutomaticallyAdvance = editableNode.AdvanceDialogueAutomatically; speech.AutoAdvanceShouldDisplayOption = editableNode.AutoAdvanceShouldDisplayOption; speech.TimeUntilAdvance = editableNode.TimeUntilAdvance; speech.TMPFont = editableNode.TMPFont; speech.Icon = editableNode.Icon; speech.Audio = editableNode.Audio; speech.Volume = editableNode.Volume; CopyParamActions(editableNode, speech); NodeEventHolder holder = this.GetNodeData(editableNode.ID); if (holder != null) { speech.Event = holder.Event; } return(speech); }
public void CreateNewSpeech(UINode node) { // Create new speech, the argument option is the speechs parent EditableSpeechNode newSpeech = new EditableSpeechNode(); newSpeech.ID = CurrentAsset.CurrentIDCounter++; // Give the speech it's default values newSpeech.Name = CurrentAsset.DefaultName; newSpeech.Icon = CurrentAsset.DefaultSprite; newSpeech.TMPFont = CurrentAsset.DefaultFont; // Set this new speech as the options child if (node is UIOptionNode) { (node as UIOptionNode).OptionNode.SetSpeech(newSpeech); } else if (node is UISpeechNode) { (node as UISpeechNode).SpeechNode.SetSpeech(newSpeech); } // This new speech doesn't have any children yet newSpeech.Options = null; // Create a new UI object to represent the new speech UISpeechNode ui = new UISpeechNode(newSpeech, Vector2.zero); uiNodes.Add(ui); // Set the input state appropriately m_inputState = eInputState.PlacingSpeech; m_currentPlacingNode = ui; }
public void SetSpeech(EditableSpeechNode newSpeech) { // Remove myself as a parent from the speech I was previously pointing to if (this.Speech != null) { this.Speech.parents.Remove(this); } // Remove any options I may have if (Options != null) { for (int i = 0; i < Options.Count; i++) { // I am no longer the parents of these options Options[i].parents.Remove(this); } Options.Clear(); } this.Speech = newSpeech; if (!newSpeech.parents.Contains(this)) { newSpeech.parents.Add(this); } }
// ------------------------------ public void AddOption(EditableOptionNode newOption) { if (Options == null) { Options = new List <EditableOptionNode>(); } if (Options.Contains(newOption)) { return; } // Delete the speech I point to, if any if (this.Speech != null) { this.Speech.parents.Remove(this); } this.Speech = null; // Setup option connection if (!newOption.parents.Contains(this)) { newOption.parents.Add(this); } Options.Add(newOption); }
public void SetSpeech(EditableSpeechNode newSpeech) { // Remove myself as a parent from the speech I was previously pointing to if (this.Speech != null) { this.Speech.parents.Remove(this); } this.Speech = newSpeech; if (!newSpeech.parents.Contains(this)) { newSpeech.parents.Add(this); } }
public void AddSpeech(EditableSpeechNode newSpeech) { // Remove any option connections I may have if (this.Connections.Count > 0 && this.Connections[0] is EditableOptionConnection) { // I am no longer a parent of these speechs' for (int i = 0; i < Connections.Count; i++) { (Connections[0] as EditableOptionConnection).Option.parents.Remove(this); } Connections.Clear(); } // Connection to this speech already exists if (Connections.Count > 0 && Connections[0] is EditableSpeechConnection) { for (int i = 0; i < Connections.Count; i++) { if ((Connections[0] as EditableSpeechConnection).Speech == newSpeech) { return; } } } // If a relationship the other-way-around between these speechs already exists, swap it. // A 2way speech<->speech relationship cannot exist. if (this.parents.Contains(newSpeech)) { this.parents.Remove(newSpeech); newSpeech.DeleteConnectionChild(this); } // Setup option connection this.Connections.Add(new EditableSpeechConnection(newSpeech)); if (!newSpeech.parents.Contains(this)) { newSpeech.parents.Add(this); } }
public void DeleteConnectionChild(EditableConversationNode node) { if (Connections.Count == 0) { return; } if (node.NodeType == eNodeType.Speech && Connections[0] is EditableSpeechConnection) { EditableSpeechNode toRemove = node as EditableSpeechNode; for (int i = 0; i < Connections.Count; i++) { EditableSpeechConnection con = Connections[i] as EditableSpeechConnection; if (con.Speech == toRemove) { Connections.RemoveAt(i); return; } } } else if (node is EditableOptionNode && Connections[0] is EditableOptionConnection) { EditableOptionNode toRemove = node as EditableOptionNode; for (int i = 0; i < Connections.Count; i++) { EditableOptionConnection con = Connections[i] as EditableOptionConnection; if (con.Option == toRemove) { Connections.RemoveAt(i); return; } } } }
private void ReconstructTree(EditableConversation ec, Conversation conversation, Dictionary <int, SpeechNode> dialogues, Dictionary <int, OptionNode> options) { // Speech nodes List <EditableSpeechNode> editableSpeechNodes = ec.SpeechNodes; for (int i = 0; i < editableSpeechNodes.Count; i++) { EditableSpeechNode editableNode = editableSpeechNodes[i]; SpeechNode speechNode = dialogues[editableNode.ID]; // Connections List <EditableConnection> editableConnections = editableNode.Connections; for (int j = 0; j < editableConnections.Count; j++) { int childID = editableConnections[j].NodeUID; // Construct node->Speech if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Speech) { SpeechConnection connection = new SpeechConnection(dialogues[childID]); CopyConnectionConditions(editableConnections[j], connection); speechNode.Connections.Add(connection); } // Construct node->Option else if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Option) { OptionConnection connection = new OptionConnection(options[childID]); CopyConnectionConditions(editableConnections[j], connection); speechNode.Connections.Add(connection); } } // Root? if (editableNode.EditorInfo.isRoot) { conversation.Root = dialogues[editableNode.ID]; } } // Option nodes List <EditableOptionNode> editableOptionNodes = ec.Options; for (int i = 0; i < editableOptionNodes.Count; i++) { EditableOptionNode editableNode = editableOptionNodes[i]; OptionNode optionNode = options[editableNode.ID]; // Connections List <EditableConnection> editableConnections = editableNode.Connections; for (int j = 0; j < editableConnections.Count; j++) { int childID = editableConnections[j].NodeUID; // Construct node->Speech if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Speech) { SpeechConnection connection = new SpeechConnection(dialogues[childID]); CopyConnectionConditions(editableConnections[j], connection); optionNode.Connections.Add(connection); } } } }
private void ReconstructEditableConversation(EditableConversation conversation) { if (conversation == null) { conversation = new EditableConversation(); } // Get a list of every node in the conversation List <EditableConversationNode> allNodes = new List <EditableConversationNode>(); for (int i = 0; i < conversation.SpeechNodes.Count; i++) { allNodes.Add(conversation.SpeechNodes[i]); } for (int i = 0; i < conversation.Options.Count; i++) { allNodes.Add(conversation.Options[i]); } // For every node: // Find the children and parents by UID for (int i = 0; i < allNodes.Count; i++) { // New parents list allNodes[i].parents = new List <EditableConversationNode>(); // Get parents by UIDs //----------------------------------------------------------------------------- // UPDATE: This behaviour has now been removed. Later in this function, // the child->parent connections are constructed by using the // parent->child connections. Having both of these behaviours run // results in each parent being in the "parents" list twice. // // for (int j = 0; j < allNodes[i].parentUIDs.Count; j++) // { // allNodes[i].parents.Add(conversation.GetNodeByUID(allNodes[i].parentUIDs[j])); // } //----------------------------------------------------------------------------- // Construct the parent->child connections // // V1.03 if (conversation.SaveVersion <= (int)eSaveVersion.V1_03) { // Construct Connections from the OptionUIDs and SpeechUIDs (which are now deprecated) // This supports upgrading from V1.03 + allNodes[i].Connections = new List <EditableConnection>(); allNodes[i].ParamActions = new List <EditableSetParamAction>(); if (allNodes[i].NodeType == EditableConversationNode.eNodeType.Speech) { EditableSpeechNode thisSpeech = allNodes[i] as EditableSpeechNode; // Speech options int count = thisSpeech.OptionUIDs.Count; for (int j = 0; j < count; j++) { int optionUID = thisSpeech.OptionUIDs[j]; EditableOptionNode option = conversation.GetOptionByUID(optionUID); thisSpeech.Connections.Add(new EditableOptionConnection(option)); } // Speech following speech { int speechUID = thisSpeech.SpeechUID; EditableSpeechNode speech = conversation.GetSpeechByUID(speechUID); if (speech != null) { thisSpeech.Connections.Add(new EditableSpeechConnection(speech)); } } } else if (allNodes[i] is EditableOptionNode) { int speechUID = (allNodes[i] as EditableOptionNode).SpeechUID; EditableSpeechNode speech = conversation.GetSpeechByUID(speechUID); if (speech != null) { allNodes[i].Connections.Add(new EditableSpeechConnection(speech)); } } } // // V1.10 + else { // For each node.. Reconstruct the connections for (int j = 0; j < allNodes[i].Connections.Count; j++) { if (allNodes[i].Connections[j] is EditableSpeechConnection) { EditableSpeechNode speech = conversation.GetSpeechByUID(allNodes[i].Connections[j].NodeUID); (allNodes[i].Connections[j] as EditableSpeechConnection).Speech = speech; } else if (allNodes[i].Connections[j] is EditableOptionConnection) { EditableOptionNode option = conversation.GetOptionByUID(allNodes[i].Connections[j].NodeUID); (allNodes[i].Connections[j] as EditableOptionConnection).Option = option; } } } } // For every node: // Tell any of the nodes children that the node is the childs parent for (int i = 0; i < allNodes.Count; i++) { EditableConversationNode thisNode = allNodes[i]; for (int j = 0; j < thisNode.Connections.Count; j++) { if (thisNode.Connections[j].ConnectionType == EditableConnection.eConnectiontype.Speech) { (thisNode.Connections[j] as EditableSpeechConnection).Speech.parents.Add(thisNode); } else if (thisNode.Connections[j].ConnectionType == EditableConnection.eConnectiontype.Option) { (thisNode.Connections[j] as EditableOptionConnection).Option.parents.Add(thisNode); } } } }
private void DrawPanel() { panelRect = new Rect(position.width - panelWidth, TOOLBAR_HEIGHT, panelWidth, position.height - TOOLBAR_HEIGHT); if (panelStyle.normal.background == null) { InitGUIStyles(); } GUILayout.BeginArea(panelRect, panelStyle); GUILayout.BeginVertical(); panelVerticalScroll = GUILayout.BeginScrollView(panelVerticalScroll); GUI.SetNextControlName("CONTROL_TITLE"); GUILayout.Space(10); if (CurrentlySelectedNode != null) { bool differentNodeSelected = (m_cachedSelectedNode != CurrentlySelectedNode); m_cachedSelectedNode = CurrentlySelectedNode; if (differentNodeSelected) { GUI.FocusControl(CONTROL_NAME); } if (CurrentlySelectedNode is UISpeechNode) { EditableSpeechNode node = (CurrentlySelectedNode.Info as EditableSpeechNode); GUILayout.Label("[" + node.ID + "] NPC Dialogue Node.", panelTitleStyle); EditorGUILayout.Space(); GUILayout.Label("Character Name", EditorStyles.boldLabel); GUI.SetNextControlName(CONTROL_NAME); node.Name = GUILayout.TextField(node.Name); EditorGUILayout.Space(); GUILayout.Label("Dialogue", EditorStyles.boldLabel); node.Text = GUILayout.TextArea(node.Text); EditorGUILayout.Space(); // Advance if (node.Speech != null || node.Options == null || node.Options.Count == 0) { GUILayout.Label("Auto-Advance options", EditorStyles.boldLabel); node.AdvanceDialogueAutomatically = EditorGUILayout.Toggle("Automatically Advance", node.AdvanceDialogueAutomatically); if (node.AdvanceDialogueAutomatically) { node.AutoAdvanceShouldDisplayOption = EditorGUILayout.Toggle("Display continue option", node.AutoAdvanceShouldDisplayOption); node.TimeUntilAdvance = EditorGUILayout.FloatField("Dialogue Time", node.TimeUntilAdvance); if (node.TimeUntilAdvance < 0f) { node.TimeUntilAdvance = 0f; } } EditorGUILayout.Space(); } GUILayout.Label("Icon", EditorStyles.boldLabel); node.Icon = (Sprite)EditorGUILayout.ObjectField(node.Icon, typeof(Sprite), false, GUILayout.ExpandWidth(true)); EditorGUILayout.Space(); GUILayout.Label("Audio Options", EditorStyles.boldLabel); GUILayout.Label("Audio"); node.Audio = (AudioClip)EditorGUILayout.ObjectField(node.Audio, typeof(AudioClip), false); GUILayout.Label("Audio Volume"); node.Volume = EditorGUILayout.Slider(node.Volume, 0, 1); EditorGUILayout.Space(); GUILayout.Label("TMP Font", EditorStyles.boldLabel); node.TMPFont = (TMPro.TMP_FontAsset)EditorGUILayout.ObjectField(node.TMPFont, typeof(TMPro.TMP_FontAsset), false); EditorGUILayout.Space(); // Events { NodeEventHolder NodeEvent = CurrentAsset.GetNodeData(node.ID); if (differentNodeSelected) { CurrentAsset.Event = NodeEvent.Event; } if (NodeEvent != null && NodeEvent.Event != null) { // Load the object and property of the node SerializedObject o = new SerializedObject(NodeEvent); SerializedProperty p = o.FindProperty("Event"); // Load the dummy event SerializedObject o2 = new SerializedObject(CurrentAsset); SerializedProperty p2 = o2.FindProperty("Event"); // Draw dummy event GUILayout.Label("Events:", EditorStyles.boldLabel); EditorGUILayout.PropertyField(p2); // Apply changes to dummy o2.ApplyModifiedProperties(); // Copy dummy changes onto the nodes event p = p2; o.ApplyModifiedProperties(); } } } else if (CurrentlySelectedNode is UIOptionNode) { EditableOptionNode node = (CurrentlySelectedNode.Info as EditableOptionNode); GUILayout.Label("[" + node.ID + "] Option Node.", panelTitleStyle); GUILayout.Label("Option text:", EditorStyles.boldLabel); node.Text = GUILayout.TextArea(node.Text); GUILayout.Label("TMP Font", EditorStyles.boldLabel); node.TMPFont = (TMPro.TMP_FontAsset)EditorGUILayout.ObjectField(node.TMPFont, typeof(TMPro.TMP_FontAsset), false); } } else { GUILayout.Label("Conversation options.", panelTitleStyle); GUILayout.Label("Default name:", EditorStyles.boldLabel); CurrentAsset.DefaultName = EditorGUILayout.TextField(CurrentAsset.DefaultName); GUILayout.Label("Default Icon:", EditorStyles.boldLabel); CurrentAsset.DefaultSprite = (Sprite)EditorGUILayout.ObjectField(CurrentAsset.DefaultSprite, typeof(Sprite), false); GUILayout.Label("Default font:", EditorStyles.boldLabel); CurrentAsset.DefaultFont = (TMPro.TMP_FontAsset)EditorGUILayout.ObjectField(CurrentAsset.DefaultFont, typeof(TMPro.TMP_FontAsset), false); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.EndArea(); }
//-------------------------------------- // Load New Asset //-------------------------------------- public void LoadNewAsset(NPCConversation asset) { CurrentAsset = asset; Log("Loading new asset: " + CurrentAsset.name); // Clear all current UI Nodes uiNodes.Clear(); // Deseralize the asset and get the conversation root EditableConversation conversation = CurrentAsset.DeserializeForEditor(); if (conversation == null) { conversation = new EditableConversation(); } ConversationRoot = conversation.GetRootNode(); // If it's null, create a root if (ConversationRoot == null) { ConversationRoot = new EditableSpeechNode(); ConversationRoot.EditorInfo.xPos = (Screen.width / 2) - (UISpeechNode.Width / 2); ConversationRoot.EditorInfo.yPos = 0; ConversationRoot.EditorInfo.isRoot = true; conversation.SpeechNodes.Add(ConversationRoot); } // Get a list of every node in the conversation List <EditableConversationNode> allNodes = new List <EditableConversationNode>(); for (int i = 0; i < conversation.SpeechNodes.Count; i++) { allNodes.Add(conversation.SpeechNodes[i]); } for (int i = 0; i < conversation.Options.Count; i++) { allNodes.Add(conversation.Options[i]); } // For every node: // Find the children and parents by UID for (int i = 0; i < allNodes.Count; i++) { // Remove duplicate parent UIDs HashSet <int> noDupes = new HashSet <int>(allNodes[i].parentUIDs); allNodes[i].parentUIDs.Clear(); foreach (int j in noDupes) { allNodes[i].parentUIDs.Add(j); } allNodes[i].parents = new List <EditableConversationNode>(); for (int j = 0; j < allNodes[i].parentUIDs.Count; j++) { allNodes[i].parents.Add(conversation.GetNodeByUID(allNodes[i].parentUIDs[j])); } if (allNodes[i] is EditableSpeechNode) { // Speech options int count = (allNodes[i] as EditableSpeechNode).OptionUIDs.Count; (allNodes[i] as EditableSpeechNode).Options = new List <EditableOptionNode>(); for (int j = 0; j < count; j++) { (allNodes[i] as EditableSpeechNode).Options.Add( conversation.GetOptionByUID((allNodes[i] as EditableSpeechNode).OptionUIDs[j])); } // Speech following speech (allNodes[i] as EditableSpeechNode).Speech = conversation. GetSpeechByUID((allNodes[i] as EditableSpeechNode).SpeechUID); } else if (allNodes[i] is EditableOptionNode) { (allNodes[i] as EditableOptionNode).Speech = conversation.GetSpeechByUID((allNodes[i] as EditableOptionNode).SpeechUID); } } // For every node: // 1: Create a corresponding UI Node to represent it, and add it to the list // 2: Tell any of the nodes children that the node is the childs parent for (int i = 0; i < allNodes.Count; i++) { EditableConversationNode node = allNodes[i]; if (node is EditableSpeechNode) { // 1 UISpeechNode uiNode = new UISpeechNode(node, new Vector2(node.EditorInfo.xPos, node.EditorInfo.yPos)); uiNodes.Add(uiNode); // 2 EditableSpeechNode speech = node as EditableSpeechNode; if (speech.Options != null) { for (int j = 0; j < speech.Options.Count; j++) { speech.Options[j].parents.Add(speech); } } if (speech.Speech != null) { speech.Speech.parents.Add(speech); } } else { // 1 UIOptionNode uiNode = new UIOptionNode(node, new Vector2(node.EditorInfo.xPos, node.EditorInfo.yPos)); uiNodes.Add(uiNode); // 2 EditableOptionNode option = node as EditableOptionNode; if (option.Speech != null) { option.Speech.parents.Add(option); } } } Recenter(); Repaint(); #if UNITY_EDITOR UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene()); #endif }
// ------------------------------ public void AddSpeech(EditableSpeechNode newSpeech) { // Add new speech connection this.Connections.Add(new EditableSpeechConnection(newSpeech)); newSpeech.parents.Add(this); }
public EditableSpeechConnection(EditableSpeechNode node) : base() { Speech = node; NodeUID = node.ID; }