Esempio n. 1
0
    public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label)
    {
        Undo.RecordObject(prop.serializedObject.targetObject, "Delegate Selection");

        EditorGUI.BeginProperty(rect, label, prop);
        int indent = EditorGUI.indentLevel;

        SerializedProperty showGroup = prop.FindPropertyRelative("mShowGroup");

        SerializedProperty nameProp   = prop.FindPropertyRelative("mEventName");
        SerializedProperty targetProp = prop.FindPropertyRelative("mTarget");
        SerializedProperty methodProp = prop.FindPropertyRelative("mMethodName");

        SerializedProperty updateMethodsProp = prop.FindPropertyRelative("mUpdateEntryList");

        if (EditorApplication.isCompiling)
        {
            updateMethodsProp.boolValue = true;
        }

        string eventName = nameProp.stringValue;

        UnityEngine.Object target = targetProp.objectReferenceValue;

        //controls
        Rect groupPos = new Rect(rect.x + 5, rect.y + 2, rect.width, ThunderEventDrawerTools.lineHeight);

        showGroup.boolValue = EditorGUI.Foldout(groupPos, showGroup.boolValue, label);

        if (showGroup.boolValue)
        {
            EditorGUI.indentLevel++;

            lineRect      = rect;
            lineRect.yMin = rect.yMin + ThunderEventDrawerTools.lineHeight;
            lineRect.yMax = lineRect.yMin + ThunderEventDrawerTools.lineHeight;

            eventName            = EditorGUI.TextField(lineRect, eventName);
            nameProp.stringValue = eventName;

            lineRect.yMin += ThunderEventDrawerTools.lineHeight;
            lineRect.yMax += ThunderEventDrawerTools.lineHeight;

            target = EditorGUI.ObjectField(lineRect, "Notify", target, typeof(UnityEngine.Object), true);

            //update method list if target component was modified
            if (targetProp.objectReferenceValue != target)
            {
                updateMethodsProp.boolValue = true;
            }

            targetProp.objectReferenceValue = target;

            if (target != null)
            {
                List <Entry> listWithParams = null;

                SerializedProperty entryArrayProp = prop.FindPropertyRelative("mEntryList");

                if (updateMethodsProp.boolValue && EditorApplication.isCompiling == false)
                {
                    GameObject go = target as GameObject;
                    if (go == null)
                    {
                        Component component = target as Component;
                        if (target)
                        {
                            UpdateMethods(listWithParams, entryArrayProp, updateMethodsProp, component.gameObject);
                        }
                    }
                    else
                    {
                        UpdateMethods(listWithParams, entryArrayProp, updateMethodsProp, go);
                    }
                }
                else
                {
                    //get list from array
                    listWithParams = new List <Entry>();
                    SerializedProperty entryItem;

                    int arraySize = entryArrayProp.arraySize;
                    for (int i = 0; i < arraySize; i++, entryItem = null)
                    {
                        entryItem = entryArrayProp.GetArrayElementAtIndex(i);

                        if (entryItem == null)
                        {
                            continue;
                        }

                        UnityEngine.Object targetComp = entryItem.FindPropertyRelative("target").objectReferenceValue;
                        string             name       = entryItem.FindPropertyRelative("name").stringValue;

                        listWithParams.Add(new Entry(targetComp, name));
                    }
                }

                int index  = 0;
                int choice = 0;

                string methodName = methodProp.stringValue;

                //check and trim missing method message here
                if (methodName.StartsWith("<Missing - ") == true)
                {
                    methodName = methodName.Replace("<Missing - ", "");
                    methodName = methodName.Replace(">", "");
                }

                string[] names = GetNames(listWithParams, ThunderEvent.GetClassName(target), methodName, true, out index, methodProp);

                lineRect.yMin += ThunderEventDrawerTools.lineHeight;
                lineRect.yMax += ThunderEventDrawerTools.lineHeight;

                choice = EditorGUI.Popup(lineRect, "Event", index, names);

                //saving selected method or field

                if (choice > 0 && choice != index)
                {
                    Entry entry = listWithParams [choice - 1];

                    if (target != entry.target)
                    {
                        target = entry.target;
                        targetProp.objectReferenceValue = target;

                        SerializedProperty cacheProp = prop.FindPropertyRelative("mCached");
                        cacheProp.boolValue = false;
                    }

                    //Debug.Log(entry.target.name + "-" + entry.name);
                    methodName = entry.name;

                    //remove params
                    if (string.IsNullOrEmpty(methodName) == false && methodName.Contains(" ("))
                    {
                        methodName = methodName.Remove(methodName.IndexOf(" ("));
                    }

                    if (methodName != methodProp.stringValue)
                    {
                        methodProp.stringValue = methodName;
                        entry.name             = methodName;

                        SerializedProperty cacheProp = prop.FindPropertyRelative("mCached");
                        cacheProp.boolValue = false;
                    }
                }

                eventDelegate.target     = target;
                eventDelegate.methodName = methodName;

                //showing if method or field is missing
                if (eventDelegate.isValid == false)
                {
                    if (methodName.StartsWith("<Missing - ") == false)
                    {
                        methodName = "<Missing - " + methodName + ">";
                    }

                    methodProp.stringValue = methodName;

                    EditorGUI.indentLevel = indent;
                    EditorGUI.EndProperty();
                    return;
                }

                //showing parameters
                SerializedProperty       paramArrayProp = prop.FindPropertyRelative("mParameters");
                ThunderEvent.Parameter[] ps             = eventDelegate.parameters;

                if (ps != null)
                {
                    bool showGameObject = false;

                    //EditorGUI.indentLevel++;

                    float paramTypeWidth  = 80;
                    float lineOriginalMax = lineRect.xMax;
                    lineRect.xMax -= 68;

                    int imax = ps.Length;
                    paramArrayProp.arraySize = imax;
                    for (int i = 0; i < imax; i++)
                    {
                        ThunderEvent.Parameter param     = ps [i];
                        SerializedProperty     paramProp = paramArrayProp.GetArrayElementAtIndex(i);

                        SerializedProperty objProp   = paramProp.FindPropertyRelative("obj");
                        SerializedProperty fieldProp = paramProp.FindPropertyRelative("field");



                        param.obj   = objProp.objectReferenceValue;
                        param.field = fieldProp.stringValue;

                        lineRect.yMin += ThunderEventDrawerTools.lineHeight;
                        lineRect.yMax += ThunderEventDrawerTools.lineHeight;

                        //showing param info
                        string paramDesc = GetSimpleName(param.expectedType);
                        paramDesc += " " + param.name;

                        if (IsPrimitiveType(param.expectedType))
                        {
                            if (lineOriginalMax == lineRect.xMax)
                            {
                                lineRect.xMax -= 68;
                            }

                            //only do this if parameter is a primitive type
                            Rect paramTypeRect = new Rect(lineRect.x + lineRect.width - 12, lineRect.y, paramTypeWidth, ThunderEventDrawerTools.lineHeight);

                            SerializedProperty paramTypeProp = paramProp.FindPropertyRelative("paramRefType");

                            //draw param type option
                            EditorGUI.PropertyField(paramTypeRect, paramTypeProp, GUIContent.none);
                            param.paramRefType = (ParameterType)paramTypeProp.enumValueIndex;
                        }
                        else
                        {
                            lineRect.xMax = lineOriginalMax;
                        }

                        bool useManualValue = paramProp.FindPropertyRelative("paramRefType").enumValueIndex == (int)ParameterType.Value;

                        if (useManualValue)
                        {
                            if (param.expectedType == typeof(string))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argStringValue");
                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.stringValue;
                            }
                            else if (param.expectedType == typeof(int))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argIntValue");
                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.intValue;
                            }
                            else if (param.expectedType == typeof(float))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argFloatValue");
                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.floatValue;
                            }
                            else if (param.expectedType == typeof(double))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argDoubleValue");
                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.doubleValue;
                            }
                            else if (param.expectedType == typeof(bool))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argBoolValue");
                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.boolValue;
                            }
                            else if (param.expectedType == typeof(Color))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argColor");
                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.colorValue;
                            }
                            else if (param.expectedType == typeof(Vector2))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argVector2");
                                lineRect.y += 2;

                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.vector2Value;
                            }
                            else if (param.expectedType == typeof(Vector3))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argVector3");
                                lineRect.y += 2;

                                EditorGUI.PropertyField(lineRect, valueProp, new GUIContent(paramDesc));

                                param.value = valueProp.vector3Value;
                            }
                            else if (param.expectedType == typeof(Quaternion))
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argVector4");
                                Vector4            vec4      = valueProp.vector4Value;

                                lineRect.y += 2;

                                //workaround for vector 4, it uses an extra line.
                                //valueProp.vector4Value = EditorGUI.Vector4Field(lineRect, paramDesc, valueProp.vector4Value);

                                //create all this values just once
                                if (vec4Values == null)
                                {
                                    vec4Values = new float[4];
                                }

                                vec4Values[0] = vec4.x;
                                vec4Values[1] = vec4.y;
                                vec4Values[2] = vec4.z;
                                vec4Values[3] = vec4.w;

                                if (vec4GUIContent == null)
                                {
                                    vec4GUIContent = new GUIContent[4];
                                }

                                vec4GUIContent[0] = new GUIContent("X");
                                vec4GUIContent[1] = new GUIContent("Y");
                                vec4GUIContent[2] = new GUIContent("Z");
                                vec4GUIContent[3] = new GUIContent("W");

                                EditorGUI.LabelField(lineRect, paramDesc);

                                Rect vector4Line = new Rect(lineRect);
                                vector4Line.xMin += (EditorGUI.indentLevel * ThunderEventDrawerTools.lineHeight) + 150;

                                EditorGUI.MultiFloatField(vector4Line, vec4GUIContent, vec4Values);

                                valueProp.vector4Value = new Vector4(vec4Values[0], vec4Values[1], vec4Values[2], vec4Values[3]);
                                param.value            = valueProp.vector4Value;
                            }
                            else if (param.expectedType.IsEnum)
                            {
                                SerializedProperty valueProp = paramProp.FindPropertyRelative("argIntValue");

                                if (param.expectedType.GetAttribute <System.FlagsAttribute>() != null)
                                {
                                    param.value        = EditorGUI.MaskField(lineRect, new GUIContent(paramDesc), valueProp.intValue, Enum.GetNames(param.expectedType));
                                    valueProp.intValue = (int)param.value;
                                }
                                else
                                {
                                    Enum selectedOpt = (Enum)Enum.ToObject(param.expectedType, valueProp.intValue);
                                    param.value        = EditorGUI.EnumPopup(lineRect, new GUIContent(paramDesc), selectedOpt);
                                    valueProp.intValue = (int)param.value;
                                }
                            }
                            else
                            {
                                showGameObject = true;
                            }
                        }

                        if (showGameObject || !useManualValue)
                        {
                            UnityEngine.Object obj = param.obj;

                            obj = EditorGUI.ObjectField(lineRect, paramDesc, obj, typeof(UnityEngine.Object), true);

                            param.obj = obj;
                            objProp.objectReferenceValue = obj;

                            if (obj == null)
                            {
                                continue;
                            }

                            //show gameobject
                            GameObject  selGO = null;
                            System.Type type  = param.obj.GetType();
                            if (type == typeof(GameObject))
                            {
                                selGO = param.obj as GameObject;
                            }
                            else if (type.IsSubclassOf(typeof(Component)))
                            {
                                selGO = (param.obj as Component).gameObject;
                            }

                            if (selGO != null)
                            {
                                // Parameters must be exact -- they can't be converted like property bindings
                                filter     = param.expectedType;
                                canConvert = false;
                                List <Entry> ents = GetProperties(selGO, true, false);

                                int      selection = 0;
                                string[] props     = GetNames(ents, ThunderEvent.GetClassName(param.obj), ThunderEvent.GetFuncName(param.obj, param.field), false, out selection);

                                lineRect.yMin += ThunderEventDrawerTools.lineHeight;
                                lineRect.yMax += ThunderEventDrawerTools.lineHeight;
                                int newSel = EditorGUI.Popup(lineRect, " ", selection, props);

                                if (newSel != selection)
                                {
                                    if (newSel == 0)
                                    {
                                        param.obj   = selGO;
                                        param.field = null;

                                        objProp.objectReferenceValue = selGO;
                                        fieldProp.stringValue        = null;
                                    }
                                    else
                                    {
                                        param.obj   = ents[newSel - 1].target;
                                        param.field = ents[newSel - 1].name;

                                        objProp.objectReferenceValue = param.obj;
                                        fieldProp.stringValue        = param.field;
                                    }
                                }
                            }
                            else if (!string.IsNullOrEmpty(param.field))
                            {
                                param.field = null;
                            }

                            filter     = typeof(void);
                            canConvert = true;
                        }

                        showGameObject = false;
                    }
                }
            }
        }

        EditorGUI.indentLevel = indent;
        EditorGUI.EndProperty();
    }
