diff --git a/Assets/Fungus/FungusScript/Editor/FungusCommandEditor.cs b/Assets/Fungus/FungusScript/Editor/FungusCommandEditor.cs index 98e08854..f6d0dd5f 100644 --- a/Assets/Fungus/FungusScript/Editor/FungusCommandEditor.cs +++ b/Assets/Fungus/FungusScript/Editor/FungusCommandEditor.cs @@ -103,27 +103,18 @@ namespace Fungus.Script GUILayout.BeginHorizontal(); - string commandName = FungusScriptEditor.GetCommandName(t.GetType()); - GUILayout.Label(commandName, EditorStyles.largeLabel); - - GUILayout.FlexibleSpace(); - - bool enabled = GUILayout.Toggle(t.enabled, ""); + bool enabled = GUILayout.Toggle(t.enabled, new GUIContent()); if (t.enabled != enabled) { Undo.RecordObject(t, "Set Enabled"); t.enabled = enabled; } - if (GUILayout.Button("Up", EditorStyles.miniButtonLeft)) - { - UnityEditorInternal.ComponentUtility.MoveComponentUp(t); - } - if (GUILayout.Button("Down", EditorStyles.miniButtonMid)) - { - UnityEditorInternal.ComponentUtility.MoveComponentDown(t); - } - + string commandName = FungusScriptEditor.GetCommandName(t.GetType()); + GUILayout.Label(commandName + " Command", EditorStyles.boldLabel); + + GUILayout.FlexibleSpace(); + if (fungusScript != null) { if (GUILayout.Button("Copy", EditorStyles.miniButtonMid)) @@ -133,18 +124,16 @@ namespace Fungus.Script if (fungusScript.copyCommand != null) { - if (GUILayout.Button("Paste", EditorStyles.miniButtonMid)) + if (GUILayout.Button("Paste", EditorStyles.miniButton)) { - CopyComponent(fungusScript.copyCommand, t.gameObject); + Sequence parentSequence = t.GetComponent(); + if (parentSequence != null) + { + PasteCommand(fungusScript.copyCommand, parentSequence); + } } } } - - if (GUILayout.Button("Delete", EditorStyles.miniButtonRight)) - { - Undo.DestroyObjectImmediate(t); - return; - } GUILayout.EndHorizontal(); @@ -169,16 +158,24 @@ namespace Fungus.Script DrawDefaultInspector(); } - T CopyComponent(T original, GameObject destination) where T : Component + static public FungusCommand PasteCommand(FungusCommand copyCommand, Sequence sequence) { - System.Type type = original.GetType(); - Component copy = Undo.AddComponent(destination, type); + System.Type type = copyCommand.GetType(); + Component copy = Undo.AddComponent(sequence.gameObject, type); System.Reflection.FieldInfo[] fields = type.GetFields(); foreach (System.Reflection.FieldInfo field in fields) { - field.SetValue(copy, field.GetValue(original)); + field.SetValue(copy, field.GetValue(copyCommand)); } - return copy as T; + + FungusScript fungusScript = sequence.GetFungusScript(); + + Undo.RecordObject(fungusScript, "Paste Command"); + + FungusCommand newCommand = copy as FungusCommand; + sequence.commandList.Add(newCommand); + + return newCommand; } static public T ObjectField(GUIContent label, GUIContent nullLabel, T selectedObject, List objectList) where T : MonoBehaviour diff --git a/Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs b/Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs new file mode 100644 index 00000000..9c80acf2 --- /dev/null +++ b/Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs @@ -0,0 +1,195 @@ +// Copyright (c) 2012-2013 Rotorz Limited. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +using UnityEngine; +using UnityEditor; +using System; +using Rotorz.ReorderableList; + +namespace Fungus.Script +{ + public class FungusCommandListAdaptor : IReorderableListAdaptor { + + private SerializedProperty _arrayProperty; + + public float fixedItemHeight; + + public SerializedProperty this[int index] { + get { return _arrayProperty.GetArrayElementAtIndex(index); } + } + + public SerializedProperty arrayProperty { + get { return _arrayProperty; } + } + + public FungusCommandListAdaptor(SerializedProperty arrayProperty, float fixedItemHeight) { + if (arrayProperty == null) + throw new ArgumentNullException("Array property was null."); + if (!arrayProperty.isArray) + throw new InvalidOperationException("Specified serialized propery is not an array."); + + this._arrayProperty = arrayProperty; + this.fixedItemHeight = fixedItemHeight; + } + + public FungusCommandListAdaptor(SerializedProperty arrayProperty) : this(arrayProperty, 0f) { + } + + public int Count { + get { return _arrayProperty.arraySize; } + } + + public virtual bool CanDrag(int index) { + return true; + } + + public virtual bool CanRemove(int index) { + return true; + } + + public void Add() { + int newIndex = _arrayProperty.arraySize; + ++_arrayProperty.arraySize; + ResetValue(_arrayProperty.GetArrayElementAtIndex(newIndex)); + } + + public void Insert(int index) { + _arrayProperty.InsertArrayElementAtIndex(index); + ResetValue(_arrayProperty.GetArrayElementAtIndex(index)); + } + + public void Duplicate(int index) { + _arrayProperty.InsertArrayElementAtIndex(index); + } + + public void Remove(int index) { + // Remove the Fungus Command component + FungusCommand command = _arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue as FungusCommand; + Undo.DestroyObjectImmediate(command); + + _arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue = null; + _arrayProperty.DeleteArrayElementAtIndex(index); + } + + public void Move(int sourceIndex, int destIndex) { + if (destIndex > sourceIndex) + --destIndex; + _arrayProperty.MoveArrayElement(sourceIndex, destIndex); + } + + public void Clear() { + _arrayProperty.ClearArray(); + } + + public void DrawItem(Rect position, int index) + { + FungusCommand command = this[index].objectReferenceValue as FungusCommand; + + FungusScript fungusScript = command.GetFungusScript(); + + bool error = false; + string summary = command.GetSummary().Replace("\n", "").Replace("\r", ""); + if (summary.Length > 80) + { + summary = summary.Substring(0, 80) + "..."; + } + if (summary.StartsWith("Error:")) + { + error = true; + } + + if (!command.enabled) + { + GUI.backgroundColor = Color.grey; + } + else if (error) + { + GUI.backgroundColor = Color.red; + } + else if (fungusScript.selectedCommand == command) + { + GUI.backgroundColor = Color.yellow; + } + + Rect buttonRect = position; + buttonRect.width = 80; + + Rect summaryRect = position; + summaryRect.x += 85; + summaryRect.width -= 85; + + string commandName = FungusScriptEditor.GetCommandName(command.GetType()); + if (GUI.Button(buttonRect, commandName, EditorStyles.miniButton)) + { + fungusScript.selectedCommand = command; + GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) + } + GUI.backgroundColor = Color.white; + + GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel); + labelStyle.wordWrap = true; + if (!command.enabled) + { + labelStyle.normal.textColor = Color.grey; + } + else if (error) + { + labelStyle.normal.textColor = Color.red; + } + + GUI.Label(summaryRect, summary, labelStyle); + + if (Event.current.type == EventType.Repaint && + command.IsExecuting()) + { + GLDraw.DrawBox(position, Color.green, 1.5f); + } + } + + public virtual float GetItemHeight(int index) { + return fixedItemHeight != 0f + ? fixedItemHeight + : EditorGUI.GetPropertyHeight(this[index], GUIContent.none, false) + ; + } + + private void ResetValue(SerializedProperty element) { + switch (element.type) { + case "string": + element.stringValue = ""; + break; + case "Vector2f": + element.vector2Value = Vector2.zero; + break; + case "Vector3f": + element.vector3Value = Vector3.zero; + break; + case "Rectf": + element.rectValue = new Rect(); + break; + case "Quaternionf": + element.quaternionValue = Quaternion.identity; + break; + case "int": + element.intValue = 0; + break; + case "float": + element.floatValue = 0f; + break; + case "UInt8": + element.boolValue = false; + break; + case "ColorRGBA": + element.colorValue = Color.black; + break; + + default: + if (element.type.StartsWith("PPtr")) + element.objectReferenceValue = null; + break; + } + } + } +} + diff --git a/Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs.meta b/Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs.meta new file mode 100644 index 00000000..edfe930d --- /dev/null +++ b/Assets/Fungus/FungusScript/Editor/FungusCommandListAdaptor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44d3aa3e5c3bf4b99b9899e8d5f5bc52 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs b/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs index 72d6fbce..a9d807da 100644 --- a/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs +++ b/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs @@ -2,7 +2,6 @@ using UnityEditor; using UnityEngine; using System.Collections; using System.Collections.Generic; -using Fungus; using Rotorz.ReorderableList; using System.Linq; @@ -74,120 +73,6 @@ namespace Fungus.Script DrawVariablesGUI(); } - public void DrawSequenceGUI(FungusScript fungusScript) - { - if (fungusScript.selectedSequence == null) - { - return; - } - - Sequence sequence = fungusScript.selectedSequence; - - EditorGUI.BeginChangeCheck(); - - string name = EditorGUILayout.TextField(new GUIContent("Name", "Name of sequence displayed in editor window"), sequence.name); - string desc = EditorGUILayout.TextField(new GUIContent("Description", "Sequence description displayed in editor window"), sequence.description); - - EditorGUILayout.Separator(); - - if (name != sequence.name) - { - // The name is the gameobject name, so have to undo seperately - Undo.RecordObject(sequence.gameObject, "Set Sequence Name"); - sequence.name = name; - } - - if (desc != sequence.description) - { - Undo.RecordObject(sequence, "Set Sequence Description"); - sequence.description = desc; - } - - GUILayout.Box("Commands", GUILayout.ExpandWidth(true)); - - FungusCommand[] commands = sequence.GetComponents(); - foreach (FungusCommand command in commands) - { - FungusCommandEditor commandEditor = Editor.CreateEditor(command) as FungusCommandEditor; - commandEditor.DrawCommandRowGUI(); - } - - if (Application.isPlaying) - { - return; - } - - EditorGUILayout.Separator(); - - GUILayout.Box("New Command", GUILayout.ExpandWidth(true)); - - EditorGUI.BeginChangeCheck(); - - EditorGUILayout.BeginHorizontal(); - - List commandNames = new List(); - List commandTypes = EditorExtensions.FindDerivedTypes(typeof(FungusCommand)).ToList(); - - foreach (System.Type type in commandTypes) - { - object[] attributes = type.GetCustomAttributes(false); - foreach (object obj in attributes) - { - CommandCategoryAttribute categoryAttr = obj as CommandCategoryAttribute; - if (categoryAttr != null) - { - string commandItem = categoryAttr.Category + " / " + GetCommandName(type); - commandNames.Add(commandItem); - break; - } - } - } - - int selectedCommandIndex = EditorGUILayout.Popup(fungusScript.selectedAddCommandIndex, commandNames.ToArray()); - - if (EditorGUI.EndChangeCheck()) - { - Undo.RecordObject(fungusScript, "Select Command"); - fungusScript.selectedAddCommandIndex = selectedCommandIndex; - } - - if (selectedCommandIndex >= commandTypes.Count) - { - EditorGUILayout.EndHorizontal(); - return; - } - - System.Type selectedType = commandTypes[selectedCommandIndex]; - if (fungusScript.selectedSequence == null || - selectedType == null) - { - EditorGUILayout.EndHorizontal(); - return; - } - - if (GUILayout.Button(new GUIContent("Add", "Add the selected command to the sequence"), EditorStyles.miniButton)) - { - Undo.AddComponent(fungusScript.selectedSequence.gameObject, selectedType); - } - - EditorGUILayout.EndHorizontal(); - - object[] helpAttributes = selectedType.GetCustomAttributes(typeof(HelpTextAttribute), false); - foreach (object obj in helpAttributes) - { - HelpTextAttribute helpTextAttr = obj as HelpTextAttribute; - if (helpTextAttr != null) - { - GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel); - labelStyle.wordWrap = true; - EditorGUILayout.HelpBox(helpTextAttr.HelpText, MessageType.Info); - break; - } - } - - EditorGUILayout.Separator(); - } - public void DrawVariablesGUI() { serializedObject.Update(); diff --git a/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs b/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs index f09d356b..f4005e97 100755 --- a/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs +++ b/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs @@ -51,7 +51,7 @@ namespace Fungus.Script GUILayout.BeginHorizontal(); DrawScriptView(fungusScript); ResizeViews(fungusScript); - DrawCommandView(fungusScript); + DrawSequenceView(fungusScript); GUILayout.EndHorizontal(); } @@ -179,7 +179,7 @@ namespace Fungus.Script } } - void DrawCommandView(FungusScript fungusScript) + void DrawSequenceView(FungusScript fungusScript) { GUILayout.Space(5); @@ -235,13 +235,16 @@ namespace Fungus.Script } GUILayout.EndHorizontal(); - - EditorGUILayout.Separator(); - FungusScriptEditor editor = Editor.CreateEditor(fungusScript) as FungusScriptEditor; - editor.DrawSequenceGUI(fungusScript); + if (fungusScript.selectedSequence != null) + { + EditorGUILayout.Separator(); + + SequenceEditor editor = Editor.CreateEditor(fungusScript.selectedSequence) as SequenceEditor; + editor.DrawSequenceGUI(fungusScript); - GUILayout.FlexibleSpace(); + GUILayout.FlexibleSpace(); + } EditorGUILayout.EndVertical(); diff --git a/Assets/Fungus/FungusScript/Editor/FungusVariableListAdaptor.cs b/Assets/Fungus/FungusScript/Editor/FungusVariableListAdaptor.cs index d208fa1f..c73f077a 100644 --- a/Assets/Fungus/FungusScript/Editor/FungusVariableListAdaptor.cs +++ b/Assets/Fungus/FungusScript/Editor/FungusVariableListAdaptor.cs @@ -198,8 +198,7 @@ namespace Fungus.Script if (fungusScript.selectedSequence != null && fungusScript.selectedCommand != null) { - FungusCommand[] commands = fungusScript.selectedSequence.GetComponents(); - foreach (FungusCommand command in commands) + foreach (FungusCommand command in fungusScript.selectedSequence.commandList) { if (fungusScript.selectedCommand == command && command.HasReference(variable)) diff --git a/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs b/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs index 4477f37b..4cb230d4 100644 --- a/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs +++ b/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs @@ -3,6 +3,8 @@ using UnityEngine; using System; using System.Collections; using System.Collections.Generic; +using System.Linq; +using Rotorz.ReorderableList; namespace Fungus.Script { @@ -10,6 +12,134 @@ namespace Fungus.Script [CustomEditor (typeof(Sequence))] public class SequenceEditor : Editor { + public void DrawSequenceGUI(FungusScript fungusScript) + { + if (fungusScript.selectedSequence == null) + { + return; + } + + serializedObject.Update(); + + Sequence sequence = fungusScript.selectedSequence; + + EditorGUI.BeginChangeCheck(); + + string name = EditorGUILayout.TextField(new GUIContent("Name", "Name of sequence displayed in editor window"), sequence.name); + string desc = EditorGUILayout.TextField(new GUIContent("Description", "Sequence description displayed in editor window"), sequence.description); + + EditorGUILayout.Separator(); + + if (name != sequence.name) + { + // The name is the gameobject name, so have to undo seperately + Undo.RecordObject(sequence.gameObject, "Set Sequence Name"); + sequence.name = name; + } + + if (desc != sequence.description) + { + Undo.RecordObject(sequence, "Set Sequence Description"); + sequence.description = desc; + } + + + ReorderableListGUI.Title("Command Sequence"); + + SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); + FungusCommandListAdaptor adaptor = new FungusCommandListAdaptor(commandListProperty, 0); + ReorderableListControl.DrawControlFromState(adaptor, null, ReorderableListFlags.DisableContextMenu | ReorderableListFlags.HideAddButton); + + if (Application.isPlaying) + { + return; + } + + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.Separator(); + + EditorGUILayout.BeginHorizontal(); + + List commandNames = new List(); + List commandTypes = EditorExtensions.FindDerivedTypes(typeof(FungusCommand)).ToList(); + + foreach (System.Type type in commandTypes) + { + object[] attributes = type.GetCustomAttributes(false); + foreach (object obj in attributes) + { + CommandCategoryAttribute categoryAttr = obj as CommandCategoryAttribute; + if (categoryAttr != null) + { + string commandItem = categoryAttr.Category + " / " + FungusScriptEditor.GetCommandName(type); + commandNames.Add(commandItem); + break; + } + } + } + + Rect newRect = GUILayoutUtility.GetRect(100, 30); + + int selectedCommandIndex = EditorGUI.Popup(newRect, fungusScript.selectedAddCommandIndex, commandNames.ToArray()); + + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(fungusScript, "Select Command"); + fungusScript.selectedAddCommandIndex = selectedCommandIndex; + } + + if (selectedCommandIndex >= commandTypes.Count) + { + EditorGUILayout.EndHorizontal(); + return; + } + + System.Type selectedType = commandTypes[selectedCommandIndex]; + if (fungusScript.selectedSequence == null || + selectedType == null) + { + EditorGUILayout.EndHorizontal(); + return; + } + + if (GUILayout.Button(new GUIContent("Add Command", "Add the selected command to the sequence"), EditorStyles.miniButton)) + { + FungusCommand newCommand = Undo.AddComponent(fungusScript.selectedSequence.gameObject, selectedType) as FungusCommand; + Undo.RecordObject(fungusScript, "Add Command"); + fungusScript.selectedSequence.commandList.Add(newCommand); + } + + /* + if (fungusScript.copyCommand != null) + { + if (GUILayout.Button("Paste", EditorStyles.miniButton)) + { + FungusCommandEditor.PasteCommand(fungusScript.copyCommand, fungusScript.selectedSequence); + } + } + */ + + EditorGUILayout.EndHorizontal(); + + object[] helpAttributes = selectedType.GetCustomAttributes(typeof(HelpTextAttribute), false); + foreach (object obj in helpAttributes) + { + HelpTextAttribute helpTextAttr = obj as HelpTextAttribute; + if (helpTextAttr != null) + { + GUIStyle labelStyle = new GUIStyle(EditorStyles.miniLabel); + labelStyle.wordWrap = true; + EditorGUILayout.HelpBox(helpTextAttr.HelpText, MessageType.Info); + break; + } + } + + EditorGUILayout.Separator(); + + serializedObject.ApplyModifiedProperties(); + } + static public Sequence SequenceField(GUIContent label, GUIContent nullLabel, FungusScript fungusScript, Sequence sequence) { if (fungusScript == null) diff --git a/Assets/Fungus/FungusScript/Scripts/Sequence.cs b/Assets/Fungus/FungusScript/Scripts/Sequence.cs index 2210fbb8..f256cd98 100644 --- a/Assets/Fungus/FungusScript/Scripts/Sequence.cs +++ b/Assets/Fungus/FungusScript/Scripts/Sequence.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; namespace Fungus.Script { + [ExecuteInEditMode] public class Sequence : MonoBehaviour { [HideInInspector] @@ -23,8 +24,10 @@ namespace Fungus.Script [System.NonSerialized] public FungusCommand activeCommand; + public List commandList = new List(); + int executionCount; - + public virtual void Start() { fungusScript = GetFungusScript(); @@ -48,8 +51,7 @@ namespace Fungus.Script public bool HasError() { - FungusCommand[] commands = GetComponents(); - foreach (FungusCommand command in commands) + foreach (FungusCommand command in commandList) { if (command.errorMessage.Length > 0) { @@ -87,8 +89,7 @@ namespace Fungus.Script FungusCommand nextCommand = null; bool executeNext = (currentCommand == null); - FungusCommand[] commands = GetComponents(); - foreach (FungusCommand command in commands) + foreach (FungusCommand command in commandList) { if (command == currentCommand) { diff --git a/Assets/Shuttle/ShuttleGame.unity b/Assets/Shuttle/ShuttleGame.unity index 30447e9e..1243a7d6 100644 Binary files a/Assets/Shuttle/ShuttleGame.unity and b/Assets/Shuttle/ShuttleGame.unity differ