Advertisement
Guest User

Untitled

a guest
Jun 21st, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 39.18 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System;
  4. using System.Reflection;
  5. using System.Collections.Generic;
  6.  
  7. using UIEventDelegate;
  8. using Object = UnityEngine.Object;
  9.  
  10. /// <summary>
  11. /// Draws a single event delegate. Contributed by Lermy Garcia and Adam Byrd.
  12. /// </summary>
  13.  
  14. [CustomPropertyDrawer(typeof(EventDelegate))]
  15. public class EventDelegateDrawer : PropertyDrawer
  16. {
  17.     EventDelegate eventDelegate = new EventDelegate();
  18.  
  19.     /// <summary>
  20.     /// The style and texture for the refresh icon.
  21.     /// </summary>
  22.  
  23.     static public GUIStyle mRefreshIconStyle;
  24.     static public Texture2D mRefreshIcon;
  25.     static public int mIconSize = 24;
  26.  
  27.     /// <summary>
  28.     /// The standard height size for each property line.
  29.     /// </summary>
  30.    
  31.     const int lineHeight = 16;
  32.    
  33.     /// <summary>
  34.     /// If you want the property drawer to limit its selection list to values of specified type, set this to something other than 'void'.
  35.     /// </summary>
  36.    
  37.     static public Type filter = typeof(void);
  38.    
  39.     /// <summary>
  40.     /// Whether it's possible to convert between basic types, such as int to string.
  41.     /// </summary>
  42.    
  43.     static public bool canConvert = true;
  44.    
  45.     //vector 4 workaround optimization
  46.     float[] vec4Values;
  47.     GUIContent[] vec4GUIContent;
  48.  
  49.     /// <summary>
  50.     /// Rect used to check for the minimalist method.
  51.     /// </summary>
  52.     Rect lineRect;
  53.  
  54.     /// <summary>
  55.     /// Width value to start using minimalistic method.
  56.     /// </summary>
  57.     //int minimalistWidth = 0; //TODO: implement minimalistic method, unity activates it at 257
  58.    
  59.     private Dictionary<string,List<Entry>> _methodCache = new Dictionary<string, List<Entry>>();
  60.  
  61.     public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
  62.     {
  63.         SerializedProperty showGroup = prop.FindPropertyRelative("mShowGroup");
  64.         if (!showGroup.boolValue)
  65.             return lineHeight;
  66.  
  67.         float lines = (3 * lineHeight);
  68.  
  69.         SerializedProperty targetProp = prop.FindPropertyRelative("mTarget");
  70.         if (targetProp.objectReferenceValue == null)
  71.             return lines;
  72.  
  73.         lines += lineHeight;
  74.  
  75.         SerializedProperty methodProp = prop.FindPropertyRelative("mMethodName");
  76.        
  77.         if (methodProp.stringValue == "<Choose>" || methodProp.stringValue.StartsWith("<Missing - "))
  78.             return lines;
  79.  
  80.         eventDelegate.target = targetProp.objectReferenceValue;
  81.         eventDelegate.methodName = methodProp.stringValue;
  82.        
  83.         if (eventDelegate.isValid == false)
  84.             return lines;
  85.  
  86.         SerializedProperty paramArrayProp = prop.FindPropertyRelative("mParameters");
  87.         EventDelegate.Parameter[] ps = eventDelegate.parameters;
  88.  
  89.         if (ps != null)
  90.         {
  91.             EventDelegate.Parameter param = null;
  92.  
  93.             int imax = ps.Length;
  94.             paramArrayProp.arraySize = imax;
  95.             for (int i = 0; i < imax; i++, param = null)
  96.             {
  97.                 param = ps [i];
  98.  
  99.                 lines += lineHeight;
  100.  
  101.                 SerializedProperty paramProp = paramArrayProp.GetArrayElementAtIndex(i);
  102.                 SerializedProperty objProp = paramProp.FindPropertyRelative("obj");
  103.  
  104.                 bool useManualValue = paramProp.FindPropertyRelative("paramRefType").enumValueIndex == (int)ParameterType.Value;
  105.  
  106.                 if (useManualValue)
  107.                 {
  108.                     if (param.expectedType == typeof(string) || param.expectedType == typeof(int) ||
  109.                         param.expectedType == typeof(float) || param.expectedType == typeof(double) ||
  110.                         param.expectedType == typeof(bool) || param.expectedType.IsEnum ||
  111.                         param.expectedType == typeof(Color))
  112.                     {
  113.                         continue;
  114.                     }
  115.                     else if (param.expectedType == typeof(Vector2) || param.expectedType == typeof(Vector3) || param.expectedType == typeof(Vector4))
  116.                     {
  117.                         //if (lineRect.width < minimalistWidth) //use minimalist method
  118.                         //{
  119.                         //    if (param.expectedType == typeof(Vector2) || param.expectedType == typeof(Vector3))
  120.                         //    {
  121.                         //        lines += lineHeight;
  122.                         //    }
  123.                         //}
  124.                         lines += 4;
  125.                         continue;
  126.                     }
  127.                 }
  128.                
  129.                 UnityEngine.Object obj = objProp.objectReferenceValue;
  130.                
  131.                 if (obj == null)
  132.                     continue;
  133.  
  134.                 System.Type type = obj.GetType();
  135.                
  136.                 GameObject selGO = null;
  137.                 if (type == typeof(GameObject))
  138.                     selGO = obj as GameObject;
  139.                 else if (type.IsSubclassOf(typeof(Component)))
  140.                     selGO = (obj as Component).gameObject;
  141.                
  142.                 if (selGO != null)
  143.                     lines += lineHeight;
  144.             }
  145.         }
  146.  
  147.         return lines;
  148.     }
  149.  
  150.     public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label)
  151.     {
  152.         Undo.RecordObject(prop.serializedObject.targetObject, "Delegate Selection");
  153.        
  154.         EditorGUI.BeginProperty(rect, label, prop);
  155.         int indent = EditorGUI.indentLevel;
  156.        
  157.         SerializedProperty showGroup = prop.FindPropertyRelative("mShowGroup");
  158.  
  159.         SerializedProperty nameProp = prop.FindPropertyRelative("mEventName");
  160.         SerializedProperty targetProp = prop.FindPropertyRelative("mTarget");
  161.         SerializedProperty methodProp = prop.FindPropertyRelative("mMethodName");
  162.  
  163.         SerializedProperty updateMethodsProp = prop.FindPropertyRelative("mUpdateEntryList");
  164.        
  165.         if (EditorApplication.isCompiling)
  166.             updateMethodsProp.boolValue = true;
  167.  
  168.         string eventName = nameProp.stringValue;
  169.         UnityEngine.Object target = targetProp.objectReferenceValue;
  170.  
  171.         //controls
  172.         Rect tempRect = new Rect(rect.x, rect.y, rect.width, lineHeight);
  173.         showGroup.boolValue = EditorGUI.Foldout(tempRect, showGroup.boolValue, label, true);
  174.  
  175.         if (showGroup.boolValue)
  176.         {
  177.             EditorGUI.indentLevel++;
  178.  
  179.             lineRect = rect;
  180.             lineRect.yMin = rect.yMin + lineHeight;
  181.             lineRect.yMax = lineRect.yMin + lineHeight;
  182.            
  183.             eventName = EditorGUI.TextField(lineRect, eventName);
  184.             nameProp.stringValue = eventName;
  185.            
  186.             lineRect.yMin += lineHeight;
  187.             lineRect.yMax += lineHeight;
  188.            
  189.             target = EditorGUI.ObjectField(lineRect, "Notify", target, typeof(UnityEngine.Object), true);
  190.  
  191.             lineRect.yMin += lineHeight;
  192.             lineRect.yMax += lineHeight;
  193.  
  194.             //painting manual refresh icon
  195.             tempRect = lineRect;
  196.             tempRect.xMin = lineRect.width + mIconSize - 4;
  197.             tempRect.height -= 1;
  198.  
  199.             if (mRefreshIconStyle == null)
  200.             {
  201.                 mRefreshIconStyle = new GUIStyle();
  202.  
  203.                 if (mRefreshIcon == null)
  204.                 {
  205.                     mRefreshIcon = Resources.Load<Texture2D>("refresh_icon");
  206.                 }
  207.  
  208.                 if (mRefreshIcon != null)
  209.                 {
  210.                     mRefreshIconStyle.normal.background = mRefreshIcon;
  211.                 }
  212.             }
  213.  
  214.             if (GUI.Button(tempRect, mRefreshIcon))
  215.             {
  216.                 updateMethodsProp.boolValue = true;
  217.             }
  218.  
  219.             //update method list if target component was modified
  220.             if (targetProp.objectReferenceValue != target)
  221.                 updateMethodsProp.boolValue = true;
  222.  
  223.             targetProp.objectReferenceValue = target;
  224.  
  225.             //checking for notify target
  226.             if (target != null)
  227.             {
  228.                 if (!_methodCache.ContainsKey(prop.propertyPath))
  229.                     _methodCache.Add(prop.propertyPath, new List<Entry>());
  230.                 List<Entry> listWithParams = _methodCache[prop.propertyPath];
  231.                
  232.                 SerializedProperty entryArrayProp = prop.FindPropertyRelative("mEntryList");
  233.  
  234.                 if (updateMethodsProp.boolValue && EditorApplication.isCompiling == false)
  235.                 {
  236.                     GameObject go = target as GameObject;
  237.                     if (go == null)
  238.                     {
  239.                         Component component = target as Component;
  240.                         if (target)
  241.                         {
  242.                             UpdateMethods (listWithParams, entryArrayProp, updateMethodsProp, component.gameObject);
  243.                         }
  244.                     }
  245.                     else
  246.                     {
  247.                         UpdateMethods (listWithParams, entryArrayProp, updateMethodsProp, go);
  248.                     }
  249.  
  250.                     _methodCache[prop.propertyPath] = listWithParams;
  251.                 }
  252.                 else if (!prop.serializedObject.isEditingMultipleObjects && listWithParams.Count == 0)
  253.                 {
  254.                     //get list from array
  255.                     listWithParams = new List<Entry>();
  256.                     SerializedProperty entryItem;
  257.  
  258.                     SerializedProperty itemTarget = null;
  259.                     string name = String.Empty;
  260.                     UnityEngine.Object targetComp = null;
  261.  
  262.                     int arraySize = entryArrayProp.arraySize;
  263.                     for (int i = 0; i < arraySize; i++, entryItem = null, itemTarget = null,
  264.                                                     name = String.Empty, targetComp = null)
  265.                     {
  266.                         entryItem = entryArrayProp.GetArrayElementAtIndex(i);
  267.  
  268.                         if (entryItem == null)
  269.                             continue;
  270.  
  271.                         itemTarget = entryItem.FindPropertyRelative("target");
  272.  
  273.                         if (itemTarget == null)
  274.                             continue;
  275.  
  276.                         targetComp = itemTarget.objectReferenceValue;
  277.                         name = entryItem.FindPropertyRelative("name").stringValue;
  278.                        
  279.                         listWithParams.Add(new Entry(targetComp, name));
  280.                     }
  281.                     _methodCache[prop.propertyPath] = listWithParams;
  282.                 }
  283.    
  284.                 int index = 0;
  285.                 int choice = 0;
  286.                
  287.                 string methodName = methodProp.stringValue;
  288.                
  289.                 //check and trim missing method message here
  290.                 if (methodName.StartsWith("<Missing - ") == true)
  291.                 {
  292.                     methodName = methodName.Replace("<Missing - ", "");
  293.                     methodName = methodName.Replace(">", "");
  294.                 }
  295.  
  296.                 string[] names = GetNames(listWithParams, methodName, true, out index, methodProp);
  297.  
  298.                 //painting event list popup
  299.                 tempRect = lineRect;
  300.                 tempRect.xMax -= mIconSize;
  301.                 choice = EditorGUI.Popup(tempRect, "Event", index, names);
  302.    
  303.                 //saving selected method or field
  304.                 if (choice > 0) //&& choice != index
  305.                 {
  306.                     Entry entry = listWithParams [choice - 1];
  307.                    
  308.                     if(target != entry.target)
  309.                     {
  310.                         target = entry.target as UnityEngine.Object;
  311.                         targetProp.objectReferenceValue = target;
  312.  
  313.                         SerializedProperty cacheProp = prop.FindPropertyRelative("mCached");
  314.                         cacheProp.boolValue = false;
  315.                     }
  316.                    
  317.                     methodName = entry.name;
  318.                    
  319.                     //remove params
  320.                     if (string.IsNullOrEmpty(methodName) == false && methodName.Contains(" ("))
  321.                         methodName = methodName.Remove(methodName.IndexOf(" ("));
  322.                    
  323.                     if(methodName != methodProp.stringValue)
  324.                     {
  325.                         methodProp.stringValue = methodName;
  326.                         entry.name = methodName;
  327.  
  328.                         SerializedProperty cacheProp = prop.FindPropertyRelative("mCached");
  329.                         cacheProp.boolValue = false;
  330.                     }
  331.                 }
  332.  
  333.                 eventDelegate.target = target;
  334.                 eventDelegate.methodName = methodName;
  335.                
  336.                 //showing if method or field is missing
  337.                 if (eventDelegate.isValid == false)
  338.                 {
  339.                     if (methodName.StartsWith("<Missing - ") == false)
  340.                         methodName = "<Missing - " + methodName + ">";
  341.                    
  342.                     methodProp.stringValue = methodName;
  343.                
  344.                     EditorGUI.indentLevel = indent;
  345.                     EditorGUI.EndProperty();
  346.                     return;
  347.                 }
  348.  
  349.                 //showing parameters
  350.                 SerializedProperty paramArrayProp = prop.FindPropertyRelative("mParameters");
  351.                 EventDelegate.Parameter[] ps = eventDelegate.parameters;
  352.  
  353.                 if (ps != null)
  354.                 {
  355.                     bool showGameObject = false;
  356.  
  357.                     float paramTypeWidth = 84;
  358.                     float lineOriginalMax = lineRect.xMax;
  359.                     lineRect.xMax -= 68;
  360.  
  361.                     int imax = ps.Length;
  362.                     paramArrayProp.arraySize = imax;
  363.                     for (int i = 0; i < imax; i++)
  364.                     {
  365.                         EventDelegate.Parameter param = ps [i];
  366.                         SerializedProperty paramProp = paramArrayProp.GetArrayElementAtIndex(i);
  367.                        
  368.                         SerializedProperty objProp = paramProp.FindPropertyRelative("obj");
  369.                         SerializedProperty fieldProp = paramProp.FindPropertyRelative("field");
  370.  
  371.                         param.obj = objProp.objectReferenceValue;
  372.                         param.field = fieldProp.stringValue;
  373.  
  374.                         lineRect.yMin += lineHeight;
  375.                         lineRect.yMax += lineHeight;
  376.  
  377.                         //showing param info
  378.                         string paramDesc = GetSimpleName(param.expectedType);
  379.                         paramDesc += " " + param.name;
  380.  
  381.                         //paint value/reference selection for primitive types
  382.                         if (IsPrimitiveType(param.expectedType))
  383.                         {
  384.                             if(lineOriginalMax == lineRect.xMax)
  385.                                 lineRect.xMax -= 68;
  386.  
  387.                             //only do this if parameter is a primitive type
  388.                             tempRect.x = lineRect.x + lineRect.width - 12;
  389.                             tempRect.y = lineRect.y;
  390.                             tempRect.width = paramTypeWidth;
  391.                             tempRect.height = lineHeight;
  392.  
  393.                             SerializedProperty paramTypeProp = paramProp.FindPropertyRelative("paramRefType");
  394.  
  395.                             //draw param type option
  396.                             EditorGUI.PropertyField(tempRect, paramTypeProp, GUIContent.none);
  397.                             param.paramRefType = (ParameterType)paramTypeProp.enumValueIndex;
  398.                         }
  399.                         else
  400.                         {
  401.                             lineRect.xMax = lineOriginalMax;
  402.                         }
  403.  
  404.                         bool useManualValue = paramProp.FindPropertyRelative("paramRefType").enumValueIndex == (int)ParameterType.Value;
  405.  
  406.                         if (useManualValue)
  407.                         {
  408.                             if (param.expectedType == typeof(string))
  409.                             {
  410.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argStringValue");
  411.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  412.  
  413.                                 param.value = valueProp.stringValue;
  414.                             }
  415.                             else if (param.expectedType == typeof(int))
  416.                             {
  417.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argIntValue");
  418.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  419.  
  420.                                 param.value = valueProp.intValue;
  421.                             }
  422.                             else if (param.expectedType == typeof(float))
  423.                             {
  424.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argFloatValue");
  425.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  426.  
  427.                                 param.value = valueProp.floatValue;
  428.                             }
  429.                             else if (param.expectedType == typeof(double))
  430.                             {
  431.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argDoubleValue");
  432.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  433.  
  434.                                 param.value = valueProp.doubleValue;
  435.                             }
  436.                             else if (param.expectedType == typeof(bool))
  437.                             {
  438.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argBoolValue");
  439.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  440.  
  441.                                 param.value = valueProp.boolValue;
  442.                             }
  443.                             else if (param.expectedType == typeof(Color))
  444.                             {
  445.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argColor");
  446.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  447.  
  448.                                 param.value = valueProp.colorValue;
  449.                             }
  450.                             else if (param.expectedType == typeof(Vector2))
  451.                             {
  452.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argVector2");
  453.                                 lineRect.y += 2;
  454.  
  455.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  456.  
  457.                                 param.value = valueProp.vector2Value;
  458.                             }
  459.                             else if (param.expectedType == typeof(Vector3))
  460.                             {
  461.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argVector3");
  462.                                 lineRect.y += 2;
  463.  
  464.                                 EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));
  465.  
  466.                                 param.value = valueProp.vector3Value;
  467.                             }
  468.                             else if (param.expectedType == typeof(Vector4))
  469.                             {
  470.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argVector4");
  471.                                 Vector4 vec4 = valueProp.vector4Value;
  472.  
  473.                                 lineRect.y += 2;
  474.  
  475.                                 //workaround for vector 4, it uses an extra line.
  476.                                 //valueProp.vector4Value = EditorGUI.Vector4Field(lineRect, paramDesc, valueProp.vector4Value);
  477.  
  478.                                 //create all this values just once
  479.                                 if (vec4Values == null)
  480.                                     vec4Values = new float[4];
  481.  
  482.                                 vec4Values[0] = vec4.x;
  483.                                 vec4Values[1] = vec4.y;
  484.                                 vec4Values[2] = vec4.z;
  485.                                 vec4Values[3] = vec4.w;
  486.  
  487.                                 if (vec4GUIContent == null)
  488.                                     vec4GUIContent = new GUIContent[4];
  489.  
  490.                                 vec4GUIContent[0] = new GUIContent("X");
  491.                                 vec4GUIContent[1] = new GUIContent("Y");
  492.                                 vec4GUIContent[2] = new GUIContent("Z");
  493.                                 vec4GUIContent[3] = new GUIContent("W");
  494.  
  495.                                 EditorGUI.LabelField(lineRect, paramDesc);
  496.  
  497.                                 tempRect = lineRect;
  498.                                 tempRect.xMin += (EditorGUI.indentLevel * lineHeight) + 86;
  499.  
  500.                                 EditorGUI.MultiFloatField(tempRect, vec4GUIContent, vec4Values);
  501.  
  502.                                 valueProp.vector4Value = new Vector4(vec4Values[0], vec4Values[1], vec4Values[2], vec4Values[3]);
  503.                                 param.value = valueProp.vector4Value;
  504.                             }
  505.                             else if (param.expectedType.IsEnum)
  506.                             {
  507.                                 SerializedProperty valueProp = paramProp.FindPropertyRelative("argIntValue");
  508.  
  509.                                 if (param.expectedType.GetAttribute<FlagsAttribute>() != null)
  510.                                 {
  511.                                     param.value = EditorGUI.MaskField(lineRect, new GUIContent(paramDesc), valueProp.intValue, Enum.GetNames(param.expectedType));
  512.                                 }
  513.                                 else
  514.                                 {
  515.                                     Enum selectedOpt = (Enum)Enum.ToObject(param.expectedType, valueProp.intValue);
  516.                                     param.value = EditorGUI.EnumPopup(lineRect, new GUIContent(paramDesc), selectedOpt);
  517.                                 }
  518.  
  519.                                 valueProp.intValue = (int)param.value;
  520.                             }
  521.                             else
  522.                             {
  523.                                 showGameObject = true;
  524.                             }
  525.                         }
  526.  
  527.                         if(showGameObject || !useManualValue)
  528.                         {
  529.                             UnityEngine.Object obj = param.obj;
  530.  
  531.                             obj = EditorGUI.ObjectField(lineRect, paramDesc, obj, typeof(UnityEngine.Object), true);
  532.  
  533.                             param.obj = obj;
  534.                             objProp.objectReferenceValue = obj;
  535.  
  536.                             if (obj == null)
  537.                                 continue;
  538.  
  539.                             //show gameobject
  540.                             GameObject selGO = null;
  541.                             System.Type type = param.obj.GetType();
  542.                             if (type == typeof(GameObject))
  543.                                 selGO = param.obj as GameObject;
  544.                             else if (type.IsSubclassOf(typeof(Component)))
  545.                                 selGO = (param.obj as Component).gameObject;
  546.  
  547.                             if (selGO != null)
  548.                             {
  549.                                 // Parameters must be exact -- they can't be converted like property bindings
  550.                                 filter = param.expectedType;
  551.                                 canConvert = false;
  552.                                 List<Entry> ents = GetProperties(selGO, true, false);
  553.  
  554.                                 int selection;
  555.                                 string[] props = GetNames(ents, EventDelegate.GetFuncName(param.obj, param.field), false, out selection);
  556.  
  557.                                 lineRect.yMin += lineHeight;
  558.                                 lineRect.yMax += lineHeight;
  559.                                 int newSel = EditorGUI.Popup(lineRect, " ", selection, props);
  560.  
  561.                                 if (newSel != selection)
  562.                                 {
  563.                                     if (newSel == 0)
  564.                                     {
  565.                                         param.obj = selGO;
  566.                                         param.field = null;
  567.  
  568.                                         objProp.objectReferenceValue = selGO;
  569.                                         fieldProp.stringValue = null;
  570.                                     }
  571.                                     else
  572.                                     {
  573.                                         param.obj = ents[newSel - 1].target;
  574.                                         param.field = ents[newSel - 1].name;
  575.  
  576.                                         objProp.objectReferenceValue = param.obj;
  577.                                         fieldProp.stringValue = param.field;
  578.                                     }
  579.                                 }
  580.                             }
  581.                             else if (!string.IsNullOrEmpty(param.field))
  582.                                 param.field = null;
  583.  
  584.                             filter = typeof(void);
  585.                             canConvert = true;
  586.                         }
  587.  
  588.                         showGameObject = false;
  589.                     }
  590.                 }
  591.             }
  592.         }
  593.        
  594.         EditorGUI.indentLevel = indent;
  595.         EditorGUI.EndProperty();
  596.     }
  597.    
  598.     /// <summary>
  599.     /// Updates the methods list and property array cache from the selected GameObject.
  600.     /// </summary>
  601.  
  602.     void UpdateMethods(List<Entry> listWithParams, SerializedProperty entryArrayProp, SerializedProperty updateMethodsProp, GameObject go)
  603.     {
  604.         if (entryArrayProp == null)
  605.             return;
  606.  
  607.         if(go == null)
  608.         {
  609.             entryArrayProp.ClearArray();
  610.             return;
  611.         }
  612.  
  613.         listWithParams = GetMethods(go, true);
  614.         entryArrayProp.ClearArray();
  615.         SerializedProperty entryProp;
  616.        
  617.         //update serialized entries
  618.         Entry entryItem = null;
  619.         for (int ind = 0, length = listWithParams.Count; ind < length; ++ind, entryItem = null)
  620.         {
  621.             entryItem = listWithParams[ind];
  622.             if(entryItem != null)
  623.             {
  624.                 if (entryArrayProp.arraySize == 0)
  625.                 {
  626.                     entryArrayProp.InsertArrayElementAtIndex(0);
  627.                     entryProp = entryArrayProp.GetArrayElementAtIndex(0);
  628.                 }
  629.                 else
  630.                 {
  631.                     entryArrayProp.InsertArrayElementAtIndex(entryArrayProp.arraySize - 1);
  632.                     entryProp = entryArrayProp.GetArrayElementAtIndex(entryArrayProp.arraySize - 1);
  633.                 }
  634.  
  635.                 entryProp.FindPropertyRelative("target").objectReferenceValue = entryItem.target;
  636.                 entryProp.FindPropertyRelative("name").stringValue = entryItem.name;
  637.             }
  638.         }
  639.        
  640.         updateMethodsProp.boolValue = false;
  641.     }
  642.    
  643.     /// <summary>
  644.     /// Convert the specified list of delegate entries into a string array.
  645.     /// </summary>
  646.    
  647.     static public string[] GetNames(List<Entry> list, string choice, bool includeParams, out int index, SerializedProperty methodProp = null)
  648.     {
  649.         index = 0;
  650.  
  651.         if (list == null)
  652.             return new string[0];
  653.        
  654.         string[] names = new string[list.Count + 1];
  655.         names [0] = "<Choose>";
  656.        
  657.         Entry entry = null;
  658.         int imax = list.Count;
  659.         for (int i = 0; i < imax; entry = null)
  660.         {
  661.             entry = list [i];
  662.  
  663.             if(entry == null)
  664.                 continue;
  665.            
  666.             //check if comes with params and remove
  667.             string del = entry.name;
  668.             string methodName = "";
  669.            
  670.             if (string.IsNullOrEmpty(del) == false && del.Contains(" ("))
  671.                 methodName = del.Remove(del.IndexOf(" ("));
  672.             else
  673.                 methodName = del;
  674.            
  675.             del = EventDelegate.GetFuncName(entry.target, del);
  676.            
  677.             if (includeParams)
  678.                 names [++i] = EventDelegate.GetFuncName(entry.target, entry.name);
  679.             else
  680.                 names [++i] = del;
  681.            
  682.             if (index == 0)
  683.             {
  684.                 if (choice == methodName)
  685.                     index = i;
  686.                 else if (string.Equals(del, choice))
  687.                     index = i;
  688.             }
  689.         }
  690.  
  691.         if (index != 0)
  692.         {
  693.             if (names[index].Contains(" ("))
  694.                 names[index] = names[index].Remove(names[index].IndexOf(" ("));
  695.  
  696.         }
  697.         else if (methodProp != null && methodProp.stringValue.StartsWith("<Missing - "))
  698.         {
  699.             names[0] = methodProp.stringValue;
  700.         }
  701.        
  702.         return names;
  703.     }
  704.    
  705.     /// <summary>
  706.     /// Returns only the name from a given type.
  707.     /// </summary>
  708.    
  709.     static public string GetSimpleName(System.Type type)
  710.     {
  711.         if (type == null)
  712.             return "";
  713.        
  714.         string name = type.ToString();
  715.        
  716.         return name.Substring(name.LastIndexOf('.') + 1);
  717.     }
  718.  
  719.     static public bool IsPrimitiveType(Type expectedType)
  720.     {
  721.         if(expectedType == typeof(string) || expectedType == typeof(int) || expectedType == typeof(float) || expectedType == typeof(double) ||
  722.             expectedType == typeof(bool) || expectedType == typeof(Vector2) || expectedType == typeof(Vector3) || expectedType == typeof(Vector4) ||
  723.             expectedType == typeof(Color) || expectedType.IsEnum)
  724.         {
  725.             return true;
  726.         }
  727.  
  728.         return false;
  729.     }
  730.    
  731.     #if REFLECTION_SUPPORT
  732.    
  733.     /// <summary>
  734.     /// Whether we can assign the property using the specified value.
  735.     /// </summary>
  736.    
  737.     bool Convert (ref object value)
  738.     {
  739.         if (mTarget == null) return false;
  740.        
  741.         Type to = GetPropertyType();
  742.         Type from;
  743.        
  744.         if (value == null)
  745.         {
  746.             #if NETFX_CORE
  747.             if (!to.GetTypeInfo().IsClass) return false;
  748.             #else
  749.             if (!to.IsClass) return false;
  750.             #endif
  751.             from = to;
  752.         }
  753.         else from = value.GetType();
  754.         return Convert(ref value, from, to);
  755.     }
  756.     #else // Everything below = no reflection support
  757.     bool Convert(ref object value)
  758.     {
  759.         return false;
  760.     }
  761.     #endif
  762.    
  763.     /// <summary>
  764.     /// Whether we can convert one type to another for assignment purposes.
  765.     /// </summary>
  766.    
  767.     static public bool Convert(Type from, Type to)
  768.     {
  769.         object temp = null;
  770.         return Convert(ref temp, from, to);
  771.     }
  772.    
  773.     /// <summary>
  774.     /// Whether we can convert one type to another for assignment purposes.
  775.     /// </summary>
  776.    
  777.     static public bool Convert(object value, Type to)
  778.     {
  779.         if (value == null)
  780.         {
  781.             value = null;
  782.             return Convert(ref value, to, to);
  783.         }
  784.         return Convert(ref value, value.GetType(), to);
  785.     }
  786.    
  787.     /// <summary>
  788.     /// Whether we can convert one type to another for assignment purposes.
  789.     /// </summary>
  790.    
  791.     static public bool Convert(ref object value, Type from, Type to)
  792.     {
  793.         #if REFLECTION_SUPPORT
  794.         // If the value can be assigned as-is, we're done
  795.         #if NETFX_CORE
  796.         if (to.GetTypeInfo().IsAssignableFrom(from.GetTypeInfo())) return true;
  797.         #else
  798.         if (to.IsAssignableFrom(from)) return true;
  799.         #endif
  800.        
  801.         #else
  802.         if (from == to)
  803.             return true;
  804.         #endif
  805.         // If the target type is a string, just convert the value
  806.         if (to == typeof(string))
  807.         {
  808.             value = (value != null) ? value.ToString() : "null";
  809.             return true;
  810.         }
  811.        
  812.         // If the value is null we should not proceed further
  813.         if (value == null)
  814.             return false;
  815.        
  816.         if (to == typeof(int))
  817.         {
  818.             if (from == typeof(string))
  819.             {
  820.                 int val;
  821.                
  822.                 if (int.TryParse((string)value, out val))
  823.                 {
  824.                     value = val;
  825.                     return true;
  826.                 }
  827.             }
  828.             else if (from == typeof(float))
  829.             {
  830.                 value = Mathf.RoundToInt((float)value);
  831.                 return true;
  832.             }
  833.         }
  834.         else if (to == typeof(float))
  835.         {
  836.             if (from == typeof(string))
  837.             {
  838.                 float val;
  839.                
  840.                 if (float.TryParse((string)value, out val))
  841.                 {
  842.                     value = val;
  843.                     return true;
  844.                 }
  845.             }
  846.         }
  847.         return false;
  848.     }
  849.    
  850.     /// <summary>
  851.     /// Collect a list of usable delegates from the specified target game object.
  852.     /// </summary>
  853.    
  854.     static public List<Entry> GetMethods(GameObject target, bool includeParams = false)
  855.     {
  856.         List<Entry> list = new List<Entry>();
  857.        
  858.         if (target == null)
  859.             return list;
  860.  
  861.         //obtaining methods to show in list
  862.         Component[] comps = target.GetComponents<Component>();
  863.         MethodInfo[] methods = null;
  864.  
  865.         Component comp = null;
  866.         for (int i = 0, imax = comps.Length; i < imax; ++i, comp = null)
  867.         {
  868.             comp = comps [i];
  869.             if (comp == null)
  870.                 continue;
  871.            
  872.             methods = comp.GetType().GetMethods(EventDelegate.MethodFlags);
  873.            
  874.             MethodInfo mi = null;
  875.             for (int b = 0, len = methods.Length; b < len; ++b, mi = null)
  876.             {
  877.                 mi = methods [b];
  878.                
  879.                 if(mi != null)
  880.                     FilterMethods(mi, list, methods, comp, includeParams);
  881.             }
  882.         }
  883.  
  884.         //add GameObject methods
  885.         methods = target.GetType().GetMethods(EventDelegate.MethodFlags);
  886.         for (int b = 0, len = methods.Length; b < len; ++b)
  887.         {
  888.             MethodInfo mi = methods [b];
  889.            
  890.             FilterMethods(mi, list, methods, target, includeParams);
  891.         }
  892.  
  893.         list.Sort();
  894.  
  895.         List<Entry> fieldList = GetProperties(target, false, true);
  896.         fieldList.Sort();
  897.  
  898.         //obtaining properties and fields to show in list
  899.         fieldList.AddRange(list);
  900.        
  901.         return fieldList;
  902.     }
  903.  
  904.     /// <summary>
  905.     /// Filter the available methods to show.
  906.     /// </summary>
  907.  
  908.     static public void FilterMethods(MethodInfo mi, List<Entry> list, MethodInfo[] methods, UnityEngine.Object target, bool includeParams)
  909.     {
  910.         //filter methods
  911.         string name = mi.Name;
  912.  
  913.         if (name == "obj_address")
  914.             return;
  915.         if (name == "MemberwiseClone")
  916.             return;
  917.         if (name == "Finalize")
  918.             return;
  919.         if (name == "Invoke")
  920.             return;
  921.         if (name == "InvokeRepeating")
  922.             return;
  923.         if (name == "CancelInvoke")
  924.             return;
  925.         if (name == "BroadcastMessage")
  926.             return;
  927.         if (name == "Equals")
  928.             return;
  929.         if (name == "CompareTag")
  930.             return;
  931.         if (name == "ToString")
  932.             return;
  933.         if (name == "GetType")
  934.             return;
  935.         if (name == "GetHashCode")
  936.             return;
  937.         if (name == "GetInstanceID")
  938.             return;
  939.         if (name.StartsWith("StartCoroutine"))
  940.             return;
  941.         if (name.StartsWith("StopCoroutine"))
  942.             return;
  943.         //if (name.StartsWith("StopAllCoroutines"))
  944.         //    return;
  945.         if (name.StartsWith("set_"))
  946.             return;
  947.         if (name.StartsWith("get_"))
  948.             return;
  949.         if (name.StartsWith("GetComponent"))
  950.             return;
  951.         if (name.StartsWith("SendMessage"))
  952.             return;
  953.         if (name.Contains("INTERNAL_"))
  954.             return;
  955.  
  956.         Entry entry = new Entry(target, name);
  957.  
  958.         if (ExistOverloadedMethod(methods, entry))
  959.             return;
  960.  
  961.         if (includeParams)
  962.         {
  963.             ParameterInfo[] parameters = mi.GetParameters();
  964.  
  965.             entry.name += " (";
  966.             if (parameters != null && parameters.Length > 0)
  967.             {                    
  968.                 int count = 0;
  969.                 ParameterInfo paramInfo = null;
  970.                 for (int ind = 0, length = parameters.Length; ind < length; ++ind, paramInfo = null)
  971.                 {
  972.                     paramInfo = parameters[ind];
  973.                     if(paramInfo != null)
  974.                     {
  975.                         entry.name += GetSimpleName(paramInfo.ParameterType) + " " + paramInfo.Name;
  976.                         count++;
  977.  
  978.                         //adding for next param
  979.                         if (count < parameters.Length)
  980.                             entry.name += ", ";
  981.                     }
  982.                 }
  983.             }
  984.             entry.name += ")";
  985.         }
  986.  
  987.         list.Add(entry);
  988.     }
  989.    
  990.     /// <summary>
  991.     /// Collect a list of usable properties and fields.
  992.     /// </summary>
  993.    
  994.     static public List<Entry> GetProperties(GameObject target, bool read, bool write)
  995.     {
  996.         Component[] comps = target.GetComponents<Component>();
  997.        
  998.         List<Entry> list = new List<Entry>();
  999.         Component comp = null;
  1000.         for (int i = 0, imax = comps.Length; i < imax; ++i, comp = null)
  1001.         {
  1002.             comp = comps [i];
  1003.             if (comp == null)
  1004.                 continue;
  1005.            
  1006.             AddProperties(list, comp, read, write);
  1007.         }
  1008.  
  1009.         AddProperties(list, target, read, write);
  1010.  
  1011.         return list;
  1012.     }
  1013.  
  1014.     static private void AddProperties(List<Entry> list, UnityEngine.Object comp, bool read, bool write)
  1015.     {
  1016.         Type type = comp.GetType();
  1017.         BindingFlags flags = EventDelegate.FieldFlags;
  1018.         FieldInfo[] fields = type.GetFields(flags);
  1019.         PropertyInfo[] props = type.GetProperties(flags);
  1020.        
  1021.         // The component itself without any method
  1022.         if (read && Convert(comp, filter))
  1023.         {
  1024.             Entry ent = new Entry();
  1025.             ent.target = comp;
  1026.            
  1027.             if (list.Contains(ent) == false)
  1028.                 list.Add(ent);
  1029.         }
  1030.        
  1031.         for (int b = 0, ilen = fields.Length; b < ilen; ++b)
  1032.         {
  1033.             FieldInfo field = fields [b];
  1034.            
  1035.             if (filter != typeof(void))
  1036.             {
  1037.                 if (canConvert)
  1038.                 {
  1039.                     if (!Convert(field.FieldType, filter))
  1040.                         continue;
  1041.                 }
  1042.                 else if (!filter.IsAssignableFrom(field.FieldType))
  1043.                     continue;
  1044.             }
  1045.            
  1046.             Entry ent = new Entry(comp, field.Name);
  1047.             list.Add(ent);
  1048.         }
  1049.        
  1050.         for (int b = 0, ilen = props.Length; b < ilen; ++b)
  1051.         {
  1052.             PropertyInfo prop = props [b];
  1053.             if (read && !prop.CanRead)
  1054.                 continue;
  1055.             if (write && !prop.CanWrite)
  1056.                 continue;
  1057.  
  1058.             if (filter != typeof(void))
  1059.             {
  1060.                 if (canConvert)
  1061.                 {
  1062.                     if (!Convert(prop.PropertyType, filter))
  1063.                         continue;
  1064.                 }
  1065.                 else if (!filter.IsAssignableFrom(prop.PropertyType))
  1066.                     continue;
  1067.             }
  1068.            
  1069.             Entry ent = new Entry(comp, prop.Name);
  1070.             list.Add(ent);
  1071.         }
  1072.     }
  1073.  
  1074.     /// <summary>
  1075.     /// Returns if an overloaded method exists in an array of functions.
  1076.     /// </summary>
  1077.  
  1078.     static public bool ExistOverloadedMethod(MethodInfo[] methodArray, Entry entry)
  1079.     {
  1080.         if (methodArray == null || methodArray.Length <= 0 || entry == null || string.IsNullOrEmpty(entry.name))
  1081.             return false;
  1082.    
  1083.         string method = entry.name;
  1084.        
  1085.         if (method.Contains(" ("))
  1086.             method = method.Remove(method.IndexOf(" ("));
  1087.        
  1088.         int count = 0;
  1089.         MethodInfo methodInfo = null;
  1090.         for (int i = 0, imax = methodArray.Length; i < imax; ++i, methodInfo = null)
  1091.         {
  1092.             methodInfo = methodArray[i];
  1093.             if (methodInfo != null && methodInfo.Name.Equals(method))
  1094.             {
  1095.                 if (count > 0)
  1096.                     return true;
  1097.                 else
  1098.                     count++;
  1099.             }
  1100.         }
  1101.        
  1102.         return false;
  1103.     }
  1104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement