Created
November 10, 2016 19:47
-
-
Save noisecrime/badd36a25f238a40f8678b364a33cf9c to your computer and use it in GitHub Desktop.
Editor class that will automatically set the scriptExecutionOrder based on using a ScriptExecutionAttribute.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ScriptExecutionAssignment | |
// NoiseCrime | |
// 11.10.2016 | |
// 05.06.2016 | |
// | |
// | |
// Editor class that will automatically set the scriptExecutionOrder based on using a ScriptExecutionAttribute. | |
// See ScriptExecutionAttribute.cs Gist! | |
// The class is called automatically everytime Unity recompiles the project - see [InitializeOnLoad] | |
// | |
// This script MUST be placed into an Editor Folder in your Unity Project. | |
// Requires Script names to match class name. | |
// Likely only works with a single class defined per file. | |
// Unfortunately the script will also execute everytime you run the project in the editor ( play ), so use defines below to control behaviour. | |
// | |
// ENABLE_SCRIPT: If NOT defined the script will not run. | |
// ENABLE_ASSIGNMENT: If NOT defined this will prevent execution of the script. | |
// ENABLE_LOGGING: If defined will log ( sorted by order ) to the console all found classes using the ScriptExecutionAttribute and their script order. | |
// ENABLE_MONO_LOGGING: If defined will log all scripts in mono that are not using default ScriptExecution value. | |
// #define ENABLE_SCRIPT | |
#define ENABLE_LOGGING | |
#define ENABLE_MONO_LOGGING | |
#define ENABLE_ASSIGNMENT | |
using UnityEngine; | |
using UnityEditor; | |
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
[InitializeOnLoad] | |
public class ScriptExecutionAssignment : Editor | |
{ | |
static ScriptExecutionAssignment() | |
{ | |
#if ENABLE_SCRIPT | |
if( EditorApplication.isCompiling || EditorApplication.isPaused || EditorApplication.isPlaying) return; | |
#if ENABLE_MONO_LOGGING | |
LogAllMonoScripts(); | |
#endif | |
AssignExecutionOrderToMonoScripts(); | |
#else | |
Debug.LogWarning("EDITOR: ScriptExecutionAssignment is disabled - check script define."); | |
#endif | |
} | |
static void LogAllMonoScripts() | |
{ | |
Dictionary<string, int[]> executionOrderLogging = new Dictionary<string, int[]>(); | |
// Lock Assemblies | |
EditorApplication.LockReloadAssemblies(); | |
foreach (MonoScript monoScript in MonoImporter.GetAllRuntimeMonoScripts()) | |
{ | |
Type monoClass = monoScript.GetClass(); | |
if( monoClass != null) | |
{ | |
int executionOrderOriginal = MonoImporter.GetExecutionOrder(monoScript); | |
if(executionOrderOriginal != 0) executionOrderLogging.Add( monoScript.name, new int[ 2 ] { executionOrderOriginal, executionOrderOriginal } ); | |
} | |
} | |
// Unlock Assemblies | |
EditorApplication.UnlockReloadAssemblies(); | |
LogResults("GetExecutionOrder", executionOrderLogging); | |
} | |
static void AssignExecutionOrderToMonoScripts() | |
{ | |
#if ENABLE_LOGGING | |
Dictionary<string, int[]> executionOrderLogging = new Dictionary<string, int[]>(); | |
#endif | |
// Lock Assemblies | |
EditorApplication.LockReloadAssemblies(); | |
foreach (MonoScript monoScript in MonoImporter.GetAllRuntimeMonoScripts()) | |
{ | |
Type monoClass = monoScript.GetClass(); | |
if( monoClass != null) | |
{ | |
Attribute att = Attribute.GetCustomAttribute(monoClass, typeof(ScriptExecutionAttribute)); | |
if( att != null) | |
{ | |
int executionOrderTarget = ((ScriptExecutionAttribute)att).executionIndex; | |
int executionOrderOriginal = MonoImporter.GetExecutionOrder(monoScript); | |
#if ENABLE_LOGGING | |
executionOrderLogging.Add( monoScript.name, new int[ 2 ] { executionOrderOriginal, executionOrderTarget } ); | |
#endif | |
#if ENABLE_ASSIGNMENT | |
// It is important not to set the execution order if the value is already correct! | |
if (executionOrderOriginal != executionOrderTarget) | |
{ | |
MonoImporter.SetExecutionOrder(monoScript, executionOrderTarget); | |
#if ENABLE_LOGGING | |
Debug.LogWarning(Decorate.Warning("The script " + monoScript.name + " was not set to correct Script Execution Order - it has been fixed and set to " + executionOrderTarget + " from " + executionOrderOriginal)); | |
#endif | |
} | |
#endif | |
} | |
} | |
} | |
// Unlock Assemblies | |
EditorApplication.UnlockReloadAssemblies(); | |
#if ENABLE_LOGGING | |
LogResults("ScriptExecutionAttribute", executionOrderLogging); | |
#endif | |
} | |
// Simple logging to console with the dictionary of found classes sorted by execution order. | |
static void LogResults( string title, Dictionary<string, int[]> results ) | |
{ | |
if ( results.Count > 0 ) | |
{ | |
string logging = title + ": Found Types\n"; | |
foreach ( KeyValuePair<string, int[]> item in results.OrderBy( key => key.Value[ 1 ] ) ) | |
logging += string.Format( "<color={0}>ScriptExecutionAttribute: Current: {0} Target: {1} Type: {2}</color>\n", item.Value[ 0 ], item.Value[ 1 ], item.Key, ( item.Value[ 0 ] == item.Value[ 1 ] ? "#F0F0F0" : "#FF0000" ) ); | |
Debug.Log( logging ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment