Browse Source
Renamed Invoke to Invoke Event (uses EventSystem). Added Invoke Method command contributed by bigdiddy on forum. Made some minor changes to contrbuted code: 1. Show Inherited is now on it’s own line in inspector 2. Removed Init on Awake option - always inits on awake 3. Added a Delay property to be consistent with Invoke Event command Added an integration test for both Invoke Event and Invoke Methodmaster
chrisgregan
10 years ago
13 changed files with 2123 additions and 13 deletions
@ -1,6 +1,6 @@ |
|||||||
fileFormatVersion: 2 |
fileFormatVersion: 2 |
||||||
guid: 1de123a9a8da54ff49b112d39101366b |
guid: 04b135d1f6a7a40429648cb2ac86ba0b |
||||||
timeCreated: 1437051529 |
timeCreated: 1439371705 |
||||||
licenseType: Free |
licenseType: Free |
||||||
MonoImporter: |
MonoImporter: |
||||||
serializedVersion: 2 |
serializedVersion: 2 |
@ -0,0 +1,442 @@ |
|||||||
|
using UnityEngine; |
||||||
|
using System.Collections; |
||||||
|
using UnityEditor; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Fungus |
||||||
|
{ |
||||||
|
|
||||||
|
[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; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 79f9520ae0b21494caa8f8bc97a2db9d |
||||||
|
timeCreated: 1439307700 |
||||||
|
licenseType: Free |
||||||
|
MonoImporter: |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -0,0 +1,403 @@ |
|||||||
|
using UnityEngine; |
||||||
|
using System.Collections; |
||||||
|
using System.Reflection; |
||||||
|
using System.Linq; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System; |
||||||
|
using UnityEngine.Events; |
||||||
|
|
||||||
|
namespace Fungus |
||||||
|
{ |
||||||
|
|
||||||
|
[CommandInfo("Scripting", |
||||||
|
"Invoke Method", |
||||||
|
"Invokes a method of a component via reflection. Supports passing multiple parameters and storing returned values in a Fungus variable.")] |
||||||
|
public class InvokeMethod : Command |
||||||
|
{ |
||||||
|
[Tooltip("Delay before invoking method")] |
||||||
|
public float delay; |
||||||
|
|
||||||
|
[Tooltip("GameObject containing the component method to be invoked")] |
||||||
|
public GameObject targetObject; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("Name of assembly containing the target component")] |
||||||
|
public string targetComponentAssemblyName; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("Full name of the target component")] |
||||||
|
public string targetComponentFullname; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("Display name of the target component")] |
||||||
|
public string targetComponentText; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("Name of target method to invoke on the target component")] |
||||||
|
public string targetMethod; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("Display name of target method to invoke on the target component")] |
||||||
|
public string targetMethodText; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("List of parameters to pass to the invoked method")] |
||||||
|
public InvokeMethodParameter[] methodParameters; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("If true, store the return value in a flowchart variable of the same type.")] |
||||||
|
public bool saveReturnValue; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("Name of Fungus variable to store the return value in")] |
||||||
|
public string returnValueVariableKey; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("The type of the return value")] |
||||||
|
public string returnValueType; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("If true, list all inherited methods for the component")] |
||||||
|
public bool showInherited; |
||||||
|
|
||||||
|
[HideInInspector] |
||||||
|
[Tooltip("The coroutine call behavior for methods that return IEnumerator")] |
||||||
|
public Fungus.Call.CallMode callMode; |
||||||
|
|
||||||
|
protected Type componentType; |
||||||
|
protected Component objComponent; |
||||||
|
protected Type[] parameterTypes = null; |
||||||
|
protected MethodInfo objMethod; |
||||||
|
|
||||||
|
protected virtual void Awake() |
||||||
|
{ |
||||||
|
if (componentType == null) |
||||||
|
{ |
||||||
|
componentType = ReflectionHelper.GetType(targetComponentAssemblyName); |
||||||
|
} |
||||||
|
|
||||||
|
if (objComponent == null) |
||||||
|
{ |
||||||
|
objComponent = targetObject.GetComponent(componentType); |
||||||
|
} |
||||||
|
|
||||||
|
if (parameterTypes == null) |
||||||
|
{ |
||||||
|
parameterTypes = GetParameterTypes(); |
||||||
|
} |
||||||
|
|
||||||
|
if (objMethod == null) |
||||||
|
{ |
||||||
|
objMethod = UnityEvent.GetValidMethodInfo(objComponent, targetMethod, parameterTypes); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnEnter() |
||||||
|
{ |
||||||
|
if (delay <= 0) |
||||||
|
{ |
||||||
|
DoInvokeMethod(); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Invoke("DoInvokeMethod", delay); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected virtual void DoInvokeMethod() |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
if (targetObject == null || string.IsNullOrEmpty(targetComponentAssemblyName) || string.IsNullOrEmpty(targetMethod)) |
||||||
|
{ |
||||||
|
Continue(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (returnValueType != "System.Collections.IEnumerator") |
||||||
|
{ |
||||||
|
var objReturnValue = objMethod.Invoke(objComponent, GetParameterValues()); |
||||||
|
|
||||||
|
if (saveReturnValue) |
||||||
|
{ |
||||||
|
SetVariable(returnValueVariableKey, objReturnValue, returnValueType); |
||||||
|
} |
||||||
|
|
||||||
|
Continue(); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
StartCoroutine(ExecuteCoroutine()); |
||||||
|
|
||||||
|
if(callMode == Call.CallMode.Continue) |
||||||
|
{ |
||||||
|
Continue(); |
||||||
|
} |
||||||
|
else if(callMode == Call.CallMode.Stop) |
||||||
|
{ |
||||||
|
Stop(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
catch (System.Exception ex) |
||||||
|
{ |
||||||
|
Debug.LogError("Error: " + ex.Message); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected virtual IEnumerator ExecuteCoroutine() |
||||||
|
{ |
||||||
|
yield return StartCoroutine((IEnumerator)objMethod.Invoke(objComponent, GetParameterValues())); |
||||||
|
|
||||||
|
if (callMode == Call.CallMode.WaitUntilFinished) |
||||||
|
{ |
||||||
|
Continue(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override Color GetButtonColor() |
||||||
|
{ |
||||||
|
return new Color32(235, 191, 217, 255); |
||||||
|
} |
||||||
|
|
||||||
|
public override string GetSummary() |
||||||
|
{ |
||||||
|
if (targetObject == null) |
||||||
|
{ |
||||||
|
return "Error: targetObject is not assigned"; |
||||||
|
} |
||||||
|
|
||||||
|
return targetObject.name + "." + targetComponentText + "." + targetMethodText; |
||||||
|
} |
||||||
|
|
||||||
|
protected System.Type[] GetParameterTypes() |
||||||
|
{ |
||||||
|
System.Type[] types = new System.Type[methodParameters.Length]; |
||||||
|
|
||||||
|
for (int i = 0; i < methodParameters.Length; i++) |
||||||
|
{ |
||||||
|
var item = methodParameters[i]; |
||||||
|
var objType = ReflectionHelper.GetType(item.objValue.typeAssemblyname); |
||||||
|
|
||||||
|
types[i] = objType; |
||||||
|
} |
||||||
|
|
||||||
|
return types; |
||||||
|
} |
||||||
|
|
||||||
|
protected object[] GetParameterValues() |
||||||
|
{ |
||||||
|
object[] values = new object[methodParameters.Length]; |
||||||
|
var flowChart = GetFlowchart(); |
||||||
|
|
||||||
|
for (int i = 0; i < methodParameters.Length; i++) |
||||||
|
{ |
||||||
|
var item = methodParameters[i]; |
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(item.variableKey)) |
||||||
|
{ |
||||||
|
values[i] = item.objValue.GetValue(); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
object objValue = null; |
||||||
|
|
||||||
|
switch (item.objValue.typeFullname) |
||||||
|
{ |
||||||
|
case "System.Int32": |
||||||
|
objValue = flowChart.GetIntegerVariable(item.variableKey); |
||||||
|
break; |
||||||
|
case "System.Boolean": |
||||||
|
objValue = flowChart.GetBooleanVariable(item.variableKey); |
||||||
|
break; |
||||||
|
case "System.Single": |
||||||
|
objValue = flowChart.GetFloatVariable(item.variableKey); |
||||||
|
break; |
||||||
|
case "System.String": |
||||||
|
objValue = flowChart.GetStringVariable(item.variableKey); |
||||||
|
break; |
||||||
|
case "UnityEngine.Color": |
||||||
|
var color = flowChart.GetVariable<ColorVariable>(item.variableKey); |
||||||
|
if (color != null) |
||||||
|
objValue = color.value; |
||||||
|
break; |
||||||
|
case "UnityEngine.GameObject": |
||||||
|
var gameObject = flowChart.GetVariable<GameObjectVariable>(item.variableKey); |
||||||
|
if (gameObject != null) |
||||||
|
objValue = gameObject.value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Material": |
||||||
|
var material = flowChart.GetVariable<MaterialVariable>(item.variableKey); |
||||||
|
if (material != null) |
||||||
|
objValue = material.value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Sprite": |
||||||
|
var sprite = flowChart.GetVariable<SpriteVariable>(item.variableKey); |
||||||
|
if (sprite != null) |
||||||
|
objValue = sprite.value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Texture": |
||||||
|
var texture = flowChart.GetVariable<TextureVariable>(item.variableKey); |
||||||
|
if (texture != null) |
||||||
|
objValue = texture.value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Vector2": |
||||||
|
var vector2 = flowChart.GetVariable<Vector2Variable>(item.variableKey); |
||||||
|
if (vector2 != null) |
||||||
|
objValue = vector2.value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Vector3": |
||||||
|
var vector3 = flowChart.GetVariable<Vector3Variable>(item.variableKey); |
||||||
|
if (vector3 != null) |
||||||
|
objValue = vector3.value; |
||||||
|
break; |
||||||
|
default: |
||||||
|
var obj = flowChart.GetVariable<ObjectVariable>(item.variableKey); |
||||||
|
if (obj != null) |
||||||
|
objValue = obj.value; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
values[i] = objValue; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return values; |
||||||
|
} |
||||||
|
|
||||||
|
protected void SetVariable(string key, object value, string returnType) |
||||||
|
{ |
||||||
|
var flowChart = GetFlowchart(); |
||||||
|
|
||||||
|
switch (returnType) |
||||||
|
{ |
||||||
|
case "System.Int32": |
||||||
|
flowChart.SetIntegerVariable(key, (int)value); |
||||||
|
break; |
||||||
|
case "System.Boolean": |
||||||
|
flowChart.SetBooleanVariable(key, (bool)value); |
||||||
|
break; |
||||||
|
case "System.Single": |
||||||
|
flowChart.SetFloatVariable(key, (float)value); |
||||||
|
break; |
||||||
|
case "System.String": |
||||||
|
flowChart.SetStringVariable(key, (string)value); |
||||||
|
break; |
||||||
|
case "UnityEngine.Color": |
||||||
|
flowChart.GetVariable<ColorVariable>(key).value = (UnityEngine.Color)value; |
||||||
|
break; |
||||||
|
case "UnityEngine.GameObject": |
||||||
|
flowChart.GetVariable<GameObjectVariable>(key).value = (UnityEngine.GameObject)value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Material": |
||||||
|
flowChart.GetVariable<MaterialVariable>(key).value = (UnityEngine.Material)value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Sprite": |
||||||
|
flowChart.GetVariable<SpriteVariable>(key).value = (UnityEngine.Sprite)value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Texture": |
||||||
|
flowChart.GetVariable<TextureVariable>(key).value = (UnityEngine.Texture)value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Vector2": |
||||||
|
flowChart.GetVariable<Vector2Variable>(key).value = (UnityEngine.Vector2)value; |
||||||
|
break; |
||||||
|
case "UnityEngine.Vector3": |
||||||
|
flowChart.GetVariable<Vector3Variable>(key).value = (UnityEngine.Vector3)value; |
||||||
|
break; |
||||||
|
default: |
||||||
|
flowChart.GetVariable<ObjectVariable>(key).value = (UnityEngine.Object)value; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[System.Serializable] |
||||||
|
public class InvokeMethodParameter |
||||||
|
{ |
||||||
|
[SerializeField] |
||||||
|
public ObjectValue objValue; |
||||||
|
|
||||||
|
|
||||||
|
[SerializeField] |
||||||
|
public string variableKey; |
||||||
|
} |
||||||
|
|
||||||
|
[System.Serializable] |
||||||
|
public class ObjectValue |
||||||
|
{ |
||||||
|
public string typeAssemblyname; |
||||||
|
public string typeFullname; |
||||||
|
|
||||||
|
public int intValue; |
||||||
|
public bool boolValue; |
||||||
|
public float floatValue; |
||||||
|
public string stringValue; |
||||||
|
|
||||||
|
public Color colorValue; |
||||||
|
public GameObject gameObjectValue; |
||||||
|
public Material materialValue; |
||||||
|
public UnityEngine.Object objectValue; |
||||||
|
public Sprite spriteValue; |
||||||
|
public Texture textureValue; |
||||||
|
public Vector2 vector2Value; |
||||||
|
public Vector3 vector3Value; |
||||||
|
|
||||||
|
public object GetValue() |
||||||
|
{ |
||||||
|
switch (typeFullname) |
||||||
|
{ |
||||||
|
case "System.Int32": |
||||||
|
return intValue; |
||||||
|
case "System.Boolean": |
||||||
|
return boolValue; |
||||||
|
case "System.Single": |
||||||
|
return floatValue; |
||||||
|
case "System.String": |
||||||
|
return stringValue; |
||||||
|
case "UnityEngine.Color": |
||||||
|
return colorValue; |
||||||
|
case "UnityEngine.GameObject": |
||||||
|
return gameObjectValue; |
||||||
|
case "UnityEngine.Material": |
||||||
|
return materialValue; |
||||||
|
case "UnityEngine.Sprite": |
||||||
|
return spriteValue; |
||||||
|
case "UnityEngine.Texture": |
||||||
|
return textureValue; |
||||||
|
case "UnityEngine.Vector2": |
||||||
|
return vector2Value; |
||||||
|
case "UnityEngine.Vector3": |
||||||
|
return vector3Value; |
||||||
|
default: |
||||||
|
var objType = ReflectionHelper.GetType(typeAssemblyname); |
||||||
|
|
||||||
|
if (objType.IsSubclassOf(typeof(UnityEngine.Object))) |
||||||
|
{ |
||||||
|
return objectValue; |
||||||
|
} |
||||||
|
else if (objType.IsEnum) |
||||||
|
return System.Enum.ToObject(objType, intValue); |
||||||
|
|
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class ReflectionHelper |
||||||
|
{ |
||||||
|
static Dictionary<string, System.Type> types = new Dictionary<string, System.Type>(); |
||||||
|
|
||||||
|
public static System.Type GetType(string typeName) |
||||||
|
{ |
||||||
|
if (types.ContainsKey(typeName)) |
||||||
|
return types[typeName]; |
||||||
|
|
||||||
|
types[typeName] = System.Type.GetType(typeName); |
||||||
|
|
||||||
|
return types[typeName]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 688e35811870d403f9e2b1ab2a699d98 |
||||||
|
timeCreated: 1439307694 |
||||||
|
licenseType: Free |
||||||
|
MonoImporter: |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -0,0 +1,9 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: a2fb91ead9b574717b37022fc3669fe2 |
||||||
|
folderAsset: yes |
||||||
|
timeCreated: 1439306621 |
||||||
|
licenseType: Free |
||||||
|
DefaultImporter: |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: a2189f9c94ed041ba883f114bc150965 |
||||||
|
timeCreated: 1439306636 |
||||||
|
licenseType: Free |
||||||
|
DefaultImporter: |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -0,0 +1,113 @@ |
|||||||
|
using UnityEngine; |
||||||
|
using System.Collections; |
||||||
|
|
||||||
|
namespace Fungus |
||||||
|
{ |
||||||
|
|
||||||
|
public class TestInvoke : MonoBehaviour |
||||||
|
{ |
||||||
|
public Flowchart flowchart; |
||||||
|
|
||||||
|
public int passCount; |
||||||
|
|
||||||
|
public void TestCall() |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
} |
||||||
|
|
||||||
|
public void TestCall(bool boolParam) |
||||||
|
{ |
||||||
|
if (boolParam) |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void TestCall(int intParam) |
||||||
|
{ |
||||||
|
if (intParam == 10) |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void TestCall(float floatParam) |
||||||
|
{ |
||||||
|
if (floatParam == 5.2f) |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void TestCall(string stringParam) |
||||||
|
{ |
||||||
|
if (stringParam == "ok") |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public bool TestCall(bool boolParam, int intParam, float floatParam, string stringParam) |
||||||
|
{ |
||||||
|
if (boolParam && intParam == 10 && floatParam == 5.2f && stringParam == "ok") |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public int TestReturnInteger() |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
return 5; |
||||||
|
} |
||||||
|
|
||||||
|
public float TestReturnFloat() |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
return 22.1f; |
||||||
|
} |
||||||
|
|
||||||
|
public string TestReturnString() |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
return "a string"; |
||||||
|
} |
||||||
|
|
||||||
|
public void DelayedInvokeEvent() |
||||||
|
{ |
||||||
|
passCount++; |
||||||
|
} |
||||||
|
|
||||||
|
public void CheckTestResult() |
||||||
|
{ |
||||||
|
if (flowchart == null) |
||||||
|
{ |
||||||
|
IntegrationTest.Fail("Flowchart object not selected"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Check Fungus variables are populated with expected values |
||||||
|
if (flowchart.GetBooleanVariable("BoolVar") != true || |
||||||
|
flowchart.GetIntegerVariable("IntVar") != 5 || |
||||||
|
flowchart.GetFloatVariable("FloatVar") != 22.1f || |
||||||
|
flowchart.GetStringVariable("StringVar") != "a string") |
||||||
|
{ |
||||||
|
IntegrationTest.Fail("Fungus variables do not match expected values"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Check the right number of methods were invoked successfully |
||||||
|
if (passCount == 10) |
||||||
|
{ |
||||||
|
IntegrationTest.Pass(); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
IntegrationTest.Fail("A method did not get invoked or parameter was incorrect"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 63b819364b72f4eceae495ec5d3173e2 |
||||||
|
timeCreated: 1439306669 |
||||||
|
licenseType: Free |
||||||
|
MonoImporter: |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
Loading…
Reference in new issue