|
|
|
// 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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|