Esempio n. 2
0
    /// <summary>
    /// Width value to start using minimalistic method.
    /// </summary>
    //int minimalistWidth = 0; //TODO: implement minimalistic method, unity activates it at 257

    public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
    {
        SerializedProperty showGroup = prop.FindPropertyRelative("mShowGroup");

        if (!showGroup.boolValue)
        {
            return(ThunderEventDrawerTools.lineHeight);
        }

        float lines = (3 * ThunderEventDrawerTools.lineHeight);

        SerializedProperty targetProp = prop.FindPropertyRelative("mTarget");

        if (targetProp.objectReferenceValue == null)
        {
            return(lines);
        }

        lines += ThunderEventDrawerTools.lineHeight;

        SerializedProperty methodProp = prop.FindPropertyRelative("mMethodName");

        if (methodProp.stringValue == "<Choose>" || methodProp.stringValue.StartsWith("<Missing - "))
        {
            return(lines);
        }

        eventDelegate.target     = targetProp.objectReferenceValue;
        eventDelegate.methodName = methodProp.stringValue;

        if (eventDelegate.isValid == false)
        {
            return(lines);
        }

        SerializedProperty paramArrayProp = prop.FindPropertyRelative("mParameters");

        ThunderEvent.Parameter[] ps = eventDelegate.parameters;

        if (ps != null)
        {
            ThunderEvent.Parameter param = null;

            int imax = ps.Length;
            paramArrayProp.arraySize = imax;
            for (int i = 0; i < imax; i++, param = null)
            {
                param = ps [i];

                lines += ThunderEventDrawerTools.lineHeight;

                SerializedProperty paramProp = paramArrayProp.GetArrayElementAtIndex(i);
                SerializedProperty objProp   = paramProp.FindPropertyRelative("obj");

                bool useManualValue = paramProp.FindPropertyRelative("paramRefType").enumValueIndex == (int)ParameterType.Value;

                if (useManualValue)
                {
                    if (param.expectedType == typeof(string) || param.expectedType == typeof(int) ||
                        param.expectedType == typeof(float) || param.expectedType == typeof(double) ||
                        param.expectedType == typeof(bool) || param.expectedType.IsEnum ||
                        param.expectedType == typeof(Color))
                    {
                        continue;
                    }
                    else if (param.expectedType == typeof(Vector2) || param.expectedType == typeof(Vector3) || param.expectedType == typeof(Vector4))
                    {
                        //if (lineRect.width < minimalistWidth) //use minimalist method
                        //{
                        //    if (param.expectedType == typeof(Vector2) || param.expectedType == typeof(Vector3))
                        //    {
                        //        lines += lineHeight;
                        //    }
                        //}
                        lines += 4;
                        continue;
                    }
                }

                UnityEngine.Object obj = objProp.objectReferenceValue;

                if (obj == null)
                {
                    continue;
                }

                System.Type type = obj.GetType();

                GameObject selGO = null;
                if (type == typeof(GameObject))
                {
                    selGO = obj as GameObject;
                }
                else if (type.IsSubclassOf(typeof(Component)))
                {
                    selGO = (obj as Component).gameObject;
                }

                if (selGO != null)
                {
                    lines += ThunderEventDrawerTools.lineHeight;
                }
            }
        }

        return(lines);
    }
