Unity 快速平台切换

Unity 快速平台切换_第1张图片
Paste_Image.png

https://www.assetstore.unity3d.com/en/#!/content/11134
本文参考Fast Platform Switch,开发所使用的Unity版本为5.3.4f1。

using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

public class FastBuildPlayerWindow : EditorWindow
{
    private EditorWindow buildPlayerWindow;

    void Awake()
    {
        var unityEditor = Assembly.LoadFile(EditorApplication.applicationContentsPath + "/Managed/UnityEditor.dll");
        var buildPlayerWindowType = unityEditor.GetType("UnityEditor.BuildPlayerWindow");

        var array = Resources.FindObjectsOfTypeAll(buildPlayerWindowType);
        var noBuildPlayerWindow = array == null || array.Length <= 0;

        buildPlayerWindow = GetWindow(buildPlayerWindowType, true);

        minSize = buildPlayerWindow.minSize;
        maxSize = buildPlayerWindow.maxSize;
        position = buildPlayerWindow.position;
        titleContent = buildPlayerWindow.titleContent;

        if(noBuildPlayerWindow)
            buildPlayerWindow.Close();
    }

    void OnDestroy()
    {

    }

    static BuildTarget GetSelectedBuildTarget()
    {
        switch (EditorUserBuildSettings.selectedBuildTargetGroup)
        {
        case BuildTargetGroup.WebPlayer:
            if(EditorUserBuildSettings.webPlayerStreamed)
                return BuildTarget.WebPlayerStreamed;

            return BuildTarget.WebPlayer;

        case BuildTargetGroup.Standalone:
            return EditorUserBuildSettings.selectedStandaloneTarget;

        case BuildTargetGroup.iOS:
            return BuildTarget.iOS;

        case BuildTargetGroup.Android:
            return BuildTarget.Android;

        case BuildTargetGroup.tvOS:
            return BuildTarget.tvOS;

        case BuildTargetGroup.Tizen:
            return BuildTarget.Tizen;

        case BuildTargetGroup.XBOX360:
            return BuildTarget.XBOX360;

        case BuildTargetGroup.XboxOne:
            return BuildTarget.XboxOne;

        case BuildTargetGroup.PS3:
            return BuildTarget.PS3;

        case BuildTargetGroup.PSP2:
            return BuildTarget.PSP2;

        case BuildTargetGroup.PS4:
            return BuildTarget.PS4;

        case BuildTargetGroup.WSA:
            return BuildTarget.WSAPlayer;

        case BuildTargetGroup.WebGL:
            return BuildTarget.WebGL;

        case BuildTargetGroup.SamsungTV:
            return BuildTarget.SamsungTV;

        default:
            return EditorUserBuildSettings.activeBuildTarget;
        }
    }

    static void DirectoryMerge(string sourceDirName, string destDirName)
    {
        if (!Directory.Exists(sourceDirName))
            return;

        const string title = "Hold On";

        string info = "Delete files from dest not in source";
        float progress = 0;

        if (Directory.Exists(destDirName))
        {
            var destFiles = Directory.GetFiles(destDirName, "*.*", SearchOption.AllDirectories);
            foreach (var file in destFiles)
            {
                if (!File.Exists(sourceDirName + file.Remove(0, destDirName.Length)))
                    File.Delete(file);

                progress += 1.0f / destFiles.Length;
                EditorUtility.DisplayProgressBar(title, info, progress);
            }
        }

        info = "Copy changed and new files from source to dest";
        progress = 0;

        // Then copy changed and new files from source to dest
        var sourceFiles = Directory.GetFiles(sourceDirName, "*.*", SearchOption.AllDirectories);
        foreach (var file in sourceFiles)
        {
            var destFile = destDirName + file.Remove(0, sourceDirName.Length);

            progress += 1.0f / sourceFiles.Length;
            EditorUtility.DisplayProgressBar(title, info, progress);

            if (File.Exists(destFile) && File.GetLastWriteTimeUtc(file) == File.GetLastWriteTimeUtc(destFile) && new FileInfo(file).Length == new FileInfo(destFile).Length)
                continue;

            Directory.CreateDirectory(Path.GetDirectoryName(destFile));

            File.Copy(file, destFile, true);
            File.SetCreationTime(destFile, File.GetCreationTime(file));
            File.SetLastAccessTime(destFile, File.GetLastAccessTime(file));
            File.SetLastWriteTime(destFile, File.GetLastWriteTime(file));
        }

        EditorUtility.ClearProgressBar();
    }

