//-------------------------------------- // Construct User-Facing Conversation Object and Nodes //-------------------------------------- private Conversation ConstructConversationObject(EditableConversation ec) { // Create a conversation object Conversation conversation = new Conversation(); // Construct the parameters CreateParameters(ec, conversation); // Create a dictionary to store our created nodes by UID Dictionary <int, SpeechNode> speechByID = new Dictionary <int, SpeechNode>(); Dictionary <int, OptionNode> optionsByID = new Dictionary <int, OptionNode>(); // Create a Dialogue and Option node for each in the conversation // Put them in the dictionary for (int i = 0; i < ec.SpeechNodes.Count; i++) { SpeechNode node = CreateSpeechNode(ec.SpeechNodes[i]); speechByID.Add(ec.SpeechNodes[i].ID, node); } for (int i = 0; i < ec.Options.Count; i++) { OptionNode node = CreateOptionNode(ec.Options[i]); optionsByID.Add(ec.Options[i].ID, node); } // Now that we have every node in the dictionary, reconstruct the tree // And also look for the root ReconstructTree(ec, conversation, speechByID, optionsByID); return(conversation); }
//-------------------------------------- // Serialize and Deserialize //-------------------------------------- public void Serialize(EditableConversation conversation) { saveVersion = CurrentVersion; conversation.Parameters = this.ParameterList; json = Jsonify(conversation); }
public EditableConversation DeserializeForEditor() { // Dejsonify EditableConversation conversation = Dejsonify(); if (conversation != null) { // Deserialize the indivudual nodes { if (conversation.SpeechNodes != null) { for (int i = 0; i < conversation.SpeechNodes.Count; i++) { conversation.SpeechNodes[i].Deserialize(this); } } if (conversation.Options != null) { for (int i = 0; i < conversation.Options.Count; i++) { conversation.Options[i].Deserialize(this); } } } } // Clear our dummy event Event = new UnityEngine.Events.UnityEvent(); return(conversation); }
public Conversation Deserialize() { // Deserialize an editor-version (containing all info) that // we will use to construct the user-facing Conversation data structure. EditableConversation ec = this.DeserializeForEditor(); return(ConstructConversationObject(ec)); }
// Start is called before the first frame update // Testing out possibility of automatically parsing dialogue // TODO define structure for dialogue and parse into this script private void OnValidate() { DialogueEditor.EditableConversation ec = nPCConversation.DeserializeForEditor(); for (int i = 0; i < ec.SpeechNodes.Count; i++) { ec.SpeechNodes[i].Text = i + " success!"; } nPCConversation.Serialize(ec); }
private void Save(bool manual = false) { if (CurrentAsset != null) { EditableConversation conversation = new EditableConversation(); // Prepare each node for serialization for (int i = 0; i < uiNodes.Count; i++) { uiNodes[i].Info.PrepareForSerialization(CurrentAsset); } // Now that each node has been prepared for serialization: // - Register the UIDs of their parents/children // - Add it to the conversation for (int i = 0; i < uiNodes.Count; i++) { uiNodes[i].Info.RegisterUIDs(); if (uiNodes[i] is UISpeechNode) { conversation.SpeechNodes.Add((uiNodes[i] as UISpeechNode).SpeechNode); } else if (uiNodes[i] is UIOptionNode) { conversation.Options.Add((uiNodes[i] as UIOptionNode).OptionNode); } } // Serialize CurrentAsset.Serialize(conversation); // Null / clear everything. We aren't pointing to it anymore. if (!manual) { CurrentAsset = null; while (uiNodes.Count != 0) { uiNodes.RemoveAt(0); } CurrentlySelectedNode = null; } #if UNITY_EDITOR if (!Application.isPlaying) { UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene()); } #endif } }
private EditableConversation Dejsonify() { if (json == null || json == "") { return(null); } EditableConversation conversation = new EditableConversation(); System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)); DataContractJsonSerializer ser = new DataContractJsonSerializer(conversation.GetType()); conversation = ser.ReadObject(ms) as EditableConversation; ms.Close(); return(conversation); }
private void CreateParameters(EditableConversation ec, Conversation conversation) { for (int i = 0; i < ec.Parameters.Count; i++) { if (ec.Parameters[i].ParameterType == EditableParameter.eParamType.Bool) { EditableBoolParameter editableParam = ec.Parameters[i] as EditableBoolParameter; BoolParameter boolParam = new BoolParameter(editableParam.ParameterName, editableParam.BoolValue); conversation.Parameters.Add(boolParam); } else if (ec.Parameters[i].ParameterType == EditableParameter.eParamType.Int) { EditableIntParameter editableParam = ec.Parameters[i] as EditableIntParameter; IntParameter intParam = new IntParameter(editableParam.ParameterName, editableParam.IntValue); conversation.Parameters.Add(intParam); } } }
private string Jsonify(EditableConversation conversation) { if (conversation == null || conversation.Options == null) { return(""); } System.IO.MemoryStream ms = new System.IO.MemoryStream(); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(EditableConversation)); ser.WriteObject(ms, conversation); byte[] jsonData = ms.ToArray(); ms.Close(); string toJson = System.Text.Encoding.UTF8.GetString(jsonData, 0, jsonData.Length); return(toJson); }
public EditableConversation DeserializeForEditor() { // Dejsonify EditableConversation conversation = Dejsonify(); if (conversation != null) { // Copy the param list this.ParameterList = conversation.Parameters; // Deserialize the indivudual nodes { if (conversation.SpeechNodes != null) { for (int i = 0; i < conversation.SpeechNodes.Count; i++) { conversation.SpeechNodes[i].DeserializeAssetData(this); } } if (conversation.Options != null) { for (int i = 0; i < conversation.Options.Count; i++) { conversation.Options[i].DeserializeAssetData(this); } } } } else { conversation = new EditableConversation(); } conversation.SaveVersion = this.saveVersion; // Clear our dummy event Event = new UnityEngine.Events.UnityEvent(); // Reconstruct ReconstructEditableConversation(conversation); return(conversation); }
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); } } } }
//-------------------------------------- // 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 Conversation Deserialize() { // Deserialize an editor-version (containing all info) that // we will use to construct the user-facing Conversation data structure. EditableConversation ec = this.DeserializeForEditor(); // Create a conversation. Conversation conversation = new Conversation(); // Create a dictionary to store our created nodes by UID Dictionary <int, SpeechNode> dialogues = new Dictionary <int, SpeechNode>(); Dictionary <int, OptionNode> options = new Dictionary <int, OptionNode>(); // Create a Dialogue and Option node for each in the conversation // Put them in the dictionary for (int i = 0; i < ec.SpeechNodes.Count; i++) { SpeechNode node = new SpeechNode(); node.Name = ec.SpeechNodes[i].Name; node.Text = ec.SpeechNodes[i].Text; node.AutomaticallyAdvance = ec.SpeechNodes[i].AdvanceDialogueAutomatically; node.AutoAdvanceShouldDisplayOption = ec.SpeechNodes[i].AutoAdvanceShouldDisplayOption; node.TimeUntilAdvance = ec.SpeechNodes[i].TimeUntilAdvance; node.TMPFont = ec.SpeechNodes[i].TMPFont; node.Icon = ec.SpeechNodes[i].Icon; node.Audio = ec.SpeechNodes[i].Audio; node.Volume = ec.SpeechNodes[i].Volume; node.Options = new List <OptionNode>(); if (this.GetNodeData(ec.SpeechNodes[i].ID) != null) { node.Event = this.GetNodeData(ec.SpeechNodes[i].ID).Event; } dialogues.Add(ec.SpeechNodes[i].ID, node); } for (int i = 0; i < ec.Options.Count; i++) { OptionNode node = new OptionNode(); node.Text = ec.Options[i].Text; node.TMPFont = ec.Options[i].TMPFont; options.Add(ec.Options[i].ID, node); } // Now that we have every node in the dictionary, reconstruct the tree // And also look for the root for (int i = 0; i < ec.SpeechNodes.Count; i++) { // Connect dialogue to options for (int j = 0; j < ec.SpeechNodes[i].OptionUIDs.Count; j++) { dialogues[ec.SpeechNodes[i].ID].Options.Add(options[ec.SpeechNodes[i].OptionUIDs[j]]); } // Connect dialogue to following dialogue if (ec.SpeechNodes[i].SpeechUID != EditableConversation.INVALID_UID) { dialogues[ec.SpeechNodes[i].ID].Dialogue = dialogues[ec.SpeechNodes[i].SpeechUID]; } // Check if root if (ec.SpeechNodes[i].EditorInfo.isRoot) { conversation.Root = dialogues[ec.SpeechNodes[i].ID]; } } for (int i = 0; i < ec.Options.Count; i++) { // Connect option to following dialogue if (dialogues.ContainsKey(ec.Options[i].SpeechUID)) { options[ec.Options[i].ID].Dialogue = dialogues[ec.Options[i].SpeechUID]; } } return(conversation); }
//-------------------------------------- // Serialize and Deserialize //-------------------------------------- public void Serialize(EditableConversation conversation) { json = Jsonify(conversation); saveVersion = CurrentVersion; }
//-------------------------------------- // Serialize and Deserialize //-------------------------------------- /// <summary> /// Save a editable conversation to an NPCConversation during runtime. /// </summary> /// <param name="conversation">The conversation to save.</param> public void RuntimeSave(EditableConversation conversation) { this.RuntimeEC = conversation; }