using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEditor.Experimental.AssetImporters; using UnityEngine; using VrmLib; namespace UniVRM10 { #if flase [ScriptedImporter(1, "glb")] #endif public class GltfScriptedImporter : ScriptedImporter, IExternalUnityObject { const string TextureDirName = "Textures"; const string MaterialDirName = "Materials"; public override void OnImportAsset(AssetImportContext ctx) { Debug.Log("OnImportAsset to " + ctx.assetPath); try { // Create model VrmLib.Model model = CreateGlbModel(ctx.assetPath); Debug.Log($"ModelLoader.Load: {model}"); // Build Unity Model var assets = EditorUnityBuilder.ToUnityAsset(model, assetPath, this); // Texture var externalTextures = this.GetExternalUnityObjects(); foreach (var texture in assets.Textures) { if (texture == null) continue; if (externalTextures.ContainsValue(texture)) { } else { ctx.AddObjectToAsset(texture.name, texture); } } // Material var externalMaterials = this.GetExternalUnityObjects(); foreach (var material in assets.Materials) { if (material == null) continue; if (externalMaterials.ContainsValue(material)) { } else { ctx.AddObjectToAsset(material.name, material); } } // Mesh foreach (var mesh in assets.Meshes) { ctx.AddObjectToAsset(mesh.name, mesh); } // Root ctx.AddObjectToAsset(assets.Root.name, assets.Root); ctx.SetMainObject(assets.Root); } catch (System.Exception ex) { Debug.LogError(ex); } } private Model CreateGlbModel(string path) { var bytes = File.ReadAllBytes(path); if (!UniGLTF.Glb.TryParse(bytes, out UniGLTF.Glb glb, out Exception ex)) { throw ex; } VrmLib.Model model = null; VrmLib.IVrmStorage storage; storage = new Vrm10Storage(glb.Json.Bytes, glb.Binary.Bytes); model = VrmLib.ModelLoader.Load(storage, Path.GetFileNameWithoutExtension(path)); model.ConvertCoordinate(VrmLib.Coordinates.Unity); return model; } public void ExtractTextures() { this.ExtractTextures(TextureDirName, (path) => { return CreateGlbModel(path); }); AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); } public void ExtractMaterials() { this.ExtractAssets(MaterialDirName, ".mat"); AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); } public void ExtractMaterialsAndTextures() { this.ExtractTextures(TextureDirName, (path) => { return CreateGlbModel(path); }, () => { this.ExtractAssets(MaterialDirName, ".mat"); }); AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); } public Dictionary GetExternalUnityObjects() where T : UnityEngine.Object { return this.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)).ToDictionary(x => x.Key.name, x => (T)x.Value); } public void SetExternalUnityObject(UnityEditor.AssetImporter.SourceAssetIdentifier sourceAssetIdentifier, T obj) where T : UnityEngine.Object { this.AddRemap(sourceAssetIdentifier, obj); AssetDatabase.WriteImportSettingsIfDirty(this.assetPath); AssetDatabase.ImportAsset(this.assetPath, ImportAssetOptions.ForceUpdate); } } }