private void SetMessageOption(int index, string field, int slot, MessageOptions.ValueType value) { m_List.GetArrayElementAtIndex(index).FindPropertyRelative(field).GetArrayElementAtIndex(slot).enumValueIndex = (int)value; }
void MessageSettings() { //path is set and boolean for displaying message settings is true //(button below was clicked) if (showMessageSetup) { //draw button for hiding message settings if (GUILayout.Button("Hide Message Settings")) { showMessageSetup = false; } EditorGUILayout.BeginHorizontal(); //clear message values if (GUILayout.Button("Clear")) { //display custom dialog and wait for user input to clear all message values if (EditorUtility.DisplayDialog("Are you sure?", "Do you really want to reset all messages and their values?", "Continue", "Cancel")) { //user clicked "Yes", reset array size to zero m_List.arraySize = 0; } } //delete all message values and disable settings so they are not recreated again if (GUILayout.Button("Deactivate")) { //display custom dialog and wait for user input to delete all message values if (EditorUtility.DisplayDialog("Are you sure?", "This will delete all message slots to reduce memory usage.", "Continue", "Cancel")) { //user clicked "Yes", reset array size to zero and hide settings m_List.arraySize = 0; showMessageSetup = false; return; } } EditorGUILayout.EndHorizontal(); //begin a scrolling view inside GUI, pass in Vector2 scroll position scrollPosMessage = EditorGUILayout.BeginScrollView(scrollPosMessage, GUILayout.Height(245)); //get modifiable list of MessageProperties mList = GetMessageList(); //loop through list for (int i = 0; i < mList.Count; i++) { EditorGUILayout.BeginHorizontal(); //draw label with waypoint index, display total count of messages for this waypoint //increased by one (so it does not start at zero) EditorGUILayout.HelpBox((i + 1) + ". Waypoint - " + "Messages: " + mList[i].message.Count, MessageType.None); //add new message to this waypoint if (GUILayout.Button("+")) { AddMessageOption(i); } //remove last message from this waypoint if (mList[i].message.Count > 1 && GUILayout.Button("-")) { RemoveMessageOption(i); } EditorGUILayout.EndHorizontal(); //loop through messages for (int j = 0; j < mList[i].message.Count; j++) { //display text box and message name input field EditorGUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("Method: ", MessageType.None); string messageField = EditorGUILayout.TextField(mList[i].message[j]); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); //display enum for selectable data types //declare variables for each data type for storing their input value MessageOptions.ValueType typeField = (MessageOptions.ValueType)EditorGUILayout.EnumPopup(mList[i].type[j]); Object objField; string textField; float numField; Vector2 vect2Field; Vector3 vect3Field; //draw corresponding data type field for selected enum type //store input in the values above. if the field has changed, //set the corresponding type value for the current MessageOption switch (typeField) { case MessageOptions.ValueType.None: break; case MessageOptions.ValueType.Object: objField = EditorGUILayout.ObjectField(mList[i].obj[j], typeof(Object), true); if (GUI.changed) { SetMessageOption(i, "obj", j, objField); } break; case MessageOptions.ValueType.Text: textField = EditorGUILayout.TextField(mList[i].text[j]); if (GUI.changed) { SetMessageOption(i, "text", j, textField); } break; case MessageOptions.ValueType.Numeric: numField = EditorGUILayout.FloatField(mList[i].num[j]); if (GUI.changed) { SetMessageOption(i, "num", j, numField); } break; case MessageOptions.ValueType.Vector2: vect2Field = EditorGUILayout.Vector2Field("", mList[i].vect2[j]); if (GUI.changed) { SetMessageOption(i, "vect2", j, vect2Field); } break; case MessageOptions.ValueType.Vector3: vect3Field = EditorGUILayout.Vector3Field("", mList[i].vect3[j]); if (GUI.changed) { SetMessageOption(i, "vect3", j, vect3Field); } break; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); //regardless of the data type, //set the message name and enum type of this MessageOption if (GUI.changed) { SetMessageOption(i, "message", j, messageField); SetMessageOption(i, "type", j, typeField); } } } //ends the scrollview defined above EditorGUILayout.EndScrollView(); //here we check for the last GUI pass, where the Inspector gets drawn //the first pass is responsible for the GUI layout of all fields, //and if we resize the list in the first pass it throws an error in the second pass //this is because the first and the second pass must have the same values on redraw if (Event.current.type == EventType.Repaint) { //get total list size and set it to the waypoint size, //so each waypoint has one MessageOption value m_List.arraySize = GetPathTransform().waypoints.Length; //loop through messages per waypoint for (int i = 0; i < mList.Count; i++) { //if the waypoint does not contain a message option, add a new slot if (mList[i].message.Count == 0) { AddMessageOption(i); break; } } } } else { //if path is set but delay settings are not shown, //draw button to toggle showDelaySetup if (GUILayout.Button("Show Message Settings")) { showMessageSetup = true; } } }
//override message settings of moveEditor public override void MessageSettings() { //path is set and display is enabled if (showMessageSetup) { //draw button for hiding message settings if (GUILayout.Button("Hide Message Settings")) { showMessageSetup = false; } EditorGUILayout.BeginHorizontal(); //delete all message values and disable settings if (GUILayout.Button("Deactivate all Messages")) { //display custom dialog and wait for user input to delete all message values if (EditorUtility.DisplayDialog("Are you sure?", "This will delete all message slots to reduce memory usage.", "Continue", "Cancel")) { m_List.arraySize = 0; showMessageSetup = false; return; } } EditorGUILayout.EndHorizontal(); //button to insert a new message at the end if (GUILayout.Button("+ Add new Message +")) { //increase the message count by one m_List.arraySize++; mList = GetMessageList(); //insert a new callable message, //only if the message has no slot already if (mList[mList.Count - 1].message.Count == 0) { AddMessageOption(mList.Count - 1); } //when adding a new message, the values from the latest message //gets copied to the new one. We want a fresh message instead, //so we remove all other slots until one slot remains for (int i = mList[mList.Count - 1].message.Count - 1; i > 0; i--) { RemoveMessageOption(mList.Count - 1); } } //begin a scrolling view inside GUI, pass in Vector2 scroll position scrollPosMessage = EditorGUILayout.BeginScrollView(scrollPosMessage, GUILayout.Height(245)); //get modifiable list of MessageProperties mList = GetMessageList(); //loop through list for (int i = 0; i < mList.Count; i++) { EditorGUILayout.BeginHorizontal(); //draw label with waypoint index, display total count of messages for this waypoint EditorGUILayout.HelpBox("Message " + i + " - Message Count: " + mList[i].message.Count, MessageType.None); //button to add new message to this waypoint if (GUILayout.Button("+")) { AddMessageOption(i); } //button to remove last message from this waypoint if (GUILayout.Button("-")) { RemoveMessageOption(i); //delete the message if no slots are left if (mList[i].message.Count == 1) { m_List.DeleteArrayElementAtIndex(i); } break; } EditorGUILayout.EndHorizontal(); //display text box with path progress input field (call position), //clamped between 0 (start) and 1 (end) EditorGUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("Call at path position in %:", MessageType.None); float callAtPosField = EditorGUILayout.FloatField(mList[i].pos, GUILayout.Width(60)); callAtPosField = Mathf.Clamp01(callAtPosField); EditorGUILayout.EndHorizontal(); //loop through messages for (int j = 0; j < mList[i].message.Count; j++) { //display text box and message name input field EditorGUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("Method:", MessageType.None); string messageField = EditorGUILayout.TextField(mList[i].message[j]); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); //display enum for selectable data types //declare variables for each data type for storing their input value MessageOptions.ValueType typeField = (MessageOptions.ValueType)EditorGUILayout.EnumPopup(mList[i].type[j]); Object objField; string textField; float numField; Vector2 vect2Field; Vector3 vect3Field; //draw corresponding data type field for selected enum type //store input in the values above. if the field has changed, //set the corresponding type value for the current MessageOption switch (typeField) { case MessageOptions.ValueType.None: break; case MessageOptions.ValueType.Object: objField = EditorGUILayout.ObjectField(mList[i].obj[j], typeof(Object), true); if (GUI.changed) { SetMessageOption(i, "obj", j, objField); } break; case MessageOptions.ValueType.Text: textField = EditorGUILayout.TextField(mList[i].text[j]); if (GUI.changed) { SetMessageOption(i, "text", j, textField); } break; case MessageOptions.ValueType.Numeric: numField = EditorGUILayout.FloatField(mList[i].num[j]); if (GUI.changed) { SetMessageOption(i, "num", j, numField); } break; case MessageOptions.ValueType.Vector2: vect2Field = EditorGUILayout.Vector2Field("", mList[i].vect2[j]); if (GUI.changed) { SetMessageOption(i, "vect2", j, vect2Field); } break; case MessageOptions.ValueType.Vector3: vect3Field = EditorGUILayout.Vector3Field("", mList[i].vect3[j]); if (GUI.changed) { SetMessageOption(i, "vect3", j, vect3Field); } break; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); //regardless of the data type, //set the call position, message name and enum type of this MessageOption if (GUI.changed) { SetMessageKeyPos(i, callAtPosField); SetMessageOption(i, "message", j, messageField); SetMessageOption(i, "type", j, typeField); } } } //ends the scrollview defined above EditorGUILayout.EndScrollView(); } else { //draw button to toggle showDelaySetup if (GUILayout.Button("Show Message Settings")) { showMessageSetup = true; } } }