160 lines
6.1 KiB
C#
160 lines
6.1 KiB
C#
|
using UnityEngine;
|
|||
|
using UnityEngine.UI;
|
|||
|
using System.Collections;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using System.Reflection;
|
|||
|
#if UNITY_EDITOR
|
|||
|
using UnityEditor;
|
|||
|
#endif
|
|||
|
|
|||
|
namespace MoreMountains.Tools
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Add this attribute to a class and its Execution Order will be changed to the value specified in parameters
|
|||
|
/// Usage : [ExecutionOrder(66)]
|
|||
|
/// </summary>
|
|||
|
public class MMExecutionOrderAttribute : Attribute
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
/// the execution order you want for the class this attribute is applied to
|
|||
|
public int ExecutionOrder = 0;
|
|||
|
|
|||
|
protected static Dictionary<MonoScript, MMExecutionOrderAttribute> _monoScripts;
|
|||
|
protected static Type _executionOrderAttributeType;
|
|||
|
protected static Assembly _typeAssembly;
|
|||
|
protected static Type[] _assemblyTypes;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attribute method
|
|||
|
/// </summary>
|
|||
|
/// <param name="newExecutionOrder"></param>
|
|||
|
public MMExecutionOrderAttribute(int newExecutionOrder)
|
|||
|
{
|
|||
|
ExecutionOrder = newExecutionOrder;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// When Unity loads, modifies the execution orders of monos with an ExecutionOrder attribute, if needed
|
|||
|
/// </summary>
|
|||
|
[InitializeOnLoadMethod]
|
|||
|
protected static void ModifyExecutionOrder()
|
|||
|
{
|
|||
|
Initialization();
|
|||
|
|
|||
|
FindExecutionOrderAttributes();
|
|||
|
|
|||
|
if (ExecutionOrderHasChanged())
|
|||
|
{
|
|||
|
UpdateExecutionOrders();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialization method
|
|||
|
/// </summary>
|
|||
|
protected static void Initialization()
|
|||
|
{
|
|||
|
_monoScripts = new Dictionary<MonoScript, MMExecutionOrderAttribute>();
|
|||
|
_executionOrderAttributeType = typeof(MMExecutionOrderAttribute);
|
|||
|
_typeAssembly = _executionOrderAttributeType.Assembly;
|
|||
|
_assemblyTypes = _typeAssembly.GetTypes();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Goes through all assembly types and stores execution order attributes when found
|
|||
|
/// </summary>
|
|||
|
protected static void FindExecutionOrderAttributes()
|
|||
|
{
|
|||
|
foreach (Type assemblyType in _assemblyTypes)
|
|||
|
{
|
|||
|
if (!HasExecutionOrderAttribute(assemblyType))
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
object[] attributes = assemblyType.GetCustomAttributes(_executionOrderAttributeType, false);
|
|||
|
MMExecutionOrderAttribute attribute = attributes[0] as MMExecutionOrderAttribute;
|
|||
|
|
|||
|
string asset = "";
|
|||
|
string[] guids = AssetDatabase.FindAssets(assemblyType.Name + " t:script");
|
|||
|
|
|||
|
if (guids.Length != 0)
|
|||
|
{
|
|||
|
foreach (string guid in guids)
|
|||
|
{
|
|||
|
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
|||
|
string filename = Path.GetFileNameWithoutExtension(assetPath);
|
|||
|
if (filename == assemblyType.Name)
|
|||
|
{
|
|||
|
asset = guid;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogError("MMTools' ExecutionOrderAttribute : Can't change "+ assemblyType.Name + "'s execution order");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
MonoScript monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(AssetDatabase.GUIDToAssetPath(asset));
|
|||
|
_monoScripts.Add(monoScript, attribute);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns true if the class in parameters has the ExecutionOrder attribute, false otherwise
|
|||
|
/// </summary>
|
|||
|
/// <param name="assemblyType"></param>
|
|||
|
/// <returns></returns>
|
|||
|
protected static bool HasExecutionOrderAttribute(Type assemblyType)
|
|||
|
{
|
|||
|
object[] attributes = assemblyType.GetCustomAttributes(_executionOrderAttributeType, false);
|
|||
|
return (attributes.Length == 1);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns true if the execution order has changed since last time
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
protected static bool ExecutionOrderHasChanged()
|
|||
|
{
|
|||
|
bool executionOrderHasChanged = false;
|
|||
|
foreach (KeyValuePair<MonoScript, MMExecutionOrderAttribute> monoScript in _monoScripts)
|
|||
|
{
|
|||
|
if (monoScript.Key != null)
|
|||
|
{
|
|||
|
if (MonoImporter.GetExecutionOrder(monoScript.Key) != monoScript.Value.ExecutionOrder)
|
|||
|
{
|
|||
|
executionOrderHasChanged = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return executionOrderHasChanged;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Updates the execution orders for all pairs found by FindExecutionOrderAttributes()
|
|||
|
/// </summary>
|
|||
|
protected static void UpdateExecutionOrders()
|
|||
|
{
|
|||
|
foreach (KeyValuePair<MonoScript, MMExecutionOrderAttribute> monoScript in _monoScripts)
|
|||
|
{
|
|||
|
if (monoScript.Key != null)
|
|||
|
{
|
|||
|
if (MonoImporter.GetExecutionOrder(monoScript.Key) != monoScript.Value.ExecutionOrder)
|
|||
|
{
|
|||
|
MonoImporter.SetExecutionOrder(monoScript.Key, monoScript.Value.ExecutionOrder);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|