public override async Task <bool> Load( string url, IDownloadProvider downloadProvider = null, IDeferAgent deferAgent = null, IMaterialGenerator materialGenerator = null, ILogger logger = null ) { importer = new GltfImport(downloadProvider, deferAgent, materialGenerator); var success = await importer.Load(url); if (success) { var insta = (GameObjectBoundsInstantiator)GetDefaultInstantiator(logger); // Auto-Instantiate if (sceneId >= 0) { success = importer.InstantiateScene(insta, sceneId); } else { success = importer.InstantiateMainScene(insta); } if (success) { SetBounds(insta); } } return(success); }
/// <summary> /// Method for manual loading with custom <see cref="IDownloadProvider"/> and <see cref="IDeferAgent"/>. /// </summary> /// <param name="url">URL of the glTF file.</param> /// <param name="downloadProvider">Download Provider for custom loading (e.g. caching or HTTP authorization)</param> /// <param name="deferAgent">Defer Agent takes care of interrupting the /// loading procedure in order to keep the frame rate responsive.</param> /// <param name="materialGenerator">Used to convert glTF materials to <see cref="Material"/> instances</param> /// <param name="logger">Used for message reporting</param> /// <returns>Async Task that loads the glTF's contents</returns> public virtual async Task <bool> Load( string url, IDownloadProvider downloadProvider = null, IDeferAgent deferAgent = null, IMaterialGenerator materialGenerator = null, ICodeLogger logger = null ) { importer = new GltfImport(downloadProvider, deferAgent, materialGenerator, logger); return(await importer.Load(url)); }
// static string[] GatherDependenciesFromSourceFile(string path) { // // Called before actual import for each changed asset that is imported by this importer type // // Extract the dependencies for the asset specified in path. // // For asset dependencies that are discovered, return them in the string array, where the string is the path to asset // // // TODO: Texture files with relative URIs should be included here // return null; // } public override void OnImportAsset(AssetImportContext ctx) { reportItems = null; var downloadProvider = new EditorDownloadProvider(); var logger = new CollectingLogger(); m_Gltf = new GltfImport( downloadProvider, new UninterruptedDeferAgent(), null, logger ); if (importSettings == null) { // Design-time import specific settings importSettings = new ImportSettings { // Avoid naming conflicts by default nodeNameMethod = ImportSettings.NameImportMethod.OriginalUnique }; } var success = AsyncHelpers.RunSync <bool>(() => m_Gltf.Load(ctx.assetPath, importSettings)); GameObjectInstantiator instantiator = null; CollectingLogger instantiationLogger = null; if (success) { m_ImportedNames = new HashSet <string>(); m_ImportedObjects = new HashSet <Object>(); var go = new GameObject("root"); instantiationLogger = new CollectingLogger(); instantiator = new GameObjectInstantiator(m_Gltf, go.transform, instantiationLogger); for (var sceneIndex = 0; sceneIndex < m_Gltf.sceneCount; sceneIndex++) { success = m_Gltf.InstantiateScene(instantiator, sceneIndex); if (!success) { break; } var sceneTransform = go.transform.GetChild(sceneIndex); var sceneGo = sceneTransform.gameObject; AddObjectToAsset(ctx, $"scenes/{sceneGo.name}", sceneGo); if (sceneIndex == m_Gltf.defaultSceneIndex) { ctx.SetMainObject(sceneGo); } } for (var i = 0; i < m_Gltf.textureCount; i++) { var texture = m_Gltf.GetTexture(i); if (texture != null) { AddObjectToAsset(ctx, $"textures/{texture.name}", texture); } } for (var i = 0; i < m_Gltf.materialCount; i++) { var mat = m_Gltf.GetMaterial(i); AddObjectToAsset(ctx, $"materials/{mat.name}", mat); } if (m_Gltf.defaultMaterial != null) { // If a default/fallback material was created, import it as well' // to avoid (pink) objects without materials var mat = m_Gltf.defaultMaterial; AddObjectToAsset(ctx, $"materials/{mat.name}", mat); } var meshes = m_Gltf.GetMeshes(); if (meshes != null) { foreach (var mesh in meshes) { AddObjectToAsset(ctx, $"meshes/{mesh.name}", mesh); } } var clips = m_Gltf.GetAnimationClips(); if (clips != null) { foreach (var animationClip in clips) { AddObjectToAsset(ctx, $"animations/{animationClip.name}", animationClip); } } m_ImportedNames = null; m_ImportedObjects = null; } var deps = new List <GltfAssetDependency>(); for (var index = 0; index < downloadProvider.assetDependencies.Count; index++) { var dependency = downloadProvider.assetDependencies[index]; if (ctx.assetPath == dependency.originalUri) { // Skip original gltf/glb file continue; } var guid = AssetDatabase.AssetPathToGUID(dependency.originalUri); if (!string.IsNullOrEmpty(guid)) { dependency.assetPath = dependency.originalUri; ctx.DependsOnSourceAsset(dependency.assetPath); } deps.Add(dependency); } assetDependencies = deps.ToArray(); var reportItemList = new List <LogItem>(); reportItemList.AddRange(logger.items); if (instantiationLogger?.items != null) { reportItemList.AddRange(instantiationLogger.items); } reportItems = reportItemList.ToArray(); }
// static string[] GatherDependenciesFromSourceFile(string path) { // // Called before actual import for each changed asset that is imported by this importer type // // Extract the dependencies for the asset specified in path. // // For asset dependencies that are discovered, return them in the string array, where the string is the path to asset // // // TODO: Texture files with relative URIs should be included here // return null; // } public override void OnImportAsset(AssetImportContext ctx) { reportItems = null; var downloadProvider = new EditorDownloadProvider(); var logger = new CollectingLogger(); m_Gltf = new GltfImport( downloadProvider, new UninterruptedDeferAgent(), null, logger ); if (editorImportSettings == null) { // Design-time import specific settings editorImportSettings = new EditorImportSettings(); } if (importSettings == null) { // Design-time import specific changes to default settings importSettings = new ImportSettings { // Avoid naming conflicts by default nodeNameMethod = ImportSettings.NameImportMethod.OriginalUnique, generateMipMaps = true, animationMethod = ImportSettings.AnimationMethod.Mecanim, }; } var success = AsyncHelpers.RunSync(() => m_Gltf.Load(ctx.assetPath, importSettings)); CollectingLogger instantiationLogger = null; if (success) { m_ImportedNames = new HashSet <string>(); m_ImportedObjects = new HashSet <Object>(); if (instantiationSettings.sceneObjectCreation == InstantiationSettings.SceneObjectCreation.Never) { // There *has* to be a common parent GameObject that gets // added to the ScriptedImporter, so we overrule this // setting. instantiationSettings.sceneObjectCreation = InstantiationSettings.SceneObjectCreation.WhenMultipleRootNodes; Debug.LogWarning("SceneObjectCreation setting \"Never\" is not available for Editor (design-time) imports. Falling back to WhenMultipleRootNodes.", this); } instantiationLogger = new CollectingLogger(); for (var sceneIndex = 0; sceneIndex < m_Gltf.sceneCount; sceneIndex++) { var scene = m_Gltf.GetSourceScene(sceneIndex); var sceneName = m_Gltf.GetSceneName(sceneIndex); var go = new GameObject(sceneName); var instantiator = new GameObjectInstantiator(m_Gltf, go.transform, instantiationLogger, instantiationSettings); success = m_Gltf.InstantiateScene(instantiator, sceneIndex); if (!success) { break; } var useFirstChild = true; var multipleNodes = scene.nodes.Length > 1; var hasAnimation = false; if (importSettings.animationMethod != ImportSettings.AnimationMethod.None && (instantiationSettings.mask & ComponentType.Animation) != 0) { var animationClips = m_Gltf.GetAnimationClips(); if (animationClips != null && animationClips.Length > 0) { hasAnimation = true; } } if (instantiationSettings.sceneObjectCreation == InstantiationSettings.SceneObjectCreation.Never || instantiationSettings.sceneObjectCreation == InstantiationSettings.SceneObjectCreation.WhenMultipleRootNodes && !multipleNodes) { // No scene GameObject was created, so the first // child is the first (and in this case only) node. // If there's animation, its clips' paths are relative // to the root GameObject (which will also carry the // `Animation` component. If not, we can import the the // first and only node as root directly. useFirstChild = !hasAnimation; } var sceneTransform = useFirstChild ? go.transform.GetChild(0) : go.transform; var sceneGo = sceneTransform.gameObject; AddObjectToAsset(ctx, $"scenes/{sceneName}", sceneGo); if (sceneIndex == m_Gltf.defaultSceneIndex) { ctx.SetMainObject(sceneGo); } } for (var i = 0; i < m_Gltf.textureCount; i++) { var texture = m_Gltf.GetTexture(i); if (texture != null) { var textureAssetPath = AssetDatabase.GetAssetPath(texture); if (string.IsNullOrEmpty(textureAssetPath)) { AddObjectToAsset(ctx, $"textures/{texture.name}", texture); } } } for (var i = 0; i < m_Gltf.materialCount; i++) { var mat = m_Gltf.GetMaterial(i); if (mat != null) { AddObjectToAsset(ctx, $"materials/{mat.name}", mat); } } if (m_Gltf.defaultMaterial != null) { // If a default/fallback material was created, import it as well' // to avoid (pink) objects without materials var mat = m_Gltf.defaultMaterial; AddObjectToAsset(ctx, $"materials/{mat.name}", mat); } var meshes = m_Gltf.GetMeshes(); if (meshes != null) { foreach (var mesh in meshes) { if (mesh == null) { continue; } if (editorImportSettings.generateSecondaryUVSet && !HasSecondaryUVs(mesh)) { Unwrapping.GenerateSecondaryUVSet(mesh); } AddObjectToAsset(ctx, $"meshes/{mesh.name}", mesh); } } #if UNITY_ANIMATION var clips = m_Gltf.GetAnimationClips(); if (clips != null) { foreach (var animationClip in clips) { if (animationClip == null) { continue; } if (importSettings.animationMethod == ImportSettings.AnimationMethod.Mecanim) { var settings = AnimationUtility.GetAnimationClipSettings(animationClip); settings.loopTime = true; AnimationUtility.SetAnimationClipSettings(animationClip, settings); } AddObjectToAsset(ctx, $"animations/{animationClip.name}", animationClip); } } // TODO seems the states don't properly connect to the Animator here // (would need to be saved as SubAssets of the AnimatorController) // var animators = go.GetComponentsInChildren<Animator>(); // foreach (var animator in animators) // { // var controller = animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController; // if (controller != null) { // AddObjectToAsset(ctx, $"animatorControllers/{animator.name}", controller); // foreach (var layer in controller.layers) // { // var stateMachine = layer.stateMachine; // stateMachine.hideFlags = HideFlags.HideInHierarchy; // if(stateMachine) // AddObjectToAsset(ctx, $"animatorControllers/{animator.name}/{stateMachine.name}", stateMachine); // } // } // } #endif m_ImportedNames = null; m_ImportedObjects = null; } var deps = new List <GltfAssetDependency>(); for (var index = 0; index < downloadProvider.assetDependencies.Count; index++) { var dependency = downloadProvider.assetDependencies[index]; if (ctx.assetPath == dependency.originalUri) { // Skip original gltf/glb file continue; } var guid = AssetDatabase.AssetPathToGUID(dependency.originalUri); if (!string.IsNullOrEmpty(guid)) { dependency.assetPath = dependency.originalUri; ctx.DependsOnSourceAsset(dependency.assetPath); } deps.Add(dependency); } assetDependencies = deps.ToArray(); var reportItemList = new List <LogItem>(); if (logger.Count > 0) { reportItemList.AddRange(logger.Items); } if (instantiationLogger?.Items != null) { reportItemList.AddRange(instantiationLogger.Items); } if (reportItemList.Any(x => x.type == LogType.Error || x.type == LogType.Exception)) { Debug.LogError($"Failed to import {assetPath} (see inspector for details)", this); } reportItems = reportItemList.ToArray(); }
// static string[] GatherDependenciesFromSourceFile(string path) { // // Called before actual import for each changed asset that is imported by this importer type // // Extract the dependencies for the asset specified in path. // // For asset dependencies that are discovered, return them in the string array, where the string is the path to asset // // // TODO: Texture files with relative URIs should be included here // return null; // } public override void OnImportAsset(AssetImportContext ctx) { reportItems = null; var downloadProvider = new EditorDownloadProvider(); var logger = new CollectingLogger(); m_Gltf = new GltfImport( downloadProvider, new UninterruptedDeferAgent(), null, logger ); if (editorImportSettings == null) { // Design-time import specific settings editorImportSettings = new EditorImportSettings(); } if (importSettings == null) { // Design-time import specific changes to default settings importSettings = new ImportSettings { // Avoid naming conflicts by default nodeNameMethod = ImportSettings.NameImportMethod.OriginalUnique }; } var success = AsyncHelpers.RunSync <bool>(() => m_Gltf.Load(ctx.assetPath, importSettings)); GameObjectInstantiator instantiator = null; CollectingLogger instantiationLogger = null; if (success) { m_ImportedNames = new HashSet <string>(); m_ImportedObjects = new HashSet <Object>(); var go = new GameObject("root"); instantiationLogger = new CollectingLogger(); instantiator = new GameObjectInstantiator(m_Gltf, go.transform, instantiationLogger); for (var sceneIndex = 0; sceneIndex < m_Gltf.sceneCount; sceneIndex++) { success = m_Gltf.InstantiateScene(instantiator, sceneIndex); if (!success) { break; } var sceneTransform = go.transform.GetChild(sceneIndex); var sceneGo = sceneTransform.gameObject; AddObjectToAsset(ctx, $"scenes/{sceneGo.name}", sceneGo); if (sceneIndex == m_Gltf.defaultSceneIndex) { ctx.SetMainObject(sceneGo); } } for (var i = 0; i < m_Gltf.textureCount; i++) { var texture = m_Gltf.GetTexture(i); if (texture != null) { var assetPath = AssetDatabase.GetAssetPath(texture); if (string.IsNullOrEmpty(assetPath)) { AddObjectToAsset(ctx, $"textures/{texture.name}", texture); } } } for (var i = 0; i < m_Gltf.materialCount; i++) { var mat = m_Gltf.GetMaterial(i); AddObjectToAsset(ctx, $"materials/{mat.name}", mat); } if (m_Gltf.defaultMaterial != null) { // If a default/fallback material was created, import it as well' // to avoid (pink) objects without materials var mat = m_Gltf.defaultMaterial; AddObjectToAsset(ctx, $"materials/{mat.name}", mat); } var meshes = m_Gltf.GetMeshes(); if (meshes != null) { foreach (var mesh in meshes) { if (editorImportSettings.generateSecondaryUVSet && !HasSecondaryUVs(mesh)) { Unwrapping.GenerateSecondaryUVSet(mesh); } AddObjectToAsset(ctx, $"meshes/{mesh.name}", mesh); } } #if UNITY_ANIMATION var clips = m_Gltf.GetAnimationClips(); if (clips != null) { foreach (var animationClip in clips) { if (importSettings.animationMethod == ImportSettings.AnimationMethod.Mecanim) { var settings = AnimationUtility.GetAnimationClipSettings(animationClip); settings.loopTime = true; AnimationUtility.SetAnimationClipSettings(animationClip, settings); } AddObjectToAsset(ctx, $"animations/{animationClip.name}", animationClip); } } // TODO seems the states don't properly connect to the Animator here // (would need to be saved as SubAssets of the AnimatorController) // var animators = go.GetComponentsInChildren<Animator>(); // foreach (var animator in animators) // { // var controller = animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController; // if (controller != null) { // AddObjectToAsset(ctx, $"animatorControllers/{animator.name}", controller); // foreach (var layer in controller.layers) // { // var stateMachine = layer.stateMachine; // stateMachine.hideFlags = HideFlags.HideInHierarchy; // if(stateMachine) // AddObjectToAsset(ctx, $"animatorControllers/{animator.name}/{stateMachine.name}", stateMachine); // } // } // } #endif m_ImportedNames = null; m_ImportedObjects = null; } var deps = new List <GltfAssetDependency>(); for (var index = 0; index < downloadProvider.assetDependencies.Count; index++) { var dependency = downloadProvider.assetDependencies[index]; if (ctx.assetPath == dependency.originalUri) { // Skip original gltf/glb file continue; } var guid = AssetDatabase.AssetPathToGUID(dependency.originalUri); if (!string.IsNullOrEmpty(guid)) { dependency.assetPath = dependency.originalUri; ctx.DependsOnSourceAsset(dependency.assetPath); } deps.Add(dependency); } assetDependencies = deps.ToArray(); var reportItemList = new List <LogItem>(); if (logger.items != null) { reportItemList.AddRange(logger.items); } if (instantiationLogger?.items != null) { reportItemList.AddRange(instantiationLogger.items); } reportItems = reportItemList.ToArray(); }