#if UNITY_2019_1_OR_NEWER using UnityEditor; using UnityEngine; namespace UnityAtoms.Editor { /// /// The base Unity Atoms property drawer. Makes it possible to create and add a new Atom via Unity's inspector. Only availble in `UNITY_2019_1_OR_NEWER`. /// /// The type of Atom the property drawer should apply to. public abstract class AtomDrawer : PropertyDrawer where T : ScriptableObject { private bool _userClickedToCreateAtom = false; private string _nameOfNewAtom = ""; private string _warningText = ""; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { var isCreatingSO = _userClickedToCreateAtom && property.objectReferenceValue == null; if (!isCreatingSO || _warningText.Length <= 0) return base.GetPropertyHeight(property, label); return base.GetPropertyHeight(property, label) * 2 + 4f; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { var isCreatingSO = _userClickedToCreateAtom && property.objectReferenceValue == null; var restWidth = _userClickedToCreateAtom ? 50 : 58; var gutter = _userClickedToCreateAtom ? 2f : 6f; Rect restRect = new Rect(); Rect warningRect = new Rect(); EditorGUI.BeginProperty(position, label, property); if (_warningText.Length > 0) { position = IMGUIUtils.SnipRectV(position, EditorGUIUtility.singleLineHeight, out warningRect, 2f); } if (property.objectReferenceValue == null) { position = IMGUIUtils.SnipRectH(position, position.width - restWidth, out restRect, gutter); } var defaultGUIColor = GUI.color; GUI.color = isCreatingSO ? Color.yellow : defaultGUIColor; position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), isCreatingSO ? new GUIContent("Name of New Atom") : label); GUI.color = defaultGUIColor; if (isCreatingSO) { _nameOfNewAtom = EditorGUI.TextField(position, _nameOfNewAtom); } else { property.objectReferenceValue = EditorGUI.ObjectField(position, property.objectReferenceValue, typeof(T), false); } if (property.objectReferenceValue == null) { if (isCreatingSO) { var buttonWidth = 24; Rect secondButtonRect; Rect firstButtonRect = IMGUIUtils.SnipRectH(restRect, restRect.width - buttonWidth, out secondButtonRect, gutter); if (GUI.Button(firstButtonRect, "✓")) { if (_nameOfNewAtom.Length > 0) { try { // Create asset T so = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(so, "Assets/" + _nameOfNewAtom + ".asset"); AssetDatabase.SaveAssets(); // Assign the newly created SO property.objectReferenceValue = so; } catch { Debug.LogError("Not able to create Atom"); } _userClickedToCreateAtom = false; _warningText = ""; } else { _warningText = "Name of new Atom must be specified!"; } } if (GUI.Button(secondButtonRect, "✗")) { _userClickedToCreateAtom = false; _warningText = ""; } if (_warningText.Length > 0) { EditorGUI.HelpBox(warningRect, _warningText, MessageType.Warning); } } else { if (GUI.Button(restRect, "Create")) { _nameOfNewAtom = ""; _userClickedToCreateAtom = true; } } } EditorGUI.EndProperty(); } } } #endif