Repository: FreyaHolmer/Render-Queue Branch: master Commit: c05cd9efcfad Files: 19 Total size: 16.7 KB Directory structure: gitextract_0fgj1vd6/ ├── .gitignore ├── LICENSE ├── README.md ├── Render Queue/ │ ├── Editor/ │ │ ├── AssetList.cs │ │ ├── AssetList.cs.meta │ │ ├── Entry.cs │ │ ├── Entry.cs.meta │ │ ├── EntryState.cs │ │ ├── EntryState.cs.meta │ │ ├── Filter.cs │ │ ├── Filter.cs.meta │ │ ├── Filters.cs │ │ ├── Filters.cs.meta │ │ ├── RenderQueueGUI.cs │ │ ├── RenderQueueGUI.cs.meta │ │ ├── RenderQueueWindow.cs │ │ └── RenderQueueWindow.cs.meta │ └── Editor.meta └── Render Queue.meta ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ [Ll]ibrary/ [Tt]emp/ [Oo]bj/ [Bb]uild/ [Bb]uilds/ Assets/AssetStoreTools* LICENSE.meta README.md.meta # Visual Studio cache directory .vs/ # Autogenerated VS/MD/Consulo solution and project files ExportedObj/ .consulo/ *.csproj *.unityproj *.sln *.suo *.tmp *.user *.userprefs *.pidb *.booproj *.svd *.pdb *.opendb # Unity3D generated meta files *.pidb.meta *.pdb.meta # Unity3D Generated File On Crash Reports sysinfo.txt # Builds *.apk *.unitypackage ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2019 Freya Holmér Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Render-Queue Render Queue Unity Extension Make sure your project is using .NET 4.x in Player Settings! ================================================ FILE: Render Queue/Editor/AssetList.cs ================================================ // Copyright © 2019 Freya Holmér • freya@acegikmo.com • https://github.com/FreyaHolmer/Render-Queue namespace RenderQueuePlugin { using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Linq; [System.Serializable] public class AssetList { [SerializeField] Vector2 scrollPosition = Vector2.zero; [SerializeField] List entries; public bool HasPendingChanges => entries.Any( e => e.ModifiedState == EntryState.Modified ); public void ApplyAllChanges() => entries.ForEach( e => e.ApplyIfModified() ); public void RevertAllChanges() => entries.ForEach( e => e.RevertIfModified() ); public void UpdateList( Filter filter, System.Type type ) { if( entries == null ) entries = new List(); // Collect any pending modifications before refreshing IEnumerable<(Object,int)> modifications = entries .Where( x => x.ModifiedState == EntryState.Modified ) .Select( x => (x.asset, x.renderQueueInput) ); // Get all assets from the project filtered by the selected filter string assetSearch = $"t:{type.Name}"; entries = AssetDatabase.FindAssets( assetSearch ) .Select( guid => AssetDatabase.GUIDToAssetPath( guid ) ) .Where( filter.filter ) .Select( path => new Entry( AssetDatabase.LoadAssetAtPath( path, type ) ) ) .ToList(); // Re-add the pending changes to corresponding entries if they still exist foreach( var (modMat, modValue) in modifications ) { Entry entry = entries.FirstOrDefault( e => e.asset == modMat ); if( entry != null ) entry.renderQueueInput = modValue; } // Order by Render Queue input entries.Sort( ( a, b ) => b.renderQueueInput.CompareTo( a.renderQueueInput ) ); } public void Draw() { scrollPosition = GUILayout.BeginScrollView( scrollPosition ); { GUILayout.BeginVertical( RenderQueueGUI.PanelStyle ); for( int i = 0; i < entries.Count; i++ ) { // Entry entries[i].Draw(); // Spacing between groups if( i < entries.Count - 1 ) { bool validEntries = entries[i].ModifiedState != EntryState.Missing && entries[i+1].ModifiedState != EntryState.Missing; if( validEntries ) { int delta = entries[i].RenderQueue - entries[i + 1].RenderQueue; if( delta > 1 ) { GUILayout.EndVertical(); RenderQueueGUI.Fade( 0.4f, () => { RenderQueueGUI.LabelSmallRight( delta.ToString() ); } ); GUILayout.BeginVertical( RenderQueueGUI.PanelStyle ); } } } } GUILayout.EndVertical(); } GUILayout.EndScrollView(); } } } ================================================ FILE: Render Queue/Editor/AssetList.cs.meta ================================================ fileFormatVersion: 2 guid: 0db4344400aec7440894b8f4545cc785 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue/Editor/Entry.cs ================================================ // Copyright © 2019 Freya Holmér • freya@acegikmo.com • https://github.com/FreyaHolmer/Render-Queue namespace RenderQueuePlugin { using UnityEngine; using UnityEditor; [System.Serializable] public class Entry { public enum EntryType { Material, Shader } public Object asset; public int renderQueueInput; public EntryType entryType; Material AssetMaterial => asset as Material; Shader AssetShader => asset as Shader; public int RenderQueue { get { switch( entryType ) { case EntryType.Material: return AssetMaterial.renderQueue; case EntryType.Shader: return AssetShader.renderQueue; } return default; } set { if( entryType == EntryType.Material ) { AssetMaterial.renderQueue = value; return; } // Note: Shader render queue is read only } } public EntryState ModifiedState { get { if( asset == null ) return EntryState.Missing; if( renderQueueInput != RenderQueue ) return EntryState.Modified; return EntryState.Unchanged; } } public Entry( Object asset ) { this.asset = asset; if( asset is Material ) entryType = EntryType.Material; else if( asset is Shader ) entryType = EntryType.Shader; this.renderQueueInput = RenderQueue; } public string GetOffsetLabelString( EntryState state ) { if( state == EntryState.Missing ) return "?"; int offset = renderQueueInput - 3000; return RenderQueueGUI.ToSignedString( offset ); } public string GetRenderTag( EntryState state ) { if( state == EntryState.Missing ) return "?"; if( entryType == EntryType.Material ) return AssetMaterial.GetTag( "RenderType", true, "-" ); return string.Empty; } public void Draw() { EntryState state = ModifiedState; GUI.color = state.GetColor(); string offsetLabel = GetOffsetLabelString( state ); string renderTagLabel = GetRenderTag( state ); GUILayout.BeginHorizontal(); { RenderQueueGUI.Disabled( () => { GUILayout.Label( offsetLabel, GUILayout.Width( 40 ) ); } ); RenderQueueGUI.EnabledStateGroup( state != EntryState.Missing, () => { if(entryType == EntryType.Material ) { renderQueueInput = EditorGUILayout.IntField( renderQueueInput, GUILayout.Width( 40 ) ); } else { GUILayout.Space( 1 ); // To make the label align with the textbox when viewing things you can edit GUILayout.Label( renderQueueInput.ToString(), GUILayout.Width( 40 ) ); // Read only } EditorGUILayout.ObjectField( asset, typeof( Material ), allowSceneObjects: false, GUILayout.ExpandWidth( true ) ); } ); if( entryType == EntryType.Material ) { RenderQueueGUI.Fade( 0.4f, () => { GUILayout.Label( renderTagLabel, EditorStyles.miniLabel, GUILayout.Width( 100 ) ); } ); } } GUILayout.EndHorizontal(); GUI.color = Color.white; } public void ApplyIfModified() { if( ModifiedState == EntryState.Modified ) { UnityEditor.Undo.RecordObject( asset, "change asset render queque" ); RenderQueue = renderQueueInput; renderQueueInput = RenderQueue; // Make sure it matches asset afterwards after } } public void RevertIfModified() { if( ModifiedState == EntryState.Modified ) renderQueueInput = RenderQueue; } } } ================================================ FILE: Render Queue/Editor/Entry.cs.meta ================================================ fileFormatVersion: 2 guid: 90b5cf8dc28d1b743b13ba90e39d42ae MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue/Editor/EntryState.cs ================================================ // Copyright © 2019 Freya Holmér • freya@acegikmo.com • https://github.com/FreyaHolmer/Render-Queue namespace RenderQueuePlugin { using UnityEngine; using UnityEditor; public enum EntryState { Unchanged, Modified, Missing } [System.Serializable] public static class EntryStateExtensions { static readonly Color[] stateColors = { Color.white, Color.cyan, Color.red }; public static Color GetColor( this EntryState state ) => stateColors[(int)state]; } } ================================================ FILE: Render Queue/Editor/EntryState.cs.meta ================================================ fileFormatVersion: 2 guid: d427040b3ca16324b9aa7d71c29b4d41 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue/Editor/Filter.cs ================================================ // Copyright © 2019 Freya Holmér • freya@acegikmo.com • https://github.com/FreyaHolmer/Render-Queue namespace RenderQueuePlugin { using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using System; public class Filter { public string name; public Func filter; public Filter( string name, Func filter ) { this.name = name; this.filter = filter; } } } ================================================ FILE: Render Queue/Editor/Filter.cs.meta ================================================ fileFormatVersion: 2 guid: e8db88d37d7956d4c9d6ceebba21988a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue/Editor/Filters.cs ================================================ // Copyright © 2019 Freya Holmér • freya@acegikmo.com • https://github.com/FreyaHolmer/Render-Queue namespace RenderQueuePlugin { using System.Collections.Generic; public static class Filters { public static List filters = new List(){ // Add new filters here // Do not use these symbols in filter names: &/^% // (They completely mess up formatting in the picker menu) new Filter( "All", (path) => true ), new Filter( "Materials + Shaders", (path) => path.StartsWith("Assets/Materials/") || path.StartsWith("Assets/Shaders/") ), }; } } ================================================ FILE: Render Queue/Editor/Filters.cs.meta ================================================ fileFormatVersion: 2 guid: 8c8b0eb330a612241831f0140c2756b6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue/Editor/RenderQueueGUI.cs ================================================ // Copyright © 2019 Freya Holmér • freya@acegikmo.com • https://github.com/FreyaHolmer/Render-Queue namespace RenderQueuePlugin { using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Linq; public static class RenderQueueGUI { static GUIStyle panelStyle; public static GUIStyle PanelStyle { get { if( panelStyle == null ) { panelStyle = new GUIStyle( EditorStyles.helpBox ) { padding = new RectOffset( 2, 2, 4, 4 ), margin = new RectOffset( 0, 0, 0, 0 ) }; } return panelStyle; } } static GUIContent iconMaterial; public static GUIContent IconMaterial { get { if( iconMaterial == null ) iconMaterial = EditorGUIUtility.IconContent( "Material Icon" ); return iconMaterial; } } static GUIContent iconShader; public static GUIContent IconShader { get { if( iconShader == null ) iconShader = EditorGUIUtility.IconContent( "Shader Icon" ); return iconShader; } } static Color cachedPrevColor; public static void Fade( float opacity, System.Action content ) { cachedPrevColor = GUI.color; Color c = cachedPrevColor; c.a *= opacity; GUI.color = c; content(); GUI.color = cachedPrevColor; } public static void Disabled( System.Action content ) { EditorGUI.BeginDisabledGroup( true ); content(); EditorGUI.EndDisabledGroup(); } public static void EnabledStateGroup( bool enabled, System.Action content ) { EditorGUI.BeginDisabledGroup( enabled == false ); content(); EditorGUI.EndDisabledGroup(); } public static string ToSignedString( int value ) { if( value == 0 ) return "±" + value; if( value > 0 ) return "+" + value; return value.ToString(); // Negative symbol is already included } public static void LabelSmallRight( string str ) { GUILayout.BeginHorizontal(); GUILayout.Label( string.Empty, GUILayout.ExpandWidth( true ) ); GUILayout.Label( str, EditorStyles.centeredGreyMiniLabel, GUILayout.ExpandWidth( false ) ); GUILayout.EndHorizontal(); } public static void Deselect() => GUI.FocusControl( "" ); } } ================================================ FILE: Render Queue/Editor/RenderQueueGUI.cs.meta ================================================ fileFormatVersion: 2 guid: e502883221570e143a4e843349ea3432 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue/Editor/RenderQueueWindow.cs ================================================ // Copyright © 2019 Freya Holmér • freya@acegikmo.com • https://github.com/FreyaHolmer/Render-Queue namespace RenderQueuePlugin { using UnityEngine; using UnityEditor; using System.Linq; using System.Collections.Generic; using System; public class RenderQueueWindow : EditorWindow { // Constants const string EDITOR_PREF_PREFIX = "render_queue_window_"; const string EDITOR_PREF_KEY_FILTER_INDEX = EDITOR_PREF_PREFIX + "filter_index"; const string EDITOR_PREF_KEY_LIST_INDEX = EDITOR_PREF_PREFIX + "list_index"; // Asset types & icons static (Type type, Func getIcon )[] typesAndIcons = { (typeof(Material), () => RenderQueueGUI.IconMaterial), (typeof(Shader), () => RenderQueueGUI.IconShader) }; [SerializeField] int listIndex = 0; [SerializeField] AssetList[] lists = new AssetList[typesAndIcons.Length]; [SerializeField] int filterIndex = 0; [SerializeField] string[] filterNames; [SerializeField] int[] filterIndices; AssetList CurrentList { get => lists[listIndex]; set => lists[listIndex] = value; } Type CurrentType => typesAndIcons[listIndex].type; [MenuItem( "Tools/Render Queue" )] public static void Intialize() => GetWindow( "Render Queue" ); private void OnEnable() { LoadPrefs(); RefreshFilters(); RefreshList(); Undo.undoRedoPerformed += OnUndoRedo; } private void OnDisable() { SavePrefs(); Undo.undoRedoPerformed -= OnUndoRedo; } public void OnGUI() { DrawHeader(); CurrentList.Draw(); DeselectIfClickedNothing(); } void SavePrefs() { EditorPrefs.SetInt( EDITOR_PREF_KEY_FILTER_INDEX, filterIndex ); EditorPrefs.SetInt( EDITOR_PREF_KEY_LIST_INDEX, listIndex ); } void LoadPrefs() { filterIndex = EditorPrefs.GetInt( EDITOR_PREF_KEY_FILTER_INDEX, 0 ); listIndex = EditorPrefs.GetInt( EDITOR_PREF_KEY_LIST_INDEX, 0 ); } void OnUndoRedo() { RefreshList(); Repaint(); } void RefreshFilters() { filterNames = Filters.filters.Select( f => f.name ).ToArray(); filterIndices = new int[filterNames.Length]; for( int i = 0; i < filterIndices.Length; i++ ) filterIndices[i] = i; filterIndex = Mathf.Clamp( filterIndex, 0, Filters.filters.Count - 1 ); } void RefreshList() { if( CurrentList == null ) CurrentList = new AssetList(); CurrentList.UpdateList( Filters.filters[filterIndex], CurrentType ); RenderQueueGUI.Deselect(); } void DrawHeader() { bool hasChanges = CurrentList.HasPendingChanges; GUILayout.BeginHorizontal( EditorStyles.toolbar ); { if( GUILayout.Button( typesAndIcons[listIndex].getIcon(), EditorStyles.toolbarButton, GUILayout.Width( 24 ), GUILayout.Height(16) ) ) { listIndex = 1 - listIndex; RefreshList(); } if( GUILayout.Button( "Refresh", EditorStyles.miniButtonLeft, GUILayout.Width( 66 ) ) ) { RefreshList(); } EditorGUI.BeginDisabledGroup( hasChanges == false ); if( GUILayout.Button( "Revert", EditorStyles.miniButtonMid, GUILayout.Width( 60 ) ) ) { CurrentList.RevertAllChanges(); RefreshList(); } if( GUILayout.Button( "Apply", EditorStyles.miniButtonRight, GUILayout.Width( 50 ) ) ) { CurrentList.ApplyAllChanges(); RefreshList(); } EditorGUI.EndDisabledGroup(); GUILayout.Space( 5 ); EditorGUI.BeginChangeCheck(); GUILayout.Label( "Folder Filter", EditorStyles.miniLabel, GUILayout.ExpandWidth( false ) ); filterIndex = EditorGUILayout.IntPopup( filterIndex, filterNames, filterIndices ); if( EditorGUI.EndChangeCheck() ) { RefreshList(); } } GUILayout.EndHorizontal(); } void DeselectIfClickedNothing() { if( Event.current.type == EventType.MouseDown && Event.current.button == 0 ) { RenderQueueGUI.Deselect(); Repaint(); } } } } ================================================ FILE: Render Queue/Editor/RenderQueueWindow.cs.meta ================================================ fileFormatVersion: 2 guid: adaf75a07a28a574397ac38179fac3b3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue/Editor.meta ================================================ fileFormatVersion: 2 guid: adfb608eb5ae6d943aca0a40ca6c11a4 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Render Queue.meta ================================================ fileFormatVersion: 2 guid: 58cf4e6c44092a14e8f72a35436a3818 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: