Пример #1
0
        // 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();
        }