public static void GetOptionsAndNameAssets <T>( this ICustomOptionNamesProvider <T> provider, ref string[] optionNames, ref T[] nameAssets, string[] defaultOptions ) where T : ScriptableObject, IFlagNames { if (optionNames != null) { return; } var guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}"); nameAssets = guids .Select(AssetDatabase.GUIDToAssetPath) .Select(AssetDatabase.LoadAssetAtPath <T>) .Where(c => c != null) .ToArray(); optionNames = nameAssets.FirstOrDefault()?.FlagNames.ToArray() ?? defaultOptions; for (var i = 0; i < optionNames.Length; ++i) { optionNames[i] = string.IsNullOrEmpty(optionNames[i]) ? defaultOptions[i] : optionNames[i]; } }
public static void DoCustomNamesPopup <T>( Rect position, SerializedProperty property, GUIContent label, ICustomOptionNamesProvider <T> optionsProvider ) where T : ScriptableObject { if (optionsProvider.NameAssets?.Count == 0) { position.xMax -= Styles.CreateAssetButtonWidth + EditorGUIUtility.standardVerticalSpacing; } else if (optionsProvider.NameAssets?.Count > 1) { position.xMax -= EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } EditorGUI.BeginProperty(position, label, property); var controlPosition = EditorGUI.PrefixLabel(position, label); var indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; var showMixed = EditorGUI.showMixedValue; var value = 0; var everything = 0; for (int i = 0, count = property.arraySize; i < count; ++i) { var sp = property.GetArrayElementAtIndex(i); EditorGUI.showMixedValue |= sp.hasMultipleDifferentValues; value |= sp.boolValue ? 1 << i : 0; everything |= 1 << i; } // in case size is smaller than 32 if (value == everything) { value = ~0; } EditorGUI.BeginChangeCheck(); value = EditorGUI.MaskField(controlPosition, GUIContent.none, value, optionsProvider.GetOptions()); if (EditorGUI.EndChangeCheck()) { for (int i = 0, count = property.arraySize; i < count; ++i) { property.GetArrayElementAtIndex(i).boolValue = (value & (1 << i)) != 0; } } EditorGUI.showMixedValue = showMixed; EditorGUI.indentLevel = indent; EditorGUI.EndProperty(); if (optionsProvider.NameAssets?.Count == 0) { position.width = Styles.CreateAssetButtonWidth; position.x = controlPosition.xMax + EditorGUIUtility.standardVerticalSpacing; Styles.CreateAssetLabel.tooltip = string.Format(Styles.CreateAssetButtonTooltip, ObjectNames.NicifyVariableName(typeof(T).Name)); if (GUI.Button(position, Styles.CreateAssetLabel, EditorStyles.miniButton)) { var assetPath = AssetDatabase.GenerateUniqueAssetPath($"Assets/{typeof(T).Name}.asset"); AssetDatabase.CreateAsset(ScriptableObject.CreateInstance <T>(), assetPath); Selection.activeObject = AssetDatabase.LoadAssetAtPath <T>(assetPath); optionsProvider.Update(); } } else if (optionsProvider.NameAssets.Count > 1) { var id = GUIUtility.GetControlID(FocusType.Passive); if (Event.current.type == EventType.Repaint) { position.width = EditorGUIUtility.singleLineHeight; position.x = controlPosition.xMax + EditorGUIUtility.standardVerticalSpacing; Styles.MultipleAssetsWarning.tooltip = string.Format( Styles.MultipleAssetsTooltip, ObjectNames.NicifyVariableName(typeof(T).Name), optionsProvider.NameAssets.FirstOrDefault(n => n != null)?.name ); GUIStyle.none.Draw(position, Styles.MultipleAssetsWarning, id); } } }