diff --git a/Assets/Fungus/Scripts/Commands/SetVariable.cs b/Assets/Fungus/Scripts/Commands/SetVariable.cs index bf61f99c..4b3d9b8b 100644 --- a/Assets/Fungus/Scripts/Commands/SetVariable.cs +++ b/Assets/Fungus/Scripts/Commands/SetVariable.cs @@ -2,28 +2,10 @@ // It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) using UnityEngine; +using System.Collections.Generic; namespace Fungus { - /// - /// Mathematical operations that can be performed on variables. - /// - public enum SetOperator - { - /// = operator. - Assign, - /// =! operator. - Negate, - /// += operator. - Add, - /// -= operator. - Subtract, - /// *= operator. - Multiply, - /// /= operator. - Divide - } - /// /// Sets a Boolean, Integer, Float or String variable to a new value using a simple arithmetic operation. The value can be a constant or reference another variable of the same type. /// @@ -37,7 +19,8 @@ namespace Fungus [VariableProperty(typeof(BooleanVariable), typeof(IntegerVariable), typeof(FloatVariable), - typeof(StringVariable))] + typeof(StringVariable), + typeof(GameObjectVariable))] [SerializeField] protected Variable variable; [Tooltip("The type of math operation to be performed")] @@ -55,6 +38,9 @@ namespace Fungus [Tooltip("String value to set with")] [SerializeField] protected StringDataMulti stringData; + [Tooltip("GameObject value to set with")] + [SerializeField] protected GameObjectData gameObjectData; + protected virtual void DoSetOperation() { if (variable == null) @@ -64,90 +50,42 @@ namespace Fungus if (variable.GetType() == typeof(BooleanVariable)) { - BooleanVariable lhs = (variable as BooleanVariable); - bool rhs = booleanData.Value; - - switch (setOperator) - { - default: - case SetOperator.Assign: - lhs.Value = rhs; - break; - case SetOperator.Negate: - lhs.Value = !rhs; - break; - } + BooleanVariable booleanVariable = (variable as BooleanVariable); + booleanVariable.Apply(setOperator, booleanData.Value); } else if (variable.GetType() == typeof(IntegerVariable)) { - IntegerVariable lhs = (variable as IntegerVariable); - int rhs = integerData.Value; - - switch (setOperator) - { - default: - case SetOperator.Assign: - lhs.Value = rhs; - break; - case SetOperator.Add: - lhs.Value += rhs; - break; - case SetOperator.Subtract: - lhs.Value -= rhs; - break; - case SetOperator.Multiply: - lhs.Value *= rhs; - break; - case SetOperator.Divide: - lhs.Value /= rhs; - break; - } + IntegerVariable integerVariable = (variable as IntegerVariable); + integerVariable.Apply(setOperator, integerData.Value); } else if (variable.GetType() == typeof(FloatVariable)) { - FloatVariable lhs = (variable as FloatVariable); - float rhs = floatData.Value; - - switch (setOperator) - { - default: - case SetOperator.Assign: - lhs.Value = rhs; - break; - case SetOperator.Add: - lhs.Value += rhs; - break; - case SetOperator.Subtract: - lhs.Value -= rhs; - break; - case SetOperator.Multiply: - lhs.Value *= rhs; - break; - case SetOperator.Divide: - lhs.Value /= rhs; - break; - } + FloatVariable floatVariable = (variable as FloatVariable); + floatVariable.Apply(setOperator, floatData.Value); } else if (variable.GetType() == typeof(StringVariable)) { - StringVariable lhs = (variable as StringVariable); - string rhs = stringData.Value; - + StringVariable stringVariable = (variable as StringVariable); var flowchart = GetFlowchart(); - rhs = flowchart.SubstituteVariables(rhs); - - switch (setOperator) - { - default: - case SetOperator.Assign: - lhs.Value = rhs; - break; - } + stringVariable.Apply(setOperator, flowchart.SubstituteVariables(stringData.Value)); + } + else if (variable.GetType() == typeof(GameObjectVariable)) + { + GameObjectVariable gameObjectVariable = (variable as GameObjectVariable); + gameObjectVariable.Apply(setOperator, gameObjectData.Value); } } #region Public members + public static readonly Dictionary operatorsByVariableType = new Dictionary() { + { typeof(BooleanVariable), BooleanVariable.setOperators }, + { typeof(IntegerVariable), IntegerVariable.setOperators }, + { typeof(FloatVariable), FloatVariable.setOperators }, + { typeof(StringVariable), StringVariable.setOperators }, + { typeof(GameObjectVariable), GameObjectVariable.setOperators } + }; + /// /// The type of math operation to be performed. /// @@ -208,6 +146,10 @@ namespace Fungus { description += stringData.GetDescription(); } + else if (variable.GetType() == typeof(GameObjectVariable)) + { + description += gameObjectData.GetDescription(); + } return description; } diff --git a/Assets/Fungus/Scripts/Components/Variable.cs b/Assets/Fungus/Scripts/Components/Variable.cs index 4fb7ea3d..45108425 100644 --- a/Assets/Fungus/Scripts/Components/Variable.cs +++ b/Assets/Fungus/Scripts/Components/Variable.cs @@ -25,6 +25,25 @@ namespace Fungus GreaterThanOrEquals } + /// + /// Mathematical operations that can be performed on variables. + /// + public enum SetOperator + { + /// = operator. + Assign, + /// =! operator. + Negate, + /// += operator. + Add, + /// -= operator. + Subtract, + /// *= operator. + Multiply, + /// /= operator. + Divide + } + /// /// Scope types for Variables. /// @@ -176,5 +195,9 @@ namespace Fungus // Remember the initial value so we can reset later on startValue = Value; } + + public virtual void Apply(SetOperator setOperator, T value) { + Debug.LogError("Variable doesn't have any operators."); + } } } diff --git a/Assets/Fungus/Scripts/Editor/SetVariableEditor.cs b/Assets/Fungus/Scripts/Editor/SetVariableEditor.cs index 8d200f6a..f8b1c394 100644 --- a/Assets/Fungus/Scripts/Editor/SetVariableEditor.cs +++ b/Assets/Fungus/Scripts/Editor/SetVariableEditor.cs @@ -11,12 +11,24 @@ namespace Fungus.EditorUtils [CustomEditor (typeof(SetVariable))] public class SetVariableEditor : CommandEditor { + protected struct VariablePropertyInfo + { + public string name; + public SerializedProperty dataProp; + + public VariablePropertyInfo(string name, SerializedProperty dataProp) { + this.name = name; + this.dataProp = dataProp; + } + } + protected SerializedProperty variableProp; protected SerializedProperty setOperatorProp; - protected SerializedProperty booleanDataProp; - protected SerializedProperty integerDataProp; - protected SerializedProperty floatDataProp; - protected SerializedProperty stringDataProp; + + // Variable data props + protected Dictionary propertyInfoByVariableType; + + protected List variableDataProps; protected virtual void OnEnable() { @@ -25,10 +37,15 @@ namespace Fungus.EditorUtils variableProp = serializedObject.FindProperty("variable"); setOperatorProp = serializedObject.FindProperty("setOperator"); - booleanDataProp = serializedObject.FindProperty("booleanData"); - integerDataProp = serializedObject.FindProperty("integerData"); - floatDataProp = serializedObject.FindProperty("floatData"); - stringDataProp = serializedObject.FindProperty("stringData"); + + // Get variable data props by name + propertyInfoByVariableType = new Dictionary() { + { typeof(BooleanVariable), new VariablePropertyInfo("Boolean", serializedObject.FindProperty("booleanData")) }, + { typeof(IntegerVariable), new VariablePropertyInfo("Integer", serializedObject.FindProperty("integerData")) }, + { typeof(FloatVariable), new VariablePropertyInfo("Float", serializedObject.FindProperty("floatData")) }, + { typeof(StringVariable), new VariablePropertyInfo("String", serializedObject.FindProperty("stringData")) }, + { typeof(GameObjectVariable), new VariablePropertyInfo("GameObject", serializedObject.FindProperty("gameObjectData")) } + }; } public override void DrawCommandGUI() @@ -43,6 +60,7 @@ namespace Fungus.EditorUtils return; } + // Select Variable EditorGUILayout.PropertyField(variableProp); if (variableProp.objectReferenceValue == null) @@ -51,107 +69,62 @@ namespace Fungus.EditorUtils return; } + // Get selected variable Variable selectedVariable = variableProp.objectReferenceValue as Variable; System.Type variableType = selectedVariable.GetType(); + // Get operators for the variable + SetOperator[] setOperators = SetVariable.operatorsByVariableType[variableType]; + + // Create operator list List operatorsList = new List(); - operatorsList.Add(new GUIContent("=")); - if (variableType == typeof(BooleanVariable)) - { - operatorsList.Add(new GUIContent("=!")); - } - else if (variableType == typeof(IntegerVariable) || - variableType == typeof(FloatVariable)) + foreach (var setOperator in setOperators) { - operatorsList.Add(new GUIContent("+=")); - operatorsList.Add(new GUIContent("-=")); - operatorsList.Add(new GUIContent("*=")); - operatorsList.Add(new GUIContent("\\=")); + switch (setOperator) + { + case SetOperator.Assign: + operatorsList.Add(new GUIContent("=")); + break; + case SetOperator.Negate: + operatorsList.Add(new GUIContent("=!")); + break; + case SetOperator.Add: + operatorsList.Add(new GUIContent("+=")); + break; + case SetOperator.Subtract: + operatorsList.Add(new GUIContent("-=")); + break; + case SetOperator.Multiply: + operatorsList.Add(new GUIContent("*=")); + break; + case SetOperator.Divide: + operatorsList.Add(new GUIContent("\\=")); + break; + default: + Debug.LogError("The " + setOperator.ToString() + " operator has no matching GUIContent."); + break; + } } - int selectedIndex = 0; - switch (t._SetOperator) + // Get previously selected operator + int selectedIndex = System.Array.IndexOf(setOperators, t._SetOperator); + if (selectedIndex < 0) { - default: - case SetOperator.Assign: - selectedIndex = 0; - break; - case SetOperator.Negate: - selectedIndex = 1; - break; - case SetOperator.Add: - selectedIndex = 1; - break; - case SetOperator.Subtract: - selectedIndex = 2; - break; - case SetOperator.Multiply: - selectedIndex = 3; - break; - case SetOperator.Divide: - selectedIndex = 4; - break; + // Default to first index if the operator is not found in the available operators list + // This can occur when changing between variable types + selectedIndex = 0; } + // Get next selected operator selectedIndex = EditorGUILayout.Popup(new GUIContent("Operation", "Arithmetic operator to use"), selectedIndex, operatorsList.ToArray()); - SetOperator setOperator = SetOperator.Assign; - if (variableType == typeof(BooleanVariable) || - variableType == typeof(StringVariable)) - { - switch (selectedIndex) - { - default: - case 0: - setOperator = SetOperator.Assign; - break; - case 1: - setOperator = SetOperator.Negate; - break; - } - } - else if (variableType == typeof(IntegerVariable) || - variableType == typeof(FloatVariable)) - { - switch (selectedIndex) - { - default: - case 0: - setOperator = SetOperator.Assign; - break; - case 1: - setOperator = SetOperator.Add; - break; - case 2: - setOperator = SetOperator.Subtract; - break; - case 3: - setOperator = SetOperator.Multiply; - break; - case 4: - setOperator = SetOperator.Divide; - break; - } - } - setOperatorProp.enumValueIndex = (int)setOperator; + setOperatorProp.enumValueIndex = (int)setOperators[selectedIndex]; + + + VariablePropertyInfo propertyInfo = propertyInfoByVariableType[variableType]; + EditorGUILayout.PropertyField(propertyInfo.dataProp, new GUIContent(propertyInfo.name)); - if (variableType == typeof(BooleanVariable)) - { - EditorGUILayout.PropertyField(booleanDataProp, new GUIContent("Boolean")); - } - else if (variableType == typeof(IntegerVariable)) - { - EditorGUILayout.PropertyField(integerDataProp, new GUIContent("Integer")); - } - else if (variableType == typeof(FloatVariable)) - { - EditorGUILayout.PropertyField(floatDataProp, new GUIContent("Float")); - } - else if (variableType == typeof(StringVariable)) - { - EditorGUILayout.PropertyField(stringDataProp, new GUIContent("String")); - } serializedObject.ApplyModifiedProperties(); } diff --git a/Assets/Fungus/Scripts/Editor/VariableEditor.cs b/Assets/Fungus/Scripts/Editor/VariableEditor.cs index 7acf938b..09a23582 100644 --- a/Assets/Fungus/Scripts/Editor/VariableEditor.cs +++ b/Assets/Fungus/Scripts/Editor/VariableEditor.cs @@ -229,7 +229,7 @@ namespace Fungus.EditorUtils Rect valueRect = controlRect; valueRect.width = controlRect.width - popupWidth - 5; Rect popupRect = controlRect; - + if (referenceProp.objectReferenceValue == null) { EditorGUI.PropertyField(valueRect, valueProp, new GUIContent("")); diff --git a/Assets/Fungus/Scripts/VariableTypes/BooleanVariable.cs b/Assets/Fungus/Scripts/VariableTypes/BooleanVariable.cs index 79a96331..1037241a 100644 --- a/Assets/Fungus/Scripts/VariableTypes/BooleanVariable.cs +++ b/Assets/Fungus/Scripts/VariableTypes/BooleanVariable.cs @@ -13,6 +13,8 @@ namespace Fungus [System.Serializable] public class BooleanVariable : VariableBase { + public static readonly SetOperator[] setOperators = { SetOperator.Assign, SetOperator.Negate }; + public virtual bool Evaluate(CompareOperator compareOperator, bool booleanValue) { bool condition = false; @@ -34,6 +36,19 @@ namespace Fungus return condition; } + public override void Apply(SetOperator setOperator, bool value) + { + switch (setOperator) + { + default: + case SetOperator.Assign: + Value = value; + break; + case SetOperator.Negate: + Value = !value; + break; + } + } } /// diff --git a/Assets/Fungus/Scripts/VariableTypes/FloatVariable.cs b/Assets/Fungus/Scripts/VariableTypes/FloatVariable.cs index 93c0349d..d3e9614f 100644 --- a/Assets/Fungus/Scripts/VariableTypes/FloatVariable.cs +++ b/Assets/Fungus/Scripts/VariableTypes/FloatVariable.cs @@ -13,6 +13,8 @@ namespace Fungus [System.Serializable] public class FloatVariable : VariableBase { + public static readonly SetOperator[] setOperators = { SetOperator.Assign, SetOperator.Add, SetOperator.Subtract, SetOperator.Multiply, SetOperator.Divide }; + public virtual bool Evaluate(CompareOperator compareOperator, float floatValue) { float lhs = Value; @@ -44,6 +46,29 @@ namespace Fungus return condition; } + + public override void Apply(SetOperator setOperator, float value) + { + switch (setOperator) + { + default: + case SetOperator.Assign: + Value = value; + break; + case SetOperator.Add: + Value += value; + break; + case SetOperator.Subtract: + Value -= value; + break; + case SetOperator.Multiply: + Value *= value; + break; + case SetOperator.Divide: + Value /= value; + break; + } + } } /// diff --git a/Assets/Fungus/Scripts/VariableTypes/GameObjectVariable.cs b/Assets/Fungus/Scripts/VariableTypes/GameObjectVariable.cs index 8a67c671..4cf7b1ba 100644 --- a/Assets/Fungus/Scripts/VariableTypes/GameObjectVariable.cs +++ b/Assets/Fungus/Scripts/VariableTypes/GameObjectVariable.cs @@ -13,7 +13,20 @@ namespace Fungus [AddComponentMenu("")] [System.Serializable] public class GameObjectVariable : VariableBase - {} + { + public static readonly SetOperator[] setOperators = { SetOperator.Assign }; + + public override void Apply(SetOperator setOperator, GameObject value) + { + switch (setOperator) + { + default: + case SetOperator.Assign: + Value = value; + break; + } + } + } /// /// Container for a GameObject variable reference or constant value. diff --git a/Assets/Fungus/Scripts/VariableTypes/IntegerVariable.cs b/Assets/Fungus/Scripts/VariableTypes/IntegerVariable.cs index ab477453..a3a78b78 100644 --- a/Assets/Fungus/Scripts/VariableTypes/IntegerVariable.cs +++ b/Assets/Fungus/Scripts/VariableTypes/IntegerVariable.cs @@ -13,6 +13,8 @@ namespace Fungus [System.Serializable] public class IntegerVariable : VariableBase { + public static readonly SetOperator[] setOperators = { SetOperator.Assign, SetOperator.Add, SetOperator.Subtract, SetOperator.Multiply, SetOperator.Divide }; + public virtual bool Evaluate(CompareOperator compareOperator, int integerValue) { int lhs = Value; @@ -44,6 +46,29 @@ namespace Fungus return condition; } + + public override void Apply(SetOperator setOperator, int value) + { + switch (setOperator) + { + default: + case SetOperator.Assign: + Value = value; + break; + case SetOperator.Add: + Value += value; + break; + case SetOperator.Subtract: + Value -= value; + break; + case SetOperator.Multiply: + Value *= value; + break; + case SetOperator.Divide: + Value /= value; + break; + } + } } /// diff --git a/Assets/Fungus/Scripts/VariableTypes/StringVariable.cs b/Assets/Fungus/Scripts/VariableTypes/StringVariable.cs index ef0ec2cf..c9772b3b 100644 --- a/Assets/Fungus/Scripts/VariableTypes/StringVariable.cs +++ b/Assets/Fungus/Scripts/VariableTypes/StringVariable.cs @@ -13,6 +13,8 @@ namespace Fungus [System.Serializable] public class StringVariable : VariableBase { + public static readonly SetOperator[] setOperators = { SetOperator.Assign }; + public virtual bool Evaluate(CompareOperator compareOperator, string stringValue) { string lhs = Value; @@ -33,6 +35,17 @@ namespace Fungus return condition; } + + public override void Apply(SetOperator setOperator, string value) + { + switch (setOperator) + { + default: + case SetOperator.Assign: + Value = value; + break; + } + } } ///