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; }
//-------------------------------------- // Event listeners //-------------------------------------- /* -- Creating Nodes -- */ public void CreateNewOption(UISpeechNode speechUI) { // Create new option, the argument speech is the options parent EditableOptionNode newOption = new EditableOptionNode(); newOption.ID = CurrentAsset.CurrentIDCounter++; // Give the speech it's default values newOption.TMPFont = CurrentAsset.DefaultFont; // Add the option to the speechs' list of options speechUI.SpeechNode.AddOption(newOption); // The option doesn't point to an speech yet newOption.Speech = null; // Create a new UI object to represent the new option UIOptionNode ui = new UIOptionNode(newOption, Vector2.zero); uiNodes.Add(ui); // Set the input state appropriately m_inputState = eInputState.PlacingOption; m_currentPlacingNode = ui; }
//-------------------------------------- // Input //-------------------------------------- private void ProcessInput() { Event e = Event.current; switch (m_inputState) { case eInputState.Regular: bool inPanel = panelRect.Contains(e.mousePosition) || e.mousePosition.y < TOOLBAR_HEIGHT; ProcessNodeEvents(e, inPanel); ProcessEvents(e); break; case eInputState.draggingPanel: panelWidth = (position.width - e.mousePosition.x); if (panelWidth < 100) { panelWidth = 100; } if (e.type == UnityEngine.EventType.MouseUp && e.button == 0) { m_inputState = eInputState.Regular; e.Use(); } Repaint(); break; case eInputState.PlacingOption: m_currentPlacingNode.SetPosition(e.mousePosition); // Left click if (e.type == UnityEngine.EventType.MouseDown && e.button == 0) { // Place the option SelectNode(m_currentPlacingNode, true); m_inputState = eInputState.Regular; Repaint(); e.Use(); } break; case eInputState.PlacingSpeech: m_currentPlacingNode.SetPosition(e.mousePosition); // Left click if (e.type == UnityEngine.EventType.MouseDown && e.button == 0) { // Place the option SelectNode(m_currentPlacingNode, true); m_inputState = eInputState.Regular; Repaint(); e.Use(); } break; case eInputState.ConnectingNode: // Click. if (e.type == UnityEngine.EventType.MouseDown && e.button == 0) { // If we're connecting a Speech node if (m_currentConnectingNode is UISpeechNode) { for (int i = 0; i < uiNodes.Count; i++) { if (uiNodes[i] == m_currentConnectingNode) { continue; } if (uiNodes[i].rect.Contains(e.mousePosition)) { if (uiNodes[i] is UISpeechNode) { UISpeechNode connecting = m_currentConnectingNode as UISpeechNode; UISpeechNode toBeChild = uiNodes[i] as UISpeechNode; // If a relationship between these speechs already exists, swap it // around, as a 2way speech<->speech relationship cannot exist. if (connecting.SpeechNode.parents.Contains(toBeChild.SpeechNode)) { // Remove the relationship connecting.SpeechNode.parents.Remove(toBeChild.SpeechNode); toBeChild.SpeechNode.Speech = null; } (m_currentConnectingNode as UISpeechNode).SpeechNode.SetSpeech((uiNodes[i] as UISpeechNode).SpeechNode); } else if (uiNodes[i] is UIOptionNode) { (m_currentConnectingNode as UISpeechNode).SpeechNode.AddOption((uiNodes[i] as UIOptionNode).OptionNode); } m_inputState = eInputState.Regular; e.Use(); break; } } } // Else if we're connecting an Option node else if (m_currentConnectingNode is UIOptionNode) { for (int i = 0; i < uiNodes.Count; i++) { if (uiNodes[i] == m_currentConnectingNode) { continue; } if (uiNodes[i].rect.Contains(e.mousePosition)) { if (uiNodes[i] is UISpeechNode) { (m_currentConnectingNode as UIOptionNode).OptionNode.SetSpeech((uiNodes[i] as UISpeechNode).SpeechNode); m_inputState = eInputState.Regular; e.Use(); break; } } } } } // Esc if (e.type == UnityEngine.EventType.KeyDown && e.keyCode == KeyCode.Escape) { m_inputState = eInputState.Regular; } break; } }
//-------------------------------------- // 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 }