You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
444 lines
18 KiB
444 lines
18 KiB
// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus). |
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) |
|
|
|
using UnityEngine; |
|
using System.Collections; |
|
using UnityEditor; |
|
using System.Linq; |
|
using System.Reflection; |
|
using System; |
|
using System.Collections.Generic; |
|
using Fungus.Commands; |
|
using Fungus.Variables; |
|
|
|
namespace Fungus.EditorUtils |
|
{ |
|
[CustomEditor(typeof(InvokeMethod))] |
|
public class InvokeMethodEditor : CommandEditor |
|
{ |
|
InvokeMethod targetMethod; |
|
|
|
public override void DrawCommandGUI() |
|
{ |
|
base.DrawCommandGUI(); |
|
|
|
targetMethod = target as InvokeMethod; |
|
|
|
if (targetMethod == null || targetMethod.TargetObject == null) |
|
return; |
|
|
|
SerializedObject objSerializedTarget = new SerializedObject(targetMethod); |
|
|
|
string component = ShowComponents(objSerializedTarget, targetMethod.TargetObject); |
|
|
|
// show component methods if selected |
|
if (!string.IsNullOrEmpty(component)) |
|
{ |
|
var method = ShowMethods(objSerializedTarget, targetMethod.TargetObject, component); |
|
|
|
// show method parameters if selected |
|
if (method != null) |
|
{ |
|
objSerializedTarget.ApplyModifiedProperties(); |
|
ShowParameters(objSerializedTarget, targetMethod.TargetObject, method); |
|
ShowReturnValue(objSerializedTarget, method); |
|
} |
|
} |
|
} |
|
|
|
private string ShowComponents(SerializedObject objTarget, GameObject gameObject) |
|
{ |
|
var targetComponentAssemblyName = objTarget.FindProperty("targetComponentAssemblyName"); |
|
var targetComponentFullname = objTarget.FindProperty("targetComponentFullname"); |
|
var targetComponentText = objTarget.FindProperty("targetComponentText"); |
|
var objComponents = gameObject.GetComponents<Component>(); |
|
var objTypesAssemblynames = (from objComp in objComponents select objComp.GetType().AssemblyQualifiedName).ToList(); |
|
var objTypesName = (from objComp in objComponents select objComp.GetType().Name).ToList(); |
|
|
|
int index = objTypesAssemblynames.IndexOf(targetComponentAssemblyName.stringValue); |
|
|
|
index = EditorGUILayout.Popup("Target Component", index, objTypesName.ToArray()); |
|
|
|
if (index != -1) |
|
{ |
|
targetComponentAssemblyName.stringValue = objTypesAssemblynames[index]; |
|
targetComponentFullname.stringValue = objComponents.GetType().FullName; |
|
targetComponentText.stringValue = objTypesName[index]; |
|
} |
|
else |
|
{ |
|
targetComponentAssemblyName.stringValue = null; |
|
} |
|
|
|
objTarget.ApplyModifiedProperties(); |
|
|
|
return targetComponentAssemblyName.stringValue; |
|
} |
|
|
|
private MethodInfo ShowMethods(SerializedObject objTarget, GameObject gameObject, string component) |
|
{ |
|
MethodInfo result = null; |
|
|
|
var targetMethodProp = objTarget.FindProperty("targetMethod"); |
|
var targetMethodTextProp = objTarget.FindProperty("targetMethodText"); |
|
var methodParametersProp = objTarget.FindProperty("methodParameters"); |
|
var showInheritedProp = objTarget.FindProperty("showInherited"); |
|
var saveReturnValueProp = objTarget.FindProperty("saveReturnValue"); |
|
var returnValueKeyProp = objTarget.FindProperty("returnValueVariableKey"); |
|
|
|
var objComponent = gameObject.GetComponent(ReflectionHelper.GetType(component)); |
|
var bindingFlags = BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance; |
|
|
|
if (!showInheritedProp.boolValue) |
|
{ |
|
bindingFlags |= BindingFlags.DeclaredOnly; |
|
} |
|
|
|
if (objComponent != null) |
|
{ |
|
var objMethods = objComponent.GetType().GetMethods(bindingFlags); |
|
var methods = (from objMethod in objMethods where !objMethod.IsSpecialName select objMethod).ToList(); // filter out the getter/setter methods |
|
var methodText = (from objMethod in methods select objMethod.Name + FormatParameters(objMethod.GetParameters()) + ": " + objMethod.ReturnType.Name).ToList(); |
|
int index = methodText.IndexOf(targetMethodTextProp.stringValue); |
|
|
|
index = EditorGUILayout.Popup("Target Method", index, methodText.ToArray()); |
|
|
|
EditorGUILayout.PropertyField(showInheritedProp); |
|
|
|
if (index != -1) |
|
{ |
|
if (targetMethodTextProp.stringValue != methodText[index]) |
|
{ |
|
// reset |
|
methodParametersProp.ClearArray(); |
|
methodParametersProp.arraySize = methods[index].GetParameters().Length; |
|
|
|
saveReturnValueProp.boolValue = false; |
|
returnValueKeyProp.stringValue = null; |
|
} |
|
|
|
targetMethodTextProp.stringValue = methodText[index]; |
|
targetMethodProp.stringValue = methods[index].Name; |
|
|
|
result = methods[index]; |
|
} |
|
else |
|
{ |
|
targetMethodTextProp.stringValue = null; |
|
targetMethodProp.stringValue = null; |
|
} |
|
|
|
objTarget.ApplyModifiedProperties(); |
|
} |
|
|
|
return result; |
|
} |
|
|
|
private void ShowParameters(SerializedObject objTarget, GameObject gameObject, MethodInfo method) |
|
{ |
|
var methodParametersProp = objTarget.FindProperty("methodParameters"); |
|
var objParams = method.GetParameters(); |
|
|
|
if (objParams.Length > 0) |
|
{ |
|
GUILayout.Space(20); |
|
EditorGUILayout.LabelField("Parameters", EditorStyles.boldLabel); |
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox); |
|
|
|
for (int i = 0; i < objParams.Length; i++) |
|
{ |
|
var objParam = objParams[i]; |
|
|
|
GUILayout.BeginHorizontal(); |
|
string labelFormat = string.Format("{0}: {1}", objParam.ParameterType.Name, objParam.Name); |
|
|
|
var objItemProp = methodParametersProp.GetArrayElementAtIndex(i); |
|
var serObjValueProp = objItemProp.FindPropertyRelative("objValue"); |
|
var serVariableKeyProp = objItemProp.FindPropertyRelative("variableKey"); |
|
var serValueTypeAssemblynameProp = serObjValueProp.FindPropertyRelative("typeAssemblyname"); |
|
var serValueTypeFullnameProp = serObjValueProp.FindPropertyRelative("typeFullname"); |
|
|
|
serValueTypeAssemblynameProp.stringValue = objParam.ParameterType.AssemblyQualifiedName; |
|
serValueTypeFullnameProp.stringValue = objParam.ParameterType.FullName; |
|
|
|
bool isDrawn = true; |
|
|
|
if (string.IsNullOrEmpty(serVariableKeyProp.stringValue)) |
|
{ |
|
isDrawn = DrawTypedPropertyInput(labelFormat, serObjValueProp, objParam.ParameterType); |
|
} |
|
|
|
if (isDrawn) |
|
{ |
|
var vars = GetFungusVariablesByType(targetMethod.GetFlowchart().Variables, objParam.ParameterType); |
|
var values = new string[] { "<Value>" }; |
|
var displayValue = values.Concat(vars).ToList(); |
|
|
|
int index = displayValue.IndexOf(serVariableKeyProp.stringValue); |
|
|
|
if (index == -1) |
|
{ |
|
index = 0; |
|
} |
|
|
|
if (string.IsNullOrEmpty(serVariableKeyProp.stringValue)) |
|
{ |
|
index = EditorGUILayout.Popup(index, displayValue.ToArray(), GUILayout.MaxWidth(80)); |
|
} |
|
else |
|
{ |
|
index = EditorGUILayout.Popup(labelFormat, index, displayValue.ToArray()); |
|
} |
|
|
|
if (index > 0) |
|
{ |
|
serVariableKeyProp.stringValue = displayValue[index]; |
|
} |
|
else |
|
{ |
|
serVariableKeyProp.stringValue = null; |
|
} |
|
} |
|
else |
|
{ |
|
var style = EditorStyles.label; |
|
var prevColor = style.normal.textColor; |
|
style.normal.textColor = Color.red; |
|
EditorGUILayout.LabelField(new GUIContent(objParam.ParameterType.Name + " cannot be drawn, don´t use this method in the flowchart."), style); |
|
style.normal.textColor = prevColor; |
|
} |
|
|
|
GUILayout.EndHorizontal(); |
|
} |
|
EditorGUILayout.EndVertical(); |
|
|
|
objTarget.ApplyModifiedProperties(); |
|
} |
|
} |
|
|
|
private void ShowReturnValue(SerializedObject objTarget, MethodInfo method) |
|
{ |
|
var saveReturnValueProp = objTarget.FindProperty("saveReturnValue"); |
|
var returnValueKeyProp = objTarget.FindProperty("returnValueVariableKey"); |
|
var returnValueTypeProp = objTarget.FindProperty("returnValueType"); |
|
var callModeProp = objTarget.FindProperty("callMode"); |
|
|
|
returnValueTypeProp.stringValue = method.ReturnType.FullName; |
|
|
|
if (method.ReturnType == typeof(IEnumerator)) |
|
{ |
|
GUILayout.Space(20); |
|
EditorGUILayout.PropertyField(callModeProp); |
|
} |
|
else if (method.ReturnType != typeof(void)) |
|
{ |
|
GUILayout.Space(20); |
|
EditorGUILayout.LabelField("Return Value", EditorStyles.boldLabel); |
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox); |
|
saveReturnValueProp.boolValue = EditorGUILayout.Toggle("Save return value", saveReturnValueProp.boolValue); |
|
|
|
if (saveReturnValueProp.boolValue) |
|
{ |
|
var vars = GetFungusVariablesByType(targetMethod.GetFlowchart().Variables, method.ReturnType).ToList(); |
|
int index = vars.IndexOf(returnValueKeyProp.stringValue); |
|
index = EditorGUILayout.Popup(method.ReturnType.Name, index, vars.ToArray()); |
|
|
|
if (index != -1) |
|
{ |
|
returnValueKeyProp.stringValue = vars[index]; |
|
} |
|
} |
|
|
|
EditorGUILayout.EndVertical(); |
|
} |
|
else |
|
{ |
|
saveReturnValueProp.boolValue = false; |
|
} |
|
|
|
objTarget.ApplyModifiedProperties(); |
|
} |
|
|
|
private bool DrawTypedPropertyInput(string label, SerializedProperty objProperty, Type type) |
|
{ |
|
SerializedProperty objectValue = null; |
|
|
|
if (type == typeof(int)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("intValue"); |
|
objectValue.intValue = EditorGUILayout.IntField(new GUIContent(label), objectValue.intValue); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(bool)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("boolValue"); |
|
objectValue.boolValue = EditorGUILayout.Toggle(new GUIContent(label), objectValue.boolValue); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(float)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("floatValue"); |
|
objectValue.floatValue = EditorGUILayout.FloatField(new GUIContent(label), objectValue.floatValue); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(string)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("stringValue"); |
|
objectValue.stringValue = EditorGUILayout.TextField(new GUIContent(label), objectValue.stringValue); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(Color)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("colorValue"); |
|
objectValue.colorValue = EditorGUILayout.ColorField(new GUIContent(label), objectValue.colorValue); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(UnityEngine.GameObject)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("gameObjectValue"); |
|
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.GameObject), true); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(UnityEngine.Material)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("materialValue"); |
|
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Material), true); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(UnityEngine.Sprite)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("spriteValue"); |
|
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Sprite), true); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(UnityEngine.Texture)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("textureValue"); |
|
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Texture), true); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(UnityEngine.Vector2)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("vector2Value"); |
|
objectValue.vector2Value = EditorGUILayout.Vector2Field(new GUIContent(label), objectValue.vector2Value); |
|
|
|
return true; |
|
} |
|
else if (type == typeof(UnityEngine.Vector3)) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("vector3Value"); |
|
objectValue.vector3Value = EditorGUILayout.Vector3Field(new GUIContent(label), objectValue.vector3Value); |
|
|
|
return true; |
|
} |
|
else if (type.IsSubclassOf(typeof(UnityEngine.Object))) |
|
{ |
|
objectValue = objProperty.FindPropertyRelative("objectValue"); |
|
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, type, true); |
|
|
|
return true; |
|
} |
|
else if (type.IsEnum) |
|
{ |
|
var enumNames = Enum.GetNames(type); |
|
objectValue = objProperty.FindPropertyRelative("intValue"); |
|
objectValue.intValue = EditorGUILayout.Popup(label, objectValue.intValue, enumNames); |
|
|
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
private string[] GetFungusVariablesByType(List<Variable> variables, Type type) |
|
{ |
|
string[] result = new string[0]; |
|
|
|
if (type == typeof(int)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(IntegerVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(bool)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(BooleanVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(float)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(FloatVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(string)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(StringVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(Color)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(ColorVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(UnityEngine.GameObject)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(GameObjectVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(UnityEngine.Material)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(MaterialVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(UnityEngine.Sprite)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(SpriteVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(UnityEngine.Texture)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(TextureVariable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(UnityEngine.Vector2)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(Vector2Variable) select v.Key).ToArray(); |
|
} |
|
else if (type == typeof(UnityEngine.Vector3)) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(Vector3Variable) select v.Key).ToArray(); |
|
} |
|
else if (type.IsSubclassOf(typeof(UnityEngine.Object))) |
|
{ |
|
result = (from v in variables where v.GetType() == typeof(ObjectVariable) select v.Key).ToArray(); |
|
} |
|
|
|
return result; |
|
} |
|
|
|
private string FormatParameters(ParameterInfo[] paramInfo) |
|
{ |
|
string result = " ("; |
|
|
|
for (int i = 0; i < paramInfo.Length; i++) |
|
{ |
|
var pi = paramInfo[i]; |
|
result += pi.ParameterType.Name; // " arg" + (i + 1); |
|
|
|
if (i < paramInfo.Length - 1) |
|
{ |
|
result += ", "; |
|
} |
|
} |
|
|
|
return result + ")"; |
|
} |
|
|
|
private object GetDefaultValue(Type t) |
|
{ |
|
if (t.IsValueType) |
|
return Activator.CreateInstance(t); |
|
|
|
return null; |
|
} |
|
} |
|
} |