CangJie/Assets/Plugins/Fungus/Scripts/Editor/InvokeMethodEditor.cs
Roman 787b285227 任务:新建项目 导入必要的插件
1.导入URP
2.配置了URP
3.导入Dotween
4.导入Odin
5.导入了InputSystem
6.设置项目为新旧输入系统并用
7.导入了FunGus
8.创建了一些空文件夹

我是每日提醒上班小助手,今天你上班了吗?😺
2022-03-10 22:49:14 +08:00

442 lines
18 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// This code is part of the Fungus library (https://github.com/snozbot/fungus)
// 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;
}
}
}