using log4net.Util; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using TexturePacker; using Unity.Collections; using Unity.Mathematics; using UnityEditor; using UnityEditor.Formats.Fbx.Exporter; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; using UnityEngine.UIElements; public sealed class TexturePackerEditor : EditorWindow { [SerializeField] private VisualTreeAsset m_VisualTreeAsset = default; private TextureMapInfo textureMapInfo; private Texture2D textureAtlas; private Texture2DArray textureArray; private IMGUIContainer imageListContainer; private List selectedTexs = new(); private List texRects = new(); private static Type gameObjectInspectorType; private List gameObjectInspectorView = new(); private List models = new(); private List modelRects = new(); private Button btApplyMesh; private Vector2 cellSize = new Vector2(100, 100); private const int MaxArraySize = 255; private int selectIndex = -1; private int selectIndexForMove = -1; private Vector2 toolbarOffset = new Vector2(0, 35); private int atlasPadding = 0; private static Func fnOpenPropertyEditor; private int textureSize = 512; private EditorWindow atlasPropertiesWindow = null; private EditorWindow arrayPropertiesWindow = null; private Label imgCntLabel = null; private Label infoLabel = null; private GraphicsFormat graphicsFormat = GraphicsFormat.R32G32B32A32_SFloat; private bool dockPreviewWindowFail = false; public enum ETextureSize { _128 = 1 << 7, _256 = 1 << 8, _512 = 1 << 9, _1024 = 1 << 10, } static readonly object fbxExportSetting = null; static Delegate exportObjectFunc; static TexturePackerEditor() { var editorCore = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name.Equals("UnityEditor.CoreModule")).FirstOrDefault(); var type = editorCore.GetType("UnityEditor.PropertyEditor"); var methodInfo = type.GetMethod("OpenPropertyEditor", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance, null, new Type[] { typeof(UnityEngine.Object), typeof(bool) }, null); fnOpenPropertyEditor = methodInfo.CreateDelegate(typeof(Func)) as Func; gameObjectInspectorType = editorCore.GetType("UnityEditor.GameObjectInspector"); var fbxAssembly = Assembly.GetAssembly(typeof(ModelExporter)); var exportMethodInfo = typeof(ModelExporter).GetMethod("ExportObject", BindingFlags.NonPublic | BindingFlags.Static); exportObjectFunc = exportMethodInfo.CreateDelegate(Expression.GetDelegateType(exportMethodInfo.GetParameters().Select(p => p.ParameterType).Concat(new[] { exportMethodInfo.ReturnType }).ToArray())); Type exportModelSettingsSerialize = fbxAssembly.GetType("UnityEditor.Formats.Fbx.Exporter.ExportModelSettingsSerialize"); fbxExportSetting = Activator.CreateInstance(exportModelSettingsSerialize); foreach (var item in exportModelSettingsSerialize.GetMethods().Union(exportModelSettingsSerialize.BaseType.GetMethods())) { switch (item.Name) { case "SetExportFormat": { item.Invoke(fbxExportSetting, new object[] { 1 }); item.Invoke(fbxExportSetting, new object[] { Enum.Parse(fbxAssembly.GetType("UnityEditor.Formats.Fbx.Exporter.ExportSettings+ExportFormat"), "1") }); break; } case "SetAnimatedSkinnedMesh": { item.Invoke(fbxExportSetting, new object[] { false }); break; } case "SetUseMayaCompatibleNames": { item.Invoke(fbxExportSetting, new object[] { false }); break; } case "SetModelAnimIncludeOption": { item.Invoke(fbxExportSetting, new object[] { Enum.Parse(fbxAssembly.GetType("UnityEditor.Formats.Fbx.Exporter.ExportSettings+Include"), "0") }); break; } case "SetLODExportType": { item.Invoke(fbxExportSetting, new object[] { Enum.Parse(fbxAssembly.GetType("UnityEditor.Formats.Fbx.Exporter.ExportSettings+LODExportType"), "0") }); break; } case "SetEmbedTextures": { item.Invoke(fbxExportSetting, new object[] { false }); break; } case "SetPreserveImportSettings": { item.Invoke(fbxExportSetting, new object[] { false }); break; } case "SetKeepInstances": { item.Invoke(fbxExportSetting, new object[] { false }); break; } case "SetExportUnredererd": { item.Invoke(fbxExportSetting, new object[] { false }); break; } default: break; } } } [MenuItem("Tools/Performance/TexturePackerEditor")] public static void OpenTexturePackerEditor() { TexturePackerEditor wnd = CreateInstance(); wnd.titleContent = new GUIContent("TexturePackerEditor"); wnd.Show(); } public static void OpenTexturePackerEditor(Texture2D[] textures) { TexturePackerEditor wnd = CreateInstance(); wnd.titleContent = new GUIContent("TexturePackerEditor"); for (int i = 0; i < textures.Length; i++) { wnd.AddTexture(textures[i]); } wnd.Show(); } [UnityEditor.Callbacks.OnOpenAsset(0)] private static bool OnOpenTextureMapInfo(int instanceID, int line) { var textureMapInfo = EditorUtility.InstanceIDToObject(instanceID) as TextureMapInfo; if (!textureMapInfo) { return false; } TexturePackerEditor wnd = GetWindow(); wnd.titleContent = new GUIContent("TexturePackerEditor"); wnd.InitWithTextureMapInfo(textureMapInfo); EditorApplication.delayCall += () => { wnd.UpdateResult(); }; return false; } private static readonly Color btNormalColor = ColorUtils.ToRGBA(0xFF585858); private static readonly Color btClikedColor = ColorUtils.ToRGBA(0xFF46607C); public void CreateGUI() { // Each editor window contains a root VisualElement object VisualElement root = rootVisualElement; // Instantiate UXML VisualElement labelFromUXML = m_VisualTreeAsset.Instantiate(); root.Add(labelFromUXML); var btArray = root.Q