public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            Rect infoRect = new Rect(position.x, position.y + Height * 0.5f, position.width, Height);
            Rect propRect = new Rect(position.x, position.y + Height * 1.5f, position.width, Height);

            Rect ErrorRect = new Rect(position.x, position.y + Height * 0.5f, position.width, Height * 2f);

            Type fieldType = fieldInfo.FieldType;

            // 컴포넌트 상속 타입이 아닌 타입 - 에러박스
            if (fieldType.IsSubclassOf(typeof(Component)) == false)
            {
                // 배열, 리스트면 크기를 0으로 고정하고 콘솔 에러 메시지
                if (fieldType.Ex_IsArrayOrListType())
                {
                    fieldInfo.SetValue(property.serializedObject.targetObject, null);
                    Debug.LogError("[AutoInject] 배열 또는 리스트에는 사용할 수 없습니다.");
                }

                // 그 외의 경우, 인스펙터에 큼지막한 에러 박스
                EditorHelper.ColorErrorBox(ErrorRect, $"Error : Component를 상속하는 타입에만 사용할 수 있습니다\n" +
                                           $"이름 : {fieldInfo.Name}, 타입 : {fieldType}");
                return;
            }


            // 컴포넌트 타입 - 올바르게 동작 ===========================================================


            // 실행모드 옵션 제한을 설정한 경우
            switch (Atr.ModeOption)
            {
            case EModeOption.EditModeOnly when EditorApplication.isPlaying:
                EditorHelper.ColorWarningBox(infoRect, $"{Atr.Option} -  에디터 모드에서만 동작합니다");
                EditorGUI.PropertyField(propRect, property, label, true);
                return;

            case EModeOption.PlayModeOnly when !EditorApplication.isPlaying:
                EditorHelper.ColorWarningBox(infoRect, $"{Atr.Option} -  플레이 모드에서만 동작합니다");
                EditorGUI.PropertyField(propRect, property, label, true);
                return;
            }

            // 인스펙터에서 지정한 옵션별로 동작 : null일 때만 실행하게 해서 에디터 성능 최적화
            if (property.objectReferenceValue == null ||
                // Type Mismatch까지 검사(참조가 들어있는 상태에서 스크립트 내의 타입을 바꿔버린 경우)
                property.objectReferenceValue.GetType().Ex_IsChildOrEqualsTo(fieldType) == false)
            {
                Component target = property.serializedObject.targetObject as Component;

                switch (Atr.Option)
                {
                case EInjection.GetComponent:
                    property.objectReferenceValue = target.GetComponent(fieldType);
                    break;

                case EInjection.GetComponentInChildren:
                    property.objectReferenceValue = target.GetComponentInChildren(fieldType);
                    break;

                case EInjection.GetComponentInChildrenOnly:
                    property.objectReferenceValue = target.Ex_GetComponentInChildrenOnly(fieldType);
                    break;

                case EInjection.GetComponentInAllChildren:
                    property.objectReferenceValue = target.Ex_GetComponentInAllChildren(fieldType);
                    break;

                case EInjection.GetComponentInparent:
                    property.objectReferenceValue = target.GetComponentInParent(fieldType);
                    break;

                case EInjection.GetComponentInparentOnly:
                    property.objectReferenceValue = target.Ex_GetComponentInParentOnly(fieldType);
                    break;

                case EInjection.FindObjectOfType:
                    property.objectReferenceValue = UnityEngine.Object.FindObjectOfType(fieldType);
                    break;
                }
            }

            // 실행 결과 - 성공
            if (property.objectReferenceValue != null)
            {
                EditorHelper.ColorInfoBox(infoRect, Color.green, $"{Atr.Option}");
            }
            // 실행 결과 - 실패(대상이 없음)
            else
            {
                EditorHelper.ColorWarningBox(infoRect, $"{Atr.Option} - Failed : 대상을 찾지 못했습니다");
            }
            EditorGUI.PropertyField(propRect, property, label, true);
        }