    void OnGUI()
    {
        try
        {
            buildPlayerWindow.Invoke("OnGUI");
        }
        catch (Exception)
        {

        }

        var activeBuildTarget = EditorUserBuildSettings.activeBuildTarget;
        var selectedBuildTarget = GetSelectedBuildTarget();

        GUI.enabled = selectedBuildTarget != activeBuildTarget && typeof(BuildPipeline).Invoke("IsBuildTargetSupported", selectedBuildTarget);

        GUILayout.BeginVertical();

        if (GUILayout.Button("Fast Switch Platform"))
        {
            const string metadataPath = "Library/metadata";

            var activeBuildTargetCachePath = "Fast Switch Platform/" + activeBuildTarget + "_metadata";
            var selectedBuildTargetCachePath = "Fast Switch Platform/" + selectedBuildTarget + "_metadata";

            DirectoryMerge(metadataPath, activeBuildTargetCachePath);

            DirectoryMerge(selectedBuildTargetCachePath, metadataPath);

            EditorUserBuildSettings.SwitchActiveBuildTarget(selectedBuildTarget);

            // Look for missing metadata files
            var currentAsset = 0;
            var assetPaths = AssetDatabase.GetAllAssetPaths();
            var assetCount = assetPaths.Length;

            AssetDatabase.StartAssetEditing();

            foreach (var path in assetPaths.Where(path => path.StartsWith("Assets")))
            {
                EditorUtility.DisplayProgressBar("Hold on", "Reimporting changed assets...", currentAsset / (float)assetCount);

                var filename = Path.GetFileName(path);
                var guid = AssetDatabase.AssetPathToGUID(path);
                if (!string.IsNullOrEmpty(guid) && !File.Exists(metadataPath + "/" + guid.Substring(0, 2) + "/" + guid))
                {
                    EditorUtility.DisplayProgressBar("Hold on", "Reimporting changed assets... (" + filename + ")", currentAsset / (float)assetCount);

                    AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
                }

                currentAsset++;
            }

            EditorUtility.DisplayProgressBar("Hold on", "Reimporting changed assets... (processing batch)", 1.0f);
            AssetDatabase.StopAssetEditing();

            EditorUtility.ClearProgressBar();

            AssetDatabase.Refresh();

            EditorUtility.ClearProgressBar();
        }

        GUILayout.Space(10f);

        GUILayout.EndVertical();
    }


    [DidReloadScripts]
    static void ReopenBuildPlayerWindow()
    {
        var array = Resources.FindObjectsOfTypeAll(typeof(FastBuildPlayerWindow));
        if (array == null || array.Length <= 0)
            return;

        GetWindow(true).Close();
        ShowBuildPlayerWindow();
    }

    [MenuItem("Window/Fast Switch Platform")]
    static void ShowBuildPlayerWindow()
    {
        GetWindow(true).Show();
    }
}
using System;
using System.Reflection;

public static class AccessExtensions
{
    public static T InvokeConstructor(this Type type, Type[] paramTypes = null, object[] paramValues = null)
    {
        return (T)type.InvokeConstructor(paramTypes, paramValues);
    }

    public static object InvokeConstructor(this Type type, Type[] paramTypes = null, object[] paramValues = null)
    {
        if (paramTypes == null || paramValues == null)
        {
            paramTypes = new Type[] { };
            paramValues = new object[] { };
        }

        var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null);

        return constructor.Invoke(paramValues);
    }

    public static T Invoke(this object o, string methodName, params object[] args)
    {
        var value = o.Invoke(methodName, args);
        if (value != null)
        {
            return (T)value;
        }

        return default(T);
    }

    public static T Invoke(this object o, string methodName, Type[] types, params object[] args)
    {
        var value = o.Invoke(methodName, types, args);
        if (value != null)
        {
            return (T)value;
        }

        return default(T);
    }

    public static object Invoke(this object o, string methodName, params object[] args)
    {
        Type[] types = new Type[args.Length];
        for (int i = 0; i < args.Length; i++)
            types[i] = args[i] == null ? null : args[i].GetType();

        return o.Invoke(methodName, types, args);
    }

    public static object Invoke(this object o, string methodName, Type[] types, params object[] args)
    {
        var invaild = Array.FindIndex(types, item => item == null) != -1;
        var type = o is Type ? (Type)o : o.GetType();

        var method = invaild ? type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) : type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, types, null);
        if(method != null)
            return method.Invoke(o, args);

        return null;
    }

    public static T GetFieldValue(this object o, string name)
    {
        var value = o.GetFieldValue(name);
        if (value != null)
        {
            return (T)value;
        }

        return default(T);
    }

    public static object GetFieldValue(this object o, string name)
    {
        var field = o.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        if (field != null)
        {
            return field.GetValue(o);
        }

        return null;
    }

    public static void SetFieldValue(this object o, string name, object value)
    {
        var field = o.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        if (field != null)
        {
            field.SetValue(o, value);
        }
    }

    public static T GetPropertyValue(this object o, string name)
    {
        var value = o.GetPropertyValue(name);
        if (value != null)
        {
            return (T)value;
        }

        return default(T);
    }

    public static object GetPropertyValue(this object o, string name)
    {
        var property = o.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        if (property != null)
        {
            return property.GetValue(o, null);
        }

        return null;
    }

    public static void SetPropertyValue(this object o, string name, object value)
    {
        var property = o.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        if (property != null)
        {
            property.SetValue(o, value, null);
        }
    }
}

你可能感兴趣的:(Unity 快速平台切换)