/// <summary> /// Minuses the tag game objects. /// </summary> /// <param name="tag">The tag.</param> /// <param name="activeGameObjects">The active game objects.</param> private void MinusTagGameObjects(string tag, params GameObject[] activeGameObjects) { TagManager.RemoveTags(activeGameObjects, tag); TagManager.RefreshTags(); }
/// <summary> /// Draws the tag find. /// </summary> private void DrawTagFind() { EditorGUILayout.BeginHorizontal(); GUIContent findTagFoldoutContent = new GUIContent(string.Format("Find tags")); GUIStyle findTagFoldoutStyle = new GUIStyle(EditorStyles.foldout); this.findTagFoldout.target = EditorGUILayout.Foldout(this.findTagFoldout.target, findTagFoldoutContent, findTagFoldoutStyle); GUILayout.FlexibleSpace(); if (GUILayout.Button(string.Empty, CustomEditorStyles.HelpIconStyle)) { Application.OpenURL("http://aiunity.com/products/multiple-tags/manual#gui-find-tags"); } EditorGUILayout.EndHorizontal(); if (EditorGUILayout.BeginFadeGroup(this.findTagFoldout.faded)) { EditorGUI.indentLevel++; EditorGUILayout.BeginHorizontal(); GUIStyle findCategoryStyle = new GUIStyle(EditorStyles.radioButton); findCategoryStyle.margin.left = 0; findCategoryStyle.margin.right = 0; EditorGUILayout.PrefixLabel("Tag category"); string[] tagCategories = Enum.GetNames(typeof(TagCategory)); this.tagCategory = (TagCategory)GUILayout.SelectionGrid((int)this.tagCategory, tagCategories, tagCategories.Length, findCategoryStyle); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUIContent findTagContent = new GUIContent("Tag expression", "Find Unity tags matching this expression. The expression can use text, regex, and boolean logic. Click the + sign to see available syntax and tags. The expression complexity can range from \"Tag1\" to \"(Tag1 & Tag2.*) | Tag3\". An empty expression is a special case that denotes all tags (ie. .*)."); EditorGUILayout.PrefixLabel(findTagContent); GUIStyle findTagStyle = new GUIStyle(EditorStyles.textField) { wordWrap = true }; foreach (string tagPath in this.TagSelected.Where(p => p.Value).Select(p => p.Key).Except(this.findTagPaths.Select(p => TagService.JoinTags(p))).ToList()) { this.TagSelected[tagPath] = false; } if (!this.findTagExpressionValid) { GUI.backgroundColor = Color.red; } GUI.SetNextControlName("FindTagExpression"); this.findTagExpression.text = GUILayout.TextField(this.findTagExpression.text, findTagStyle); GUI.backgroundColor = Color.white; bool addLayout = GUILayout.Button(string.Empty, CustomEditorStyles.PlusIconStyle); if (Event.current.type == EventType.Repaint) { this.findGameObjectMenuRect = GUILayoutUtility.GetLastRect(); } if (addLayout) { EditorGUI.FocusTextInControl("FindTagExpression"); GenericMenu findMenu = CreateFindMenu(this.findTagExpression); findMenu.DropDown(this.findGameObjectMenuRect); } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; try { Regex.Match(string.Empty, this.findTagExpression.text); this.findTagPaths = string.IsNullOrEmpty(this.findTagExpression.text) ? TagService.AllTagPaths : TagService.GetTagPathMatches(this.findTagExpression.text); this.findTagExpressionValid = true; } catch (ArgumentException) { this.findTagExpressionValid = false; } if (this.findTagPaths.Any()) { EditorGUILayout.Space(); this.tagFindScroll = EditorGUILayout.BeginScrollView(this.tagFindScroll, false, false); GUIStyle tagHeaderStyle = new GUIStyle(EditorStyles.label); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20); EditorGUILayout.BeginVertical("box"); bool tagSelectAll = this.TagSelected.All(p => p.Value || TagService.FixedTags.Any(f => f == p.Key)); bool tagSelectAllUpdate = EditorGUILayout.ToggleLeft("Select All", tagSelectAll, tagHeaderStyle); if (tagSelectAllUpdate ^ tagSelectAll) { this.TagSelected = this.TagSelected.ToDictionary(p => p.Key, p => tagSelectAllUpdate && !TagService.FixedTags.Any(f => f == p.Key)); } foreach (string tagPath in this.findTagPaths.Select(p => TagService.JoinTags(p)).Reverse()) { EditorGUILayout.BeginHorizontal(); int tagPathCount = 0; TagManager.TagPathCount.TryGetValue(tagPath, out tagPathCount); if (this.tagCategory == TagCategory.All || (this.tagCategory == TagCategory.Used && tagPathCount > 0) || (this.tagCategory == TagCategory.Unused && tagPathCount == 0)) { EditorGUI.BeginDisabledGroup(TagService.FixedTags.Any(f => f == tagPath)); GUIContent tagSelectedContent = new GUIContent(string.Format("({0}) {1}", tagPathCount, tagPath)); bool tagSelected = this.TagSelected[tagPath] = this.TagSelected.TryGetValue(tagPath, out tagSelected) && tagSelected; this.TagSelected[tagPath] = EditorGUILayout.ToggleLeft(tagSelectedContent, tagSelected, tagHeaderStyle); EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); } EditorGUIUtility.labelWidth = 0; EditorGUILayout.Space(); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndScrollView(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20); GUIContent tagAddContent = new GUIContent("Add", "Add tags to unity."); if (GUILayout.Button(tagAddContent)) { CreateTagPopup(tag => TagManager.AddTags(tag)); TagManager.RefreshTags(); } GUIContent deleteGUIContent = new GUIContent("Delete"); if (GUILayout.Button(deleteGUIContent)) { bool tagSelected = false; foreach (IEnumerable <string> tagPath in this.findTagPaths.Where(p => this.TagSelected.TryGetValue(TagService.JoinTags(p), out tagSelected) && tagSelected)) { TagManager.RemoveTags(tagPath.ToArray()); RefreshTags(); } } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } } EditorGUILayout.EndFadeGroup(); }
/// <summary> /// Draws the options. /// </summary> private void DrawOptions() { EditorGUILayout.BeginHorizontal(); GUIContent optionsFoldoutContent = new GUIContent(string.Format("Options")); this.optionsFoldout.target = EditorGUILayout.Foldout(this.optionsFoldout.target, optionsFoldoutContent); GUILayout.FlexibleSpace(); if (GUILayout.Button(string.Empty, CustomEditorStyles.HelpIconStyle)) { Application.OpenURL("http://aiunity.com/products/multiple-tags/manual#gui-options"); } EditorGUILayout.EndHorizontal(); if (EditorGUILayout.BeginFadeGroup(this.optionsFoldout.faded)) { EditorGUI.indentLevel++; // Create config internal level GUI Logger.InternalLogLevel = (LogLevels)EditorGUILayout.EnumFlagsField(this.internalLevelsContent, Logger.InternalLogLevel); GUIContent tagExpandContent = new GUIContent("Tag expand", "This will facilitate the generation of tag permutations." + " For example when selected the creation of tagPath T1/T2/T3 would also produce tagPaths TI and T1/T2." + " Also note with this option enabled the \"Tag optimize\" command will expand all tagPaths. The default is disabled."); TagManager.tagExpand = Convert.ToBoolean(EditorPrefs.GetInt("AiUnityMultipleTagsTagExpand", Convert.ToInt32(TagManager.tagExpand))); EditorPrefs.SetInt("AiUnityMultipleTagsTagExpand", Convert.ToInt32(EditorGUILayout.Toggle(tagExpandContent, TagManager.tagExpand))); GUIContent groupExpandContent = new GUIContent("Group expand", "This will facilitate the generation of group permutations." + " For example when selected adding tag T1/Color.Red would automatically create T1/Color.Blue." + " Also note with this option enabled the \"Tag optimize\" command will expand all tagGroups. The default is enabled."); TagManager.groupExpand = Convert.ToBoolean(EditorPrefs.GetInt("AiUnityMultipleTagsGroupExpand", Convert.ToInt32(TagManager.groupExpand))); EditorPrefs.SetInt("AiUnityMultipleTagsGroupExpand", Convert.ToInt32(EditorGUILayout.Toggle(groupExpandContent, TagManager.groupExpand))); EditorGUILayout.BeginHorizontal(); GUIContent tagAccessCreatorContent = new GUIContent("TagAccess script", "Manually or automatically generate TagAccess.cs in folder AiUnity / UserData / MultipleTags / Resources." + " TagAccess provides type safe access to Unity Tags and is utilized by the MultipleTags APIs." + " With auto selected any change to the Unity tags will cause TagAccess.cs to regenerate."); EditorGUILayout.PrefixLabel(tagAccessCreatorContent); if (GUILayout.Button("Create", GUILayout.Width(50))) { TagAccessCreator.Instance.Create(); } EditorGUIUtility.labelWidth = 50; GUIContent autoUpdateContent = new GUIContent("Auto", "When selected any change to the Unity tags will cause TagAccess.cs to be regenerate. The default is disabled."); bool autoUpdate = Convert.ToBoolean(EditorPrefs.GetInt("AiUnityMultipleTagsAutoUpdate", 0)); EditorPrefs.SetInt("AiUnityMultipleTagsAutoUpdate", Convert.ToInt32(EditorGUILayout.Toggle(autoUpdateContent, autoUpdate))); EditorGUIUtility.labelWidth = 0; GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUIContent tagOptimizeContent = new GUIContent("Tag optimize", "Analyze and optimize all Unity tags. This operation will irreversibly add and delete Unity tags." + " Optimization includes consolidating and removing duplicate tagPaths. TagPaths and tagGroups are conditionally expanded based upon the expand options." + " With auto selected any tag(s) that are added/removed in the GUI will be optimized."); EditorGUILayout.PrefixLabel(tagOptimizeContent); if (GUILayout.Button("Run", GUILayout.Width(50))) { bool tagOptimizeConfirmation = EditorUtility.DisplayDialog("Confirm optimization", "This operation will irreversibly alter Unity tags. Do you wish to proceed?", "OK", "Cancel"); if (tagOptimizeConfirmation) { TagManager.OptimizeTags(); } } EditorGUIUtility.labelWidth = 50; GUIContent autoOptimizeContent = new GUIContent("Auto", "When selected optimization is run on any tag(s) that are added or removed. The default is enabled."); TagManager.AutoTagOptimize = Convert.ToBoolean(EditorPrefs.GetInt("AiUnityMultipleTagsAutoOptimize", 1)); EditorPrefs.SetInt("AiUnityMultipleTagsAutoOptimize", Convert.ToInt32(EditorGUILayout.Toggle(autoOptimizeContent, TagManager.AutoTagOptimize))); EditorGUIUtility.labelWidth = 0; GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; } EditorGUILayout.EndFadeGroup(); }
/// <summary> /// Refreshes the tags. /// </summary> void RefreshTags() { TagManager.RefreshTags(); Repaint(); }