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 }
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 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); } } } }
public EditableOptionConnection(EditableOptionNode node) : base() { Option = node; NodeUID = node.ID; }