Esempio n. 3
0
    /// <summary>
    /// The standard height size for each property line.
    /// </summary>


    private UnityEditorInternal.ReorderableList getList(SerializedProperty property)
    {
        if (list == null)
        {
            list = new ReorderableList(property.serializedObject, property, true, true, true, true);

            list.drawElementCallback = (UnityEngine.Rect rect, int index, bool isActive, bool isFocused) =>
            {
                rect.width -= 10;
                rect.x     += 8;

                SerializedProperty elemtProp = property.GetArrayElementAtIndex(index);

                if (EditorApplication.isCompiling)
                {
                    SerializedProperty updateMethodsProp = elemtProp.FindPropertyRelative("mUpdateEntryList");
                    if (updateMethodsProp != null)
                    {
                        updateMethodsProp.boolValue = true;
                    }
                }

                EditorGUI.PropertyField(rect, elemtProp, true);
            };

            list.elementHeightCallback = (index) =>
            {
                var element = property.GetArrayElementAtIndex(index);

                float yOffset = 12;

                SerializedProperty showGroup = element.FindPropertyRelative("mShowGroup");
                if (!showGroup.boolValue)
                {
                    return(ThunderEventDrawerTools.lineHeight + 1);
                }

                float lines = (3 * ThunderEventDrawerTools.lineHeight) + yOffset;

                SerializedProperty targetProp = element.FindPropertyRelative("mTarget");
                if (targetProp.objectReferenceValue == null)
                {
                    return(lines);
                }

                lines += ThunderEventDrawerTools.lineHeight;

                SerializedProperty methodProp = element.FindPropertyRelative("mMethodName");

                if (methodProp.stringValue == "<Choose>" || methodProp.stringValue.StartsWith("<Missing - "))
                {
                    return(lines);
                }

                eventDelegate.target     = targetProp.objectReferenceValue;
                eventDelegate.methodName = methodProp.stringValue;

                if (eventDelegate.isValid == false)
                {
                    return(lines);
                }

                SerializedProperty       paramArrayProp = element.FindPropertyRelative("mParameters");
                ThunderEvent.Parameter[] ps             = eventDelegate.parameters;

                if (ps != null)
                {
                    int imax = ps.Length;
                    paramArrayProp.arraySize = imax;
                    for (int i = 0; i < imax; i++)
                    {
                        ThunderEvent.Parameter param = ps[i];

                        lines += ThunderEventDrawerTools.lineHeight;

                        SerializedProperty paramProp = paramArrayProp.GetArrayElementAtIndex(i);
                        SerializedProperty objProp   = paramProp.FindPropertyRelative("obj");

                        bool useManualValue = paramProp.FindPropertyRelative("paramRefType").enumValueIndex == (int)ParameterType.Value;

                        if (useManualValue)
                        {
                            if (param.expectedType == typeof(string) || param.expectedType == typeof(int) ||
                                param.expectedType == typeof(float) || param.expectedType == typeof(double) ||
                                param.expectedType == typeof(bool) || param.expectedType.IsEnum ||
                                param.expectedType == typeof(Color))
                            {
                                continue;
                            }
                            else if (param.expectedType == typeof(Vector2) || param.expectedType == typeof(Vector3) || param.expectedType == typeof(Vector4))
                            {
                                //TODO: use minimalist method
                                lines += 2f;
                                continue;
                            }
                        }

                        UnityEngine.Object obj = objProp.objectReferenceValue;

                        if (obj == null)
                        {
                            continue;
                        }

                        Type type = obj.GetType();

                        GameObject selGO = null;
                        if (type == typeof(GameObject))
                        {
                            selGO = obj as GameObject;
                        }
                        else if (type.IsSubclassOf(typeof(Component)))
                        {
                            selGO = (obj as Component).gameObject;
                        }

                        if (selGO != null)
                        {
                            lines += ThunderEventDrawerTools.lineHeight;
                        }
                    }
                }

                return(lines - ThunderEventDrawerTools.lineHeight / 2);
            };
        }

        return(list);
    }