예제 #1
0
        /// <summary>
        /// Executes the given import request, producing a PtAsset and a prefab.
        /// </summary>
        /// <param name="request">The request to perform.</param>
        private static void ExecuteImportRequest(ImportRequest request)
        {
            PtDebug.LogFormat("Executing import request: {0}", request);

            string gltfFullPath   = PtUtils.ToAbsolutePath(request.gltfLocalPath);
            string assetLocalPath = request.ptAssetLocalPath;
            string assetFullPath  = PtUtils.ToAbsolutePath(assetLocalPath);

            PtAsset assetToReplace = AssetDatabase.LoadAssetAtPath <PtAsset>(assetLocalPath);

            GameObject prefabToReplace = null;

            if (assetToReplace != null)
            {
                if (assetToReplace.assetPrefab == null)
                {
                    Debug.LogErrorFormat("Couldn't find prefab for asset {0}.", assetToReplace);
                    PtAnalytics.SendEvent(PtAnalytics.Action.IMPORT_FAILED, "Prefab not found");
                    return;
                }
                prefabToReplace = assetToReplace.assetPrefab;
            }

            // Determine if file is glTF2 or glTF1.
            bool isGltf2 = Path.GetExtension(request.gltfLocalPath) == ".gltf2";

            // First, import the GLTF and build a GameObject from it.
            EditorUtility.DisplayProgressBar(PROGRESS_BAR_TITLE, PROGRESS_BAR_TEXT, 0.5f);
            // Use a SanitizedPath stream loader because any format file we have downloaded and saved to disk we
            // have replaced the original relative path string with the MD5 string hash. This custom stream loader
            // will always convert uris passed to it to this hash value, and read them from there.
            IUriLoader binLoader = new HashedPathBufferedStreamLoader(Path.GetDirectoryName(gltfFullPath));

            ImportGltf.GltfImportResult result = null;
            using (TextReader reader = new StreamReader(gltfFullPath)) {
                result = ImportGltf.Import(isGltf2 ? GltfSchemaVersion.GLTF2 : GltfSchemaVersion.GLTF1,
                                           reader, binLoader, request.options.baseOptions);
            }
            EditorUtility.ClearProgressBar();
            string baseName = PtUtils.GetPtAssetBaseName(request.polyAsset);

            result.root.name = baseName;

            // Create the asset (delete it first if it exists).
            if (File.Exists(assetFullPath))
            {
                AssetDatabase.DeleteAsset(assetLocalPath);

                // If we are replacing an existing asset, we should rename the replacement to the new name,
                // since the name reflects the identity of the asset. So if the user is importing the asset
                // dog_a381b3g to replace what was previously cat_v81938.asset, the replacement file should
                // be named dog_a381b3g.asset, not cat_v81938.asset.
                assetLocalPath = PtUtils.GetDefaultPtAssetPath(request.polyAsset);
                assetFullPath  = PtUtils.ToAbsolutePath(assetLocalPath);
            }
            Directory.CreateDirectory(Path.GetDirectoryName(assetFullPath));

            // Create the new PtAsset and fill it in.
            AssetDatabase.CreateAsset(ScriptableObject.CreateInstance <PtAsset>(), assetLocalPath);
            PtAsset newAsset = AssetDatabase.LoadAssetAtPath <PtAsset>(assetLocalPath);

            newAsset.name    = baseName;
            newAsset.title   = request.polyAsset.displayName ?? "";
            newAsset.author  = request.polyAsset.authorName ?? "";
            newAsset.license = request.polyAsset.license;
            newAsset.url     = request.polyAsset.Url;

            // Ensure the imported object has a PtAssetObject component which references the PtAsset.
            result.root.AddComponent <PtAssetObject>().asset = newAsset;

            // Add all the meshes to the PtAsset.
            SaveMeshes(result.meshes, newAsset);

            // If the asset has materials, save those to the PtAsset.
            if (result.materials != null)
            {
                SaveMaterials(result.materials, newAsset);
            }

            // If the asset has textures, save those to the PtAsset.
            if (result.textures != null)
            {
                SaveTextures(result.textures, newAsset);
            }

            // Reimport is required to ensure custom asset displays correctly.
            AssetDatabase.ImportAsset(assetLocalPath);

            GameObject newPrefab;

            if (prefabToReplace)
            {
                // Replace the existing prefab with our new object, without breaking prefab connections.
                newPrefab = PrefabUtility.ReplacePrefab(result.root, prefabToReplace, ReplacePrefabOptions.ReplaceNameBased);
                AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(newPrefab), baseName);
            }
            else
            {
                // Create a new prefab.
                // Prefab path is the same as the asset path but with the extension changed to '.prefab'.
                string prefabLocalPath = Regex.Replace(assetLocalPath, "\\.asset$", ".prefab");
                if (!prefabLocalPath.EndsWith(".prefab"))
                {
                    Debug.LogErrorFormat("Error: failed to compute prefab path for {0}", assetLocalPath);
                    PtAnalytics.SendEvent(PtAnalytics.Action.IMPORT_FAILED, "Prefab path error");
                    return;
                }
                newPrefab = PrefabUtility.CreatePrefab(prefabLocalPath, result.root);
            }

            // Now ensure the asset points to the prefab.
            newAsset.assetPrefab = newPrefab;
            if (newAsset.assetPrefab == null)
            {
                Debug.LogErrorFormat("Could not get asset prefab reference for asset {0}", newAsset);
                PtAnalytics.SendEvent(PtAnalytics.Action.IMPORT_FAILED, "Prefab ref error");
            }

            GameObject.DestroyImmediate(result.root);

            AssetDatabase.Refresh();

            if (request.options.alsoInstantiate)
            {
                PrefabUtility.InstantiatePrefab(newPrefab);
            }

            PtDebug.LogFormat("GLTF import complete: {0}", request);

            PtAnalytics.SendEvent(PtAnalytics.Action.IMPORT_SUCCESSFUL, isGltf2 ? "GLTF2" : "GLTF1");

            // If this is a third-party asset, we need to update the attributions file.
            AttributionFileGenerator.Generate(/* showUi */ false);

            EditorWindow.GetWindow <AssetBrowserWindow>().HandleAssetImported(request.polyAsset.name);

            // Select the prefab in the editor so the user knows where it is.
            AssetDatabase.Refresh();
            Selection.activeObject = newPrefab;
            EditorGUIUtility.PingObject(newPrefab);
        }