控制Unity中脚本的运行顺序

思路就是先拿到脚本和脚本挂的特性值 然后使用monoImportor.Set修改执行顺序

using System;
using System.Collections.Generic;
#if UNITY_EDITOR
using System.IO;
using UnityEditor;
#endif
using UnityEngine;

[AttributeUsage( AttributeTargets.Class, Inherited = false, AllowMultiple = false )]
sealed class ExecutionOrderAttribute : Attribute {

    public readonly int ExecutionOrder = 0;

    public ExecutionOrderAttribute( int executionOrder ) {
        ExecutionOrder = executionOrder;
    }

#if UNITY_EDITOR
    private const string PB_TITLE = "Updating Execution Order";
    private const string PB_MESSAGE = "Hold on to your butt, Cap'n!";
    private const string ERR_MESSAGE = "Unable to locate and set execution order for {0}";



    //这个特性类似 InitializeLoad   点击运行的时候会加载脚本  或者你在vs修改了什么东西 也会加载一次
    [InitializeOnLoadMethod]
    private static void Execute() {
        //用类型拿到这个程序集中所有的脚本 
        Type type = typeof( ExecutionOrderAttribute );

        //我糙  真是服了  用var居然不用引用命名空间
        var assembly = type.Assembly;

        //可以尝试进行打印查看程序及中的类集合 
        Type[] types = assembly.GetTypes();

        var scripts = new Dictionary<MonoScript, ExecutionOrderAttribute>();

        var progress = 0f;
        var step = 1f / types.Length;

        foreach ( var item in types ) {
            //拿到类身上的特性
            var attributes = item.GetCustomAttributes( type, false );

            //如果脚本上的特性大于一个跳过继续
            if ( attributes.Length != 1 )
                continue;

            var attribute = attributes[0] as ExecutionOrderAttribute;

            var asset = "";

            //从Asset中拿到这个脚本的唯一标识符(就是哪个guid特性里面的值)
            var guids = AssetDatabase.FindAssets( string.Format( "{0} t:script", item.Name ) );

            if ( guids.Length > 1 ) {
                foreach ( var guid in guids ) {
                    var assetPath = AssetDatabase.GUIDToAssetPath( guid );
                    var filename = Path.GetFileNameWithoutExtension( assetPath );
                    if ( filename == item.Name ) {
                        asset = guid;
                        break;
                    }
                }
            } else if ( guids.Length == 1 ) {
                asset = guids[0];
            } else {
                Debug.LogErrorFormat( ERR_MESSAGE, item.Name );
                return;
            }
            //将guid码转化为资源路径然后加载对应的脚本
            MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>( AssetDatabase.GUIDToAssetPath( asset ) );

            //将脚本和对应的特性加载到集合中
            scripts.Add( script, attribute );
        }

        bool changed = false;
        foreach ( var item in scripts ) {
            //查看七楼八楼的对应解释
            //https://forum.unity.com/threads/script-execution-order-manipulation.130805/
            if ( MonoImporter.GetExecutionOrder( item.Key ) != item.Value.ExecutionOrder ) {
                changed = true;
                break;
            }
        }

        if ( changed ) {
            foreach ( var item in scripts ) {
                var cancelled = EditorUtility.DisplayCancelableProgressBar( PB_TITLE, PB_MESSAGE, progress );
                progress += step;
                if ( MonoImporter.GetExecutionOrder( item.Key ) != item.Value.ExecutionOrder ) {
                    MonoImporter.SetExecutionOrder( item.Key, item.Value.ExecutionOrder );
                }

                if ( cancelled ) break;
            }
        }

        Debug.Log("排序行为执行");

        EditorUtility.ClearProgressBar();
    }
#endif
}

  

猜你喜欢

转载自www.cnblogs.com/chenggg/p/10781462.html