Esempio n. 2
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            float x     = position.x;
            float y     = position.y;
            float width = position.width;

            Rect firstThird = new Rect(x, y + Height * 0.5f, width, Height);
            Rect midThird   = new Rect(x, y + Height * 1.5f, width, Height);
            Rect errorRect  = new Rect(x, y + Height * 0.5f, width, Height * 2f);

            // 타입 제한 : 컴포넌트, 게임오브젝트
            if (FieldType.Ex_IsChildOrEqualsTo(typeof(Component)) == false &&
                FieldType.IsEquivalentTo(typeof(GameObject)) == false)
            {
                // 배열, 리스트면 크기를 0으로 고정하고 콘솔 에러 메시지
                if (FieldType.Ex_IsArrayOrListType())
                {
                    fieldInfo.SetValue(property.serializedObject.targetObject, null);
                    Debug.LogError("[Required] 배열 또는 리스트에는 사용할 수 없습니다.");
                }

                if (!Atr.ShowMessageBox)
                {
                    EditorHelper.ColorErrorBox(position, $"[Required - Error] Component 타입이 아닙니다. - 대상 타입 : {FieldType}");
                }
                else
                {
                    EditorHelper.ColorErrorBox(errorRect, $"[Required - Error] Component 타입이 아닙니다.\n대상 타입 : {FieldType}");
                }

                return;
            }


            Rect  rect         = position;
            Color contentColor = new Color(0.3f, 1f, 0.2f);

            // 1-1. 경고 - null이거나 MisMatch
            // Type Mismatch까지 검사(참조가 들어있는 상태에서 스크립트 내의 타입을 바꿔버린 경우)
            if (IsEmpty(property))
            {
                if (Atr.ShowMessageBox)
                {
                    // ★ Missing Reference 잡아주기
                    property.objectReferenceValue = null;

                    EditorHelper.ColorErrorBox(firstThird, "[Required Component]");
                    rect = midThird;

                    if (Atr.ShowLogError)
                    {
                        Debug.LogError($"[Required Component] - GameObject : {property.serializedObject.targetObject.name}, " +
                                       $"Field : {fieldInfo.Name}");
                    }
                }
                contentColor = new Color(1f, 0.3f, 0.2f);
            }

            // 1-2. 평소 상태
            // do nothing

            var col = GUI.contentColor;

            GUI.contentColor = contentColor;
            EditorGUI.PropertyField(rect, property, label, true);
            GUI.contentColor = col;
        }
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            float minValue = 0f;
            float maxValue = Atr.MaxValue.Ex_ClampMin(minValue);
            float currentValue;
            Rect  propRect = new Rect(position.x, position.y, position.width, Height);
            Rect  backRect = new Rect(position.x, position.y + Height, position.width, Height * 1.5f);

            switch (property.propertyType)
            {
            case SerializedPropertyType.Integer:

                // 값 범위 강제 제한
                if (Atr.ClampInRange)
                {
                    property.intValue = property.intValue.Ex_Clamp((int)minValue, (int)maxValue);
                }
                currentValue = property.intValue;
                break;

            case SerializedPropertyType.Float:

                if (Atr.ClampInRange)
                {
                    property.floatValue = property.floatValue.Ex_Clamp(minValue, maxValue);
                }
                currentValue = property.floatValue;
                break;

            default:
                EditorGUI.PropertyField(propRect, property, label, true);
                EditorHelper.ColorErrorBox(backRect, $"[ProgressBar - Error] 숫자 타입에만 사용할 수 있습니다.\n대상 타입 : {property.type} ");
                return;
            }


            // 바 가로길이 구하기
            float ratio   = (currentValue / maxValue).Ex_Clamp(0f, 1f);
            Rect  barRect = new Rect(position.x, position.y + Height, position.width * ratio, Height * 1.5f);

            // 기본 필드 그리기
            if (Atr.ClampInRange)
            {
                label.text = $"{label.text} [Clamped]";
            }
            EditorGUI.PropertyField(propRect, property, label, true);

            // 바 그리기
            EditorGUI.DrawRect(backRect, Color.black);
            EditorGUI.DrawRect(barRect, Atr.BarColor.Ex_Convert());

            // 텍스트 그리기
            var textStyle = new GUIStyle(GUI.skin.label);

            textStyle.fontStyle        = FontStyle.Bold;
            textStyle.normal.textColor = Atr.TextColor.Ex_Convert();
            textStyle.fontSize         = 20;
            textStyle.alignment        = TextAnchor.MiddleCenter;

            EditorGUI.LabelField(backRect, $"{currentValue} / {maxValue}", textStyle);
        }