Пример #1
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            byte[]    bytes         = File.ReadAllBytes(ctx.assetPath);
            Texture2D sourceTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false);

            sourceTexture.LoadImage(bytes);

            originalWidth  = sourceTexture.width;
            originalHeight = sourceTexture.height;

            cols = sourceTexture.width / pageSize;
            if (cols == 0)
            {
                cols = 1;
            }

            rows = sourceTexture.height / pageSize;
            if (rows == 0)
            {
                rows = 1;
            }

            bool changedPageSize = false;

            while (cols * rows > 2048)
            {
                pageSize       *= 2;
                cols           /= 2;
                rows           /= 2;
                changedPageSize = true;
            }

            if (changedPageSize)
            {
                ctx.LogImportWarning("Texture Width * Texture Height * Page Size must be less or equal to 2048, so the Page Size is increased to " + pageSize);
            }

            int resizeX = sourceTexture.width;
            int resizeY = sourceTexture.height;

            if (sourceTexture.width % pageSize != 0)
            {
                resizeX = cols * pageSize;
            }
            if (sourceTexture.height % pageSize != 0)
            {
                resizeY = rows * pageSize;
            }

            if (resizeX != sourceTexture.width || resizeY != sourceTexture.height)
            {
                TextureScaler.Scale(sourceTexture, resizeX, resizeY);
                ctx.LogImportWarning("The width and height of the texture must be equal to Page Size * N, so the texture size is changed to " + resizeX + "x" + resizeY);
            }

            Texture2DArray array = InitTexture2DArray(sourceTexture, ctx);

            ctx.AddObjectToAsset("_MainTex", array);
            ctx.SetMainObject(array);

            DestroyImmediate(sourceTexture);
        }
Пример #2
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            string     sceneName = null;
            GameObject gltfScene = null;

            UnityEngine.Mesh[] meshes = null;
            try
            {
                sceneName = Path.GetFileNameWithoutExtension(ctx.assetPath);
                gltfScene = CreateGLTFScene(ctx.assetPath);

                // Remove empty roots
                if (_removeEmptyRootObjects)
                {
                    var t = gltfScene.transform;
                    while (
                        gltfScene.transform.childCount == 1 &&
                        gltfScene.GetComponents <Component>().Length == 1)
                    {
                        var parent = gltfScene;
                        gltfScene = gltfScene.transform.GetChild(0).gameObject;
                        t         = gltfScene.transform;
                        t.parent  = null;                // To keep transform information in the new parent
                        Object.DestroyImmediate(parent); // Get rid of the parent
                    }
                }

                // Ensure there are no hide flags present (will cause problems when saving)
                gltfScene.hideFlags &= ~(HideFlags.HideAndDontSave);
                foreach (Transform child in gltfScene.transform)
                {
                    child.gameObject.hideFlags &= ~(HideFlags.HideAndDontSave);
                }

                // Zero position
                gltfScene.transform.position = Vector3.zero;

                // Get meshes
                var meshNames    = new List <string>();
                var meshHash     = new HashSet <UnityEngine.Mesh>();
                var meshFilters  = gltfScene.GetComponentsInChildren <MeshFilter>();
                var vertexBuffer = new List <Vector3>();
                meshes = meshFilters.Select(mf =>
                {
                    var mesh = mf.sharedMesh;
                    vertexBuffer.Clear();
                    mesh.GetVertices(vertexBuffer);
                    for (var i = 0; i < vertexBuffer.Count; ++i)
                    {
                        vertexBuffer[i] *= _scaleFactor;
                    }
                    mesh.SetVertices(vertexBuffer);
                    if (_swapUvs)
                    {
                        var uv   = mesh.uv;
                        var uv2  = mesh.uv2;
                        mesh.uv  = uv2;
                        mesh.uv2 = uv2;
                    }
                    if (_importNormals == GLTFImporterNormals.None)
                    {
                        mesh.normals = new Vector3[0];
                    }
                    if (_importNormals == GLTFImporterNormals.Calculate)
                    {
                        mesh.RecalculateNormals();
                    }
                    mesh.UploadMeshData(!_readWriteEnabled);

                    if (_generateColliders)
                    {
                        var collider        = mf.gameObject.AddComponent <MeshCollider>();
                        collider.sharedMesh = mesh;
                    }

                    if (meshHash.Add(mesh))
                    {
                        var meshName = string.IsNullOrEmpty(mesh.name) ? mf.gameObject.name : mesh.name;
                        mesh.name    = ObjectNames.GetUniqueName(meshNames.ToArray(), meshName);
                        meshNames.Add(mesh.name);
                    }

                    return(mesh);
                }).ToArray();

                var renderers = gltfScene.GetComponentsInChildren <Renderer>();

                if (_importMaterials)
                {
                    // Get materials
                    var materialNames = new List <string>();
                    var materialHash  = new HashSet <UnityEngine.Material>();
                    var materials     = renderers.SelectMany(r =>
                    {
                        return(r.sharedMaterials.Select(mat =>
                        {
                            if (materialHash.Add(mat))
                            {
                                var matName = string.IsNullOrEmpty(mat.name) ? mat.shader.name : mat.name;
                                if (matName == mat.shader.name)
                                {
                                    matName = matName.Substring(Mathf.Min(matName.LastIndexOf("/") + 1, matName.Length - 1));
                                }

                                // Ensure name is unique
                                matName = string.Format("{0} {1}", sceneName, ObjectNames.NicifyVariableName(matName));
                                matName = ObjectNames.GetUniqueName(materialNames.ToArray(), matName);

                                mat.name = matName;
                                materialNames.Add(matName);
                            }

                            return mat;
                        }));
                    }).ToArray();

                    // Get textures
                    var textureNames   = new List <string>();
                    var textureHash    = new HashSet <Texture2D>();
                    var texMaterialMap = new Dictionary <Texture2D, List <TexMaterialMap> >();
                    var textures       = materials.SelectMany(mat =>
                    {
                        var shader = mat.shader;
                        if (!shader)
                        {
                            return(Enumerable.Empty <Texture2D>());
                        }

                        var matTextures = new List <Texture2D>();
                        for (var i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i)
                        {
                            if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
                            {
                                var propertyName = ShaderUtil.GetPropertyName(shader, i);
                                var tex          = mat.GetTexture(propertyName) as Texture2D;
                                if (tex)
                                {
                                    if (textureHash.Add(tex))
                                    {
                                        var texName = tex.name;
                                        if (string.IsNullOrEmpty(texName))
                                        {
                                            if (propertyName.StartsWith("_"))
                                            {
                                                texName = propertyName.Substring(Mathf.Min(1, propertyName.Length - 1));
                                            }
                                        }

                                        // Ensure name is unique
                                        texName = string.Format("{0} {1}", sceneName, ObjectNames.NicifyVariableName(texName));
                                        texName = ObjectNames.GetUniqueName(textureNames.ToArray(), texName);

                                        tex.name = texName;
                                        textureNames.Add(texName);
                                        matTextures.Add(tex);
                                    }

                                    List <TexMaterialMap> materialMaps;
                                    if (!texMaterialMap.TryGetValue(tex, out materialMaps))
                                    {
                                        materialMaps = new List <TexMaterialMap>();
                                        texMaterialMap.Add(tex, materialMaps);
                                    }

                                    materialMaps.Add(new TexMaterialMap(mat, propertyName, propertyName == "_BumpMap"));
                                }
                            }
                        }
                        return(matTextures);
                    }).ToArray();

                    var folderName = Path.GetDirectoryName(ctx.assetPath);

                    // Save textures as separate assets and rewrite refs
                    // TODO: Support for other texture types
                    if (textures.Length > 0)
                    {
                        var texturesRoot = string.Concat(folderName, "/", "Textures/");
                        Directory.CreateDirectory(texturesRoot);

                        foreach (var tex in textures)
                        {
                            var ext     = _useJpgTextures ? ".jpg" : ".png";
                            var texPath = string.Concat(texturesRoot, tex.name, ext);
                            File.WriteAllBytes(texPath, _useJpgTextures ? tex.EncodeToJPG() : tex.EncodeToPNG());

                            AssetDatabase.ImportAsset(texPath);
                        }
                    }

                    // Save materials as separate assets and rewrite refs
                    if (materials.Length > 0)
                    {
                        var materialRoot = string.Concat(folderName, "/", "Materials/");
                        Directory.CreateDirectory(materialRoot);

                        foreach (var mat in materials)
                        {
                            var materialPath = string.Concat(materialRoot, mat.name, ".mat");
                            var newMat       = mat;
                            CopyOrNew(mat, materialPath, m =>
                            {
                                // Fix references
                                newMat = m;
                                foreach (var r in renderers)
                                {
                                    var sharedMaterials = r.sharedMaterials;
                                    for (var i = 0; i < sharedMaterials.Length; ++i)
                                    {
                                        var sharedMaterial = sharedMaterials[i];
                                        if (sharedMaterial.name == mat.name)
                                        {
                                            sharedMaterials[i] = m;
                                        }
                                    }
                                    sharedMaterials   = sharedMaterials.Where(sm => sm).ToArray();
                                    r.sharedMaterials = sharedMaterials;
                                }
                            });
                            // Fix textures
                            // HACK: This needs to be a delayed call.
                            // Unity needs a frame to kick off the texture import so we can rewrite the ref
                            if (textures.Length > 0)
                            {
                                EditorApplication.delayCall += () =>
                                {
                                    for (var i = 0; i < textures.Length; ++i)
                                    {
                                        var tex          = textures[i];
                                        var texturesRoot = string.Concat(folderName, "/", "Textures/");
                                        var ext          = _useJpgTextures ? ".jpg" : ".png";
                                        var texPath      = string.Concat(texturesRoot, tex.name, ext);

                                        // Grab new imported texture
                                        var materialMaps = texMaterialMap[tex];
                                        var importer     = (TextureImporter)TextureImporter.GetAtPath(texPath);
                                        var importedTex  = AssetDatabase.LoadAssetAtPath <Texture2D>(texPath);
                                        if (importer != null)
                                        {
                                            var isNormalMap = false;
                                            foreach (var materialMap in materialMaps)
                                            {
                                                if (materialMap.Material == mat)
                                                {
                                                    isNormalMap |= materialMap.IsNormalMap;
                                                    newMat.SetTexture(materialMap.Property, importedTex);
                                                }
                                            }
                                            ;

                                            if (isNormalMap)
                                            {
                                                // Try to auto-detect normal maps
                                                importer.textureType = TextureImporterType.NormalMap;
                                            }
                                            else if (importer.textureType == TextureImporterType.Sprite)
                                            {
                                                // Force disable sprite mode, even for 2D projects
                                                importer.textureType = TextureImporterType.Default;
                                            }

                                            importer.SaveAndReimport();
                                        }
                                        else
                                        {
                                            Debug.LogWarning(string.Format("GLTFImporter: Unable to import texture at path: {0}", texPath));
                                        }
                                    }
                                };
                            }
                        }
                    }
                }
                else
                {
                    var temp = GameObject.CreatePrimitive(PrimitiveType.Plane);
                    temp.SetActive(false);
                    var defaultMat = new[] { temp.GetComponent <Renderer>().sharedMaterial };
                    DestroyImmediate(temp);

                    foreach (var rend in renderers)
                    {
                        rend.sharedMaterials = defaultMat;
                    }
                }
            }
            catch
            {
                if (gltfScene)
                {
                    DestroyImmediate(gltfScene);
                }
                throw;
            }

#if UNITY_2017_3_OR_NEWER
            // Set main asset
            ctx.AddObjectToAsset("main asset", gltfScene);

            // Add meshes
            foreach (var mesh in meshes)
            {
                ctx.AddObjectToAsset("mesh " + mesh.name, mesh);
            }

            ctx.SetMainObject(gltfScene);
#else
            // Set main asset
            ctx.SetMainAsset("main asset", gltfScene);

            // Add meshes
            foreach (var mesh in meshes)
            {
                ctx.AddSubAsset("mesh " + mesh.name, mesh);
            }
#endif
        }
Пример #3
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            {
                var ext = Path.GetExtension(ctx.assetPath).ToLower();
                if (ext == ".vox")
                {
                    fileType = VoxelBase.FileType.vox;
                }
                else if (ext == ".qb")
                {
                    fileType = VoxelBase.FileType.qb;
                }
                else
                {
                    return;
                }
            }
            var gameObject  = new GameObject(Path.GetFileNameWithoutExtension(ctx.assetPath));
            var voxelObject = gameObject.AddComponent <VoxelObject>();
            {
                voxelObject.legacyVoxImport      = legacyVoxImport;
                voxelObject.importMode           = importMode;
                voxelObject.importScale          = importScale;
                voxelObject.importOffset         = importOffset;
                voxelObject.combineFaces         = combineFaces;
                voxelObject.ignoreCavity         = ignoreCavity;
                voxelObject.voxelStructure       = outputStructure ? ScriptableObject.CreateInstance <VoxelStructure>() : null;
                voxelObject.generateLightmapUVs  = generateLightmapUVs;
                voxelObject.meshFaceVertexOffset = meshFaceVertexOffset;
                voxelObject.loadFromVoxelFile    = loadFromVoxelFile;
                voxelObject.generateMipMaps      = generateMipMaps;
            }
            var objectCore = new VoxelObjectCore(voxelObject);

            try
            {
                if (!objectCore.Create(ctx.assetPath, null))
                {
                    Debug.LogErrorFormat("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath);
                    DestroyImmediate(gameObject);
                    return;
                }
            }
            catch
            {
                Debug.LogErrorFormat("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath);
                DestroyImmediate(gameObject);
                return;
            }

            #region Material
            if (retainExisting)
            {
                bool changed = false;
                var  assets  = AssetDatabase.LoadAllAssetsAtPath(ctx.assetPath);
                for (int i = 0; i < voxelObject.materials.Count; i++)
                {
                    var material = assets.FirstOrDefault(c => c.name == string.Format("mat{0}", i)) as Material;
                    if (material != null)
                    {
                        material.mainTexture     = voxelObject.atlasTexture;
                        voxelObject.materials[i] = material;
                        changed = true;
                    }
                }
                if (changed)
                {
                    var renderer = gameObject.GetComponent <MeshRenderer>();
                    renderer.sharedMaterials = voxelObject.materials.ToArray();
                }
            }
            #endregion

            #region Collider
            switch (colliderType)
            {
            case ColliderType.Box:
                gameObject.AddComponent <BoxCollider>();
                break;

            case ColliderType.Sphere:
                gameObject.AddComponent <SphereCollider>();
                break;

            case ColliderType.Capsule:
                gameObject.AddComponent <CapsuleCollider>();
                break;

            case ColliderType.Mesh:
                gameObject.AddComponent <MeshCollider>();
                break;
            }
            #endregion

#if UNITY_2017_3_OR_NEWER
            ctx.AddObjectToAsset(gameObject.name, gameObject);
            ctx.AddObjectToAsset(voxelObject.mesh.name = "mesh", voxelObject.mesh);
            for (int i = 0; i < voxelObject.materials.Count; i++)
            {
                ctx.AddObjectToAsset(voxelObject.materials[i].name = string.Format("mat{0}", i), voxelObject.materials[i]);
            }
            ctx.AddObjectToAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
            if (voxelObject.voxelStructure != null)
            {
                ctx.AddObjectToAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
            }

            VoxelObject.DestroyImmediate(voxelObject);

            ctx.SetMainObject(gameObject);
#else
            ctx.SetMainAsset(gameObject.name, gameObject);
            ctx.AddSubAsset(voxelObject.mesh.name = "mesh", voxelObject.mesh);
            for (int i = 0; i < voxelObject.materials.Count; i++)
            {
                ctx.AddSubAsset(voxelObject.materials[i].name = string.Format("mat{0}", i), voxelObject.materials[i]);
            }
            ctx.AddSubAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
            if (voxelObject.voxelStructure != null)
            {
                ctx.AddSubAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
            }

            VoxelObject.DestroyImmediate(voxelObject);
#endif
        }
Пример #4
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;

            AssetCollection assetCollection = new AssetCollection();

            MinimalGraphData.GatherMinimalDependenciesFromFile(assetPath, assetCollection);

            var textGraph = File.ReadAllText(path, Encoding.UTF8);
            var graph     = new GraphData
            {
                messageManager = new MessageManager(), assetGuid = AssetDatabase.AssetPathToGUID(path)
            };

            MultiJson.Deserialize(graph, textGraph);
            graph.OnEnable();
            graph.ValidateGraph();

            Shader shader = null;

#if VFX_GRAPH_10_0_0_OR_NEWER
            if (!graph.isOnlyVFXTarget)
#endif
            {
                // build the shader text
                // this will also add Target dependencies into the asset collection
                var text = GetShaderText(path, out configuredTextures, assetCollection, graph);

#if UNITY_2021_1_OR_NEWER
                // 2021.1 or later is guaranteed to have the new version of this function
                shader = ShaderUtil.CreateShaderAsset(ctx, text, false);
#else
                // earlier builds of Unity may or may not have it
                // here we try to invoke the new version via reflection
                var createShaderAssetMethod = typeof(ShaderUtil).GetMethod(
                    "CreateShaderAsset",
                    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.ExactBinding,
                    null,
                    new Type[] { typeof(AssetImportContext), typeof(string), typeof(bool) },
                    null);

                if (createShaderAssetMethod != null)
                {
                    shader = createShaderAssetMethod.Invoke(null, new Object[] { ctx, text, false }) as Shader;
                }
                else
                {
                    // method doesn't exist in this version of Unity, call old version
                    // this doesn't create dependencies properly, but is the best that we can do
                    shader = ShaderUtil.CreateShaderAsset(text, false);
                }
#endif

                if (graph.messageManager.nodeMessagesChanged)
                {
                    foreach (var pair in graph.messageManager.GetNodeMessages())
                    {
                        var node = graph.GetNodeFromId(pair.Key);
                        MessageManager.Log(node, path, pair.Value.First(), shader);
                    }
                }

                EditorMaterialUtility.SetShaderDefaults(
                    shader,
                    configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
                EditorMaterialUtility.SetShaderNonModifiableDefaults(
                    shader,
                    configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
            }

            UnityEngine.Object mainObject = shader;
#if VFX_GRAPH_10_0_0_OR_NEWER
            ShaderGraphVfxAsset vfxAsset = null;
            if (graph.hasVFXTarget)
            {
                vfxAsset = GenerateVfxShaderGraphAsset(graph);
                if (mainObject == null)
                {
                    mainObject = vfxAsset;
                }
                else
                {
                    //Correct main object if we have a shader and ShaderGraphVfxAsset : save as sub asset
                    vfxAsset.name = Path.GetFileNameWithoutExtension(path);
                    ctx.AddObjectToAsset("VFXShaderGraph", vfxAsset);
                }
            }
#endif

            Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon");
            ctx.AddObjectToAsset("MainAsset", mainObject, texture);
            ctx.SetMainObject(mainObject);

            foreach (var target in graph.activeTargets)
            {
                if (target is IHasMetadata iHasMetadata)
                {
                    var metadata = iHasMetadata.GetMetadataObject();
                    if (metadata == null)
                    {
                        continue;
                    }

                    metadata.hideFlags = HideFlags.HideInHierarchy;
                    ctx.AddObjectToAsset($"{iHasMetadata.identifier}:Metadata", metadata);
                }
            }

            var sgMetadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>();
            sgMetadata.hideFlags         = HideFlags.HideInHierarchy;
            sgMetadata.assetDependencies = new List <UnityEngine.Object>();

            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.IncludeInExportPackage))
                {
                    // this sucks that we have to fully load these assets just to set the reference,
                    // which then gets serialized as the GUID that we already have here.  :P

                    var dependencyPath = AssetDatabase.GUIDToAssetPath(asset.Key);
                    if (!string.IsNullOrEmpty(dependencyPath))
                    {
                        sgMetadata.assetDependencies.Add(
                            AssetDatabase.LoadAssetAtPath(dependencyPath, typeof(UnityEngine.Object)));
                    }
                }
            }
            ctx.AddObjectToAsset("SGInternal:Metadata", sgMetadata);

            // declare dependencies
            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.SourceDependency))
                {
                    ctx.DependsOnSourceAsset(asset.Key);

                    // I'm not sure if this warning below is actually used or not, keeping it to be safe
                    var assetPath = AssetDatabase.GUIDToAssetPath(asset.Key);

                    // Ensure that dependency path is relative to project
                    if (!string.IsNullOrEmpty(assetPath) && !assetPath.StartsWith("Packages/") && !assetPath.StartsWith("Assets/"))
                    {
                        Debug.LogWarning($"Invalid dependency path: {assetPath}", mainObject);
                    }
                }

                // NOTE: dependencies declared by GatherDependenciesFromSourceFile are automatically registered as artifact dependencies
                // HOWEVER: that path ONLY grabs dependencies via MinimalGraphData, and will fail to register dependencies
                // on GUIDs that don't exist in the project.  For both of those reasons, we re-declare the dependencies here.
                if (asset.Value.HasFlag(AssetCollection.Flags.ArtifactDependency))
                {
                    ctx.DependsOnArtifact(asset.Key);
                }
            }
        }
Пример #5
0
        private void ImportYarn(AssetImportContext ctx)
        {
            var    sourceText = File.ReadAllText(ctx.assetPath);
            string fileName   = System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath);

            Yarn.Program compiledProgram = null;
            IDictionary <string, Yarn.Compiler.StringInfo> stringTable = null;

            compilationErrorMessage = null;

            try
            {
                // Compile the source code into a compiled Yarn program (or
                // generate a parse error)
                compilationStatus       = Yarn.Compiler.Compiler.CompileString(sourceText, fileName, out compiledProgram, out stringTable);
                isSuccesfullyCompiled   = true;
                compilationErrorMessage = string.Empty;
            }
            catch (Yarn.Compiler.ParseException e)
            {
                isSuccesfullyCompiled   = false;
                compilationErrorMessage = e.Message;
                ctx.LogImportError(e.Message);
            }

            // Create a container for storing the bytes
            if (programContainer == null)
            {
                programContainer = ScriptableObject.CreateInstance <YarnProgram>();
            }

            byte[] compiledBytes = null;

            if (compiledProgram != null)
            {
                using (var memoryStream = new MemoryStream())
                    using (var outputStream = new Google.Protobuf.CodedOutputStream(memoryStream))
                    {
                        // Serialize the compiled program to memory
                        compiledProgram.WriteTo(outputStream);
                        outputStream.Flush();

                        compiledBytes = memoryStream.ToArray();
                    }
            }


            programContainer.compiledProgram = compiledBytes;

            // Add this container to the imported asset; it will be
            // what the user interacts with in Unity
            ctx.AddObjectToAsset("Program", programContainer, YarnEditorUtility.GetYarnDocumentIconTexture());
            ctx.SetMainObject(programContainer);

            if (stringTable?.Count > 0)
            {
                var lines = stringTable.Select(x => new StringTableEntry
                {
                    ID         = x.Key,
                    Language   = baseLanguageID,
                    Text       = x.Value.text,
                    File       = x.Value.fileName,
                    Node       = x.Value.nodeName,
                    LineNumber = x.Value.lineNumber.ToString(),
                    Lock       = GetHashString(x.Value.text, 8),
                }).OrderBy(entry => int.Parse(entry.LineNumber));

                var stringTableCSV = StringTableEntry.CreateCSV(lines);

                var textAsset = new TextAsset(stringTableCSV);
                textAsset.name = $"{fileName} ({baseLanguageID})";

                ctx.AddObjectToAsset("Strings", textAsset);

                programContainer.baseLocalizationId = baseLanguageID;
                baseLanguage = textAsset;
                programContainer.localizations      = localizations.Append(new YarnProgram.YarnTranslation(baseLanguageID, textAsset)).ToArray();
                programContainer.baseLocalizationId = baseLanguageID;

                stringIDs = lines.Select(l => l.ID).ToArray();
            }
        }
Пример #6
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;
            var    sourceAssetDependencyPaths = new List <string>();

            UnityEngine.Object mainObject;

            var textGraph = File.ReadAllText(path, Encoding.UTF8);
            var graph     = new GraphData
            {
                messageManager = new MessageManager(), assetGuid = AssetDatabase.AssetPathToGUID(path)
            };

            MultiJson.Deserialize(graph, textGraph);
            graph.OnEnable();
            graph.ValidateGraph();

            if (graph.outputNode is VfxMasterNode vfxMasterNode)
            {
                var vfxAsset = GenerateVfxShaderGraphAsset(vfxMasterNode);

                mainObject = vfxAsset;
            }
            else
            {
                var text   = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, graph);
                var shader = ShaderUtil.CreateShaderAsset(text, false);

                if (graph != null && graph.messageManager.nodeMessagesChanged)
                {
                    foreach (var pair in graph.messageManager.GetNodeMessages())
                    {
                        var node = graph.GetNodeFromId(pair.Key);
                        MessageManager.Log(node, path, pair.Value.First(), shader);
                    }
                }

                EditorMaterialUtility.SetShaderDefaults(
                    shader,
                    configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
                EditorMaterialUtility.SetShaderNonModifiableDefaults(
                    shader,
                    configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());

                mainObject = shader;
            }
            Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon@64");

            ctx.AddObjectToAsset("MainAsset", mainObject, texture);
            ctx.SetMainObject(mainObject);

            var metadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>();

            metadata.hideFlags = HideFlags.HideInHierarchy;
            if (graph != null)
            {
                metadata.outputNodeTypeName = graph.outputNode.GetType().FullName;
            }
            metadata.assetDependencies = new List <UnityEngine.Object>();
            var deps = GatherDependenciesFromSourceFile(ctx.assetPath);

            foreach (string dependency in deps)
            {
                metadata.assetDependencies.Add(AssetDatabase.LoadAssetAtPath(dependency, typeof(UnityEngine.Object)));
            }

            ctx.AddObjectToAsset("Metadata", metadata);

            foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
            {
                // Ensure that dependency path is relative to project
                if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/"))
                {
                    Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", mainObject);
                    continue;
                }

                ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
            }
        }
Пример #7
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            ////REVIEW: need to check with version control here?
            // Read file.
            string text;

            try
            {
                text = File.ReadAllText(ctx.assetPath);
            }
            catch (Exception exception)
            {
                ctx.LogImportError(string.Format("Could not read file '{0}' ({1})",
                                                 ctx.assetPath, exception));
                return;
            }

            // Create asset.
            var asset = ScriptableObject.CreateInstance <InputActionAsset>();

            // Parse JSON.
            try
            {
                ////TODO: make sure action names are unique
                asset.LoadFromJson(text);
            }
            catch (Exception exception)
            {
                ctx.LogImportError(string.Format("Could not parse input actions in JSON format from '{0}' ({1})",
                                                 ctx.assetPath, exception));
                DestroyImmediate(asset);
                return;
            }

            // Load icons.
            ////REVIEW: the icons won't change if the user changes skin; not sure it makes sense to differentiate here
            var isDarkSkin = EditorGUIUtility.isProSkin;
            var assetIcon  = (Texture2D)EditorGUIUtility.Load(isDarkSkin ? kAssetIconDark : kAssetIcon);
            var actionIcon = (Texture2D)EditorGUIUtility.Load(isDarkSkin ? kActionIconDark : kActionIcon);

            // Add asset.
            ctx.AddObjectToAsset("<root>", asset, assetIcon);
            ctx.SetMainObject(asset);

            // Make sure every map and every action has a stable ID assigned to it.
            var maps = asset.actionMaps;

            foreach (var map in maps)
            {
                if (map.idDontGenerate == Guid.Empty)
                {
                    // Generate and remember GUID.
                    var id = map.id;
                    ArrayHelpers.Append(ref m_ActionMapGuids, new RememberedGuid
                    {
                        guid = id.ToString(),
                        name = map.name,
                    });
                }
                else
                {
                    // Retrieve remembered GUIDs.
                    if (m_ActionMapGuids != null)
                    {
                        for (var i = 0; i < m_ActionMapGuids.Length; ++i)
                        {
                            if (string.Compare(m_ActionMapGuids[i].name, map.name,
                                               StringComparison.InvariantCultureIgnoreCase) == 0)
                            {
                                map.m_Guid = Guid.Empty;
                                map.m_Id   = m_ActionMapGuids[i].guid;
                                break;
                            }
                        }
                    }
                }

                foreach (var action in map.actions)
                {
                    var actionName = string.Format("{0}/{1}", map.name, action.name);
                    if (action.idDontGenerate == Guid.Empty)
                    {
                        // Generate and remember GUID.
                        var id = action.id;
                        ArrayHelpers.Append(ref m_ActionGuids, new RememberedGuid
                        {
                            guid = id.ToString(),
                            name = actionName,
                        });
                    }
                    else
                    {
                        // Retrieve remembered GUIDs.
                        if (m_ActionGuids != null)
                        {
                            for (var i = 0; i < m_ActionGuids.Length; ++i)
                            {
                                if (string.Compare(m_ActionGuids[i].name, actionName,
                                                   StringComparison.InvariantCultureIgnoreCase) == 0)
                                {
                                    action.m_Guid = Guid.Empty;
                                    action.m_Id   = m_ActionGuids[i].guid;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            // Create subasset for each action.
            foreach (var map in maps)
            {
                var haveSetName = !string.IsNullOrEmpty(map.name);

                foreach (var action in map.actions)
                {
                    var actionReference = ScriptableObject.CreateInstance <InputActionReference>();
                    actionReference.Set(action);

                    var objectName = action.name;
                    if (haveSetName)
                    {
                        objectName = string.Format("{0}/{1}", map.name, action.name);
                    }

                    actionReference.name = objectName;
                    ctx.AddObjectToAsset(objectName, actionReference, actionIcon);
                }
            }

            // Generate wrapper code, if enabled.
            if (m_GenerateWrapperCode)
            {
                var wrapperFilePath = m_WrapperCodePath;
                if (string.IsNullOrEmpty(wrapperFilePath))
                {
                    var assetPath = ctx.assetPath;
                    var directory = Path.GetDirectoryName(assetPath);
                    var fileName  = Path.GetFileNameWithoutExtension(assetPath);
                    wrapperFilePath = Path.Combine(directory, fileName) + ".cs";
                }

                var options = new InputActionCodeGenerator.Options
                {
                    sourceAssetPath    = ctx.assetPath,
                    namespaceName      = m_WrapperCodeNamespace,
                    className          = m_WrapperClassName,
                    generateEvents     = m_GenerateActionEvents,
                    generateInterfaces = m_GenerateInterfaces,
                };

                if (InputActionCodeGenerator.GenerateWrapperCode(wrapperFilePath, maps, asset.controlSchemes, options))
                {
                    // Inform database that we modified a source asset *during* import.
                    AssetDatabase.ImportAsset(wrapperFilePath);
                }
            }

            // Refresh editors.
            AssetInspectorWindow.RefreshAllOnAssetReimport();
        }
Пример #8
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 (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();
        }
Пример #9
0
    public override void OnImportAsset(AssetImportContext ctx)
    {
        GameObject        temp = new GameObject();
        GameObject        gameObject;
        GameObject        mesh;
        GameObject        brick     = temp;
        List <GameObject> meshes    = new List <GameObject>();
        List <GameObject> parts     = new List <GameObject>();
        List <Mesh>       bricks    = new List <Mesh>();
        List <string>     names     = new List <string>();
        List <Material>   materials = new List <Material>();
        List <short>      files     = new List <short>();
        List <short>      parents   = new List <short>();
        string            name;
        short             material;

        Vector3[] vertices;
        Vector3[] normals;
        int[]     indices;
        Vector2[] uv;
        Matrix4x4 matrix;

        using (BinaryReader reader = new BinaryReader(File.Open(ctx.assetPath, FileMode.Open)))
        {
            name       = reader.ReadString();
            gameObject = new GameObject(name.Replace(".obl", ""));
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                name = reader.ReadString();
                mesh = new GameObject(name + "_" + reader.ReadInt16());
                if (name.EndsWith("x0"))
                {
                    parents.Add(reader.ReadInt16());
                    parts.Add(mesh);
                    mesh.transform.parent = gameObject.transform;
                    matrix = new Matrix4x4(new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()),
                                           new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()),
                                           new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()),
                                           new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
                    mesh.transform.position = matrix.GetColumn(3);
                    mesh.transform.rotation = matrix.rotation;
                    brick = mesh;
                }
                else
                {
                    mesh.transform.parent   = brick.transform;
                    mesh.transform.position = brick.transform.position;
                    mesh.transform.rotation = brick.transform.rotation;
                }
                material = reader.ReadInt16();
                if (!files.Contains(material))
                {
                    Material mat = Resources.Load <Material>("Materials/" + material);
                    materials.Add(mat);
                    files.Add(material);
                }
                vertices = new Vector3[reader.ReadInt32()];
                for (int i = 0; i < vertices.Length; i++)
                {
                    vertices[i] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                }
                normals = new Vector3[reader.ReadInt32()];
                for (int i = 0; i < normals.Length; i++)
                {
                    normals[i] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                }
                indices = new int[reader.ReadInt32()];
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = reader.ReadInt16();
                }
                uv = new Vector2[vertices.Length];
                for (int i = 0; i < uv.Length; i++)
                {
                    Vector3 v = vertices[i];
                    uv[i] = new Vector2((v.x + v.y) / 2, (v.y + v.z) / 2);
                }
                if (!names.Contains(name))
                {
                    Mesh m = new Mesh
                    {
                        vertices  = vertices,
                        normals   = normals,
                        triangles = indices,
                        uv        = uv
                    };
                    bricks.Add(m);
                    names.Add(name);
                }
                mesh.AddComponent <MeshFilter>();
                mesh.GetComponent <MeshFilter>().mesh = bricks[names.IndexOf(name)];
                mesh.AddComponent <MeshRenderer>();
                mesh.GetComponent <MeshRenderer>().materials = new Material[] { materials[files.IndexOf(material)] };
                meshes.Add(mesh);
            }
        }
        for (int i = 0; i < parts.Count; i++)
        {
            int index = parts.FindIndex(x => x.name.EndsWith(parents[i].ToString()));
            if (parents[i] != -1)
            {
                parts[i].transform.parent = parts[index].transform;
            }
        }
        gameObject.transform.localScale = new Vector3(0.5f, 0.5f, -0.5f);
        ctx.AddObjectToAsset(gameObject.name, gameObject);
        ctx.SetMainObject(gameObject);
        for (int i = 0; i < bricks.Count; i++)
        {
            ctx.AddObjectToAsset(names[i], bricks[i]);
        }
        for (int i = 0; i < materials.Count; i++)
        {
            ctx.AddObjectToAsset(files[i].ToString(), materials[i]);
        }
        DestroyImmediate(temp);
    }
Пример #10
0
    public override void OnImportAsset(AssetImportContext ase)
    {
        switch (Pivot)
        {
        case PivotPositionEnum.TopLeft:
            PivotPosition = new Vector2(0, 1);
            break;

        case PivotPositionEnum.TopCenter:
            PivotPosition = new Vector2(.5f, 1);
            break;

        case PivotPositionEnum.TopRight:
            PivotPosition = new Vector2(1, 1);
            break;

        case PivotPositionEnum.MidleLeft:
            PivotPosition = new Vector2(0, .5f);
            break;

        case PivotPositionEnum.MiddleCenter:
            PivotPosition = new Vector2(.5f, .5f);
            break;

        case PivotPositionEnum.MiddleRight:
            PivotPosition = new Vector2(1, .5f);
            break;

        case PivotPositionEnum.BottomLeft:
            PivotPosition = new Vector2(0, 0);
            break;

        case PivotPositionEnum.BottomCenter:
            PivotPosition = new Vector2(.5f, 0);
            break;

        case PivotPositionEnum.BottomRight:
            PivotPosition = new Vector2(1, 0);
            break;
        }

        Aseprite = new Aseprite(File.ReadAllBytes(ase.assetPath), MergedLayersImportOption,
                                SeparateLayersImportOption, PivotPosition, Path.GetFileNameWithoutExtension(ase.assetPath));

        if ((int)SeparateLayersImportOption > 0)
        {
            for (var l = 0; l < Aseprite.Layers.Length; l++)
            {
                ase.AddObjectToAsset(Aseprite.Layers[l].Texture.name, Aseprite.Layers[l].Texture);
                if ((int)SeparateLayersImportOption > 1)
                {
                    foreach (var sprite in Aseprite.Layers[l].Sprites)
                    {
                        ase.AddObjectToAsset(sprite.name, sprite);
                    }
                    if ((int)SeparateLayersImportOption > 2)
                    {
                        AddAnimation($"Layer_{l}_", Aseprite.Layers[l].Sprites, ase);
                    }
                }
            }
        }

        if (Aseprite.ColorPalette != null)
        {
            ase.AddObjectToAsset("Palette", Aseprite.ColorPalette);
        }

        if ((int)MergedLayersImportOption > 0)
        {
            ase.AddObjectToAsset(Aseprite.MergedLayer.Texture.name, Aseprite.MergedLayer.Texture);
            ase.SetMainObject(Aseprite.MergedLayer.Texture);
            if ((int)MergedLayersImportOption > 1)
            {
                foreach (var sprite in Aseprite.MergedLayer.Sprites)
                {
                    ase.AddObjectToAsset(sprite.name, sprite);
                }
                if ((int)MergedLayersImportOption > 2)
                {
                    AddAnimation("", Aseprite.MergedLayer.Sprites, ase);
                }
            }
        }
        else
        {
            if (Aseprite.ColorPalette != null)
            {
                ase.SetMainObject(Aseprite.ColorPalette);
            }
        }
    }
Пример #11
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;

            AssetCollection assetCollection = new AssetCollection();

            MinimalGraphData.GatherMinimalDependenciesFromFile(assetPath, assetCollection);

            var textGraph = File.ReadAllText(path, Encoding.UTF8);
            var graph     = new GraphData
            {
                messageManager = new MessageManager(), assetGuid = AssetDatabase.AssetPathToGUID(path)
            };

            MultiJson.Deserialize(graph, textGraph);
            graph.OnEnable();
            graph.ValidateGraph();

            Shader shader = null;

#if VFX_GRAPH_10_0_0_OR_NEWER
            if (!graph.isOnlyVFXTarget)
#endif
            {
                // build the shader text
                // this will also add Target dependencies into the asset collection
                var text = GetShaderText(path, out configuredTextures, assetCollection, graph);

#if UNITY_2021_1_OR_NEWER
                // 2021.1 or later is guaranteed to have the new version of this function
                shader = ShaderUtil.CreateShaderAsset(ctx, text, false);
#else
                // earlier builds of Unity may or may not have it
                // here we try to invoke the new version via reflection
                var createShaderAssetMethod = typeof(ShaderUtil).GetMethod(
                    "CreateShaderAsset",
                    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.ExactBinding,
                    null,
                    new Type[] { typeof(AssetImportContext), typeof(string), typeof(bool) },
                    null);

                if (createShaderAssetMethod != null)
                {
                    shader = createShaderAssetMethod.Invoke(null, new Object[] { ctx, text, false }) as Shader;
                }
                else
                {
                    // method doesn't exist in this version of Unity, call old version
                    // this doesn't create dependencies properly, but is the best that we can do
                    shader = ShaderUtil.CreateShaderAsset(text, false);
                }
#endif

                ReportErrors(graph, shader, path);

                EditorMaterialUtility.SetShaderDefaults(
                    shader,
                    configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
                EditorMaterialUtility.SetShaderNonModifiableDefaults(
                    shader,
                    configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
            }

            UnityEngine.Object mainObject = shader;
#if VFX_GRAPH_10_0_0_OR_NEWER
            ShaderGraphVfxAsset vfxAsset = null;
            if (graph.hasVFXTarget)
            {
                vfxAsset = GenerateVfxShaderGraphAsset(graph);
                if (mainObject == null)
                {
                    mainObject = vfxAsset;
                }
                else
                {
                    //Correct main object if we have a shader and ShaderGraphVfxAsset : save as sub asset
                    vfxAsset.name = Path.GetFileNameWithoutExtension(path);
                    ctx.AddObjectToAsset("VFXShaderGraph", vfxAsset);
                }
            }
#endif

            Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon");
            ctx.AddObjectToAsset("MainAsset", mainObject, texture);
            ctx.SetMainObject(mainObject);

            foreach (var target in graph.activeTargets)
            {
                if (target is IHasMetadata iHasMetadata)
                {
                    var metadata = iHasMetadata.GetMetadataObject();
                    if (metadata == null)
                    {
                        continue;
                    }

                    metadata.hideFlags = HideFlags.HideInHierarchy;
                    ctx.AddObjectToAsset($"{iHasMetadata.identifier}:Metadata", metadata);
                }
            }

            var sgMetadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>();
            sgMetadata.hideFlags         = HideFlags.HideInHierarchy;
            sgMetadata.assetDependencies = new List <UnityEngine.Object>();

            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.IncludeInExportPackage))
                {
                    // this sucks that we have to fully load these assets just to set the reference,
                    // which then gets serialized as the GUID that we already have here.  :P

                    var dependencyPath = AssetDatabase.GUIDToAssetPath(asset.Key);
                    if (!string.IsNullOrEmpty(dependencyPath))
                    {
                        sgMetadata.assetDependencies.Add(
                            AssetDatabase.LoadAssetAtPath(dependencyPath, typeof(UnityEngine.Object)));
                    }
                }
            }

            List <GraphInputData> inputInspectorDataList = new List <GraphInputData>();
            foreach (AbstractShaderProperty property in graph.properties)
            {
                // Don't write out data for non-exposed blackboard items
                if (!property.isExposed)
                {
                    continue;
                }

                // VTs are treated differently
                if (property is VirtualTextureShaderProperty virtualTextureShaderProperty)
                {
                    inputInspectorDataList.Add(MinimalCategoryData.ProcessVirtualTextureProperty(virtualTextureShaderProperty));
                }
                else
                {
                    inputInspectorDataList.Add(new GraphInputData()
                    {
                        referenceName = property.referenceName, propertyType = property.propertyType, isKeyword = false
                    });
                }
            }
            foreach (ShaderKeyword keyword in graph.keywords)
            {
                // Don't write out data for non-exposed blackboard items
                if (!keyword.isExposed)
                {
                    continue;
                }

                var sanitizedReferenceName = keyword.referenceName;
                if (keyword.keywordType == KeywordType.Boolean && keyword.referenceName.Contains("_ON"))
                {
                    sanitizedReferenceName = sanitizedReferenceName.Replace("_ON", String.Empty);
                }

                inputInspectorDataList.Add(new GraphInputData()
                {
                    referenceName = sanitizedReferenceName, keywordType = keyword.keywordType, isKeyword = true
                });
            }

            sgMetadata.categoryDatas = new List <MinimalCategoryData>();
            foreach (CategoryData categoryData in graph.categories)
            {
                // Don't write out empty categories
                if (categoryData.childCount == 0)
                {
                    continue;
                }

                MinimalCategoryData mcd = new MinimalCategoryData()
                {
                    categoryName  = categoryData.name,
                    propertyDatas = new List <GraphInputData>()
                };
                foreach (var input in categoryData.Children)
                {
                    GraphInputData propData;
                    // Only write out data for exposed blackboard items
                    if (input.isExposed == false)
                    {
                        continue;
                    }

                    // VTs are treated differently
                    if (input is VirtualTextureShaderProperty virtualTextureShaderProperty)
                    {
                        propData = MinimalCategoryData.ProcessVirtualTextureProperty(virtualTextureShaderProperty);
                        inputInspectorDataList.RemoveAll(inputData => inputData.referenceName == propData.referenceName);
                        mcd.propertyDatas.Add(propData);
                        continue;
                    }
                    else if (input is ShaderKeyword keyword)
                    {
                        var sanitizedReferenceName = keyword.referenceName;
                        if (keyword.keywordType == KeywordType.Boolean && keyword.referenceName.Contains("_ON"))
                        {
                            sanitizedReferenceName = sanitizedReferenceName.Replace("_ON", String.Empty);
                        }

                        propData = new GraphInputData()
                        {
                            referenceName = sanitizedReferenceName, keywordType = keyword.keywordType, isKeyword = true
                        };
                    }
                    else
                    {
                        var prop = input as AbstractShaderProperty;
                        propData = new GraphInputData()
                        {
                            referenceName = input.referenceName, propertyType = prop.propertyType, isKeyword = false
                        };
                    }

                    mcd.propertyDatas.Add(propData);
                    inputInspectorDataList.Remove(propData);
                }
                sgMetadata.categoryDatas.Add(mcd);
            }

            // Any uncategorized elements get tossed into an un-named category at the top as a fallback
            if (inputInspectorDataList.Count > 0)
            {
                sgMetadata.categoryDatas.Insert(0, new MinimalCategoryData()
                {
                    categoryName = "", propertyDatas = inputInspectorDataList
                });
            }

            ctx.AddObjectToAsset("SGInternal:Metadata", sgMetadata);

            // declare dependencies
            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.SourceDependency))
                {
                    ctx.DependsOnSourceAsset(asset.Key);

                    // I'm not sure if this warning below is actually used or not, keeping it to be safe
                    var assetPath = AssetDatabase.GUIDToAssetPath(asset.Key);

                    // Ensure that dependency path is relative to project
                    if (!string.IsNullOrEmpty(assetPath) && !assetPath.StartsWith("Packages/") && !assetPath.StartsWith("Assets/"))
                    {
                        Debug.LogWarning($"Invalid dependency path: {assetPath}", mainObject);
                    }
                }

                // NOTE: dependencies declared by GatherDependenciesFromSourceFile are automatically registered as artifact dependencies
                // HOWEVER: that path ONLY grabs dependencies via MinimalGraphData, and will fail to register dependencies
                // on GUIDs that don't exist in the project.  For both of those reasons, we re-declare the dependencies here.
                if (asset.Value.HasFlag(AssetCollection.Flags.ArtifactDependency))
                {
                    ctx.DependsOnArtifact(asset.Key);
                }
            }
        }
Пример #12
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            name = Path.GetFileNameWithoutExtension(ctx.assetPath);
            //name = GetFileName(ctx.assetPath);

            AseFile aseFile = ReadAseFile(ctx.assetPath);

            if (LayersToTextures)
            {
                GenerateSeparateTexturesFromLayers(ctx, aseFile);
                return;
            }

            SpriteAtlasBuilder atlasBuilder = new SpriteAtlasBuilder(textureSettings, aseFile.Header.Width, aseFile.Header.Height);

            Texture2D[] frames = null;
            if (importType != AseFileImportType.LayerToSprite)
            {
                frames = aseFile.GetFrames();
            }
            else
            {
                frames = aseFile.GetLayersAsFrames();
            }

            SpriteImportData[] spriteImportData = new SpriteImportData[0];

            //if (textureSettings.transparentMask)
            //{
            //    atlas = atlasBuilder.GenerateAtlas(frames, out spriteImportData, textureSettings.transparentColor, false);
            //}
            //else
            //{
            //    atlas = atlasBuilder.GenerateAtlas(frames, out spriteImportData, false);

            //}

            Texture2D atlas = atlasBuilder.GenerateAtlas(frames, out spriteImportData, textureSettings.transparentMask, false);


            atlas.filterMode          = textureSettings.filterMode;
            atlas.alphaIsTransparency = false;
            atlas.wrapMode            = TextureWrapMode.Clamp;
            atlas.name = "Texture";

            ctx.AddObjectToAsset("Texture", atlas);

            ctx.SetMainObject(atlas);

            switch (importType)
            {
            case AseFileImportType.LayerToSprite:
            case AseFileImportType.Sprite:
                ImportSprites(ctx, aseFile, spriteImportData, atlas);
                break;

            case AseFileImportType.Tileset:
                ImportTileset(ctx, atlas);
                break;
            }

            ctx.SetMainObject(atlas);
        }
    // Called by Unity to perform an import
    public override void OnImportAsset(AssetImportContext ctx)
    {
        // "ctx" contains information about the import that Unity wants us
        // to do; it contains the path to the file, and we'll put the Unity
        // objects into it when we're done

        // "cube" files will contain JSON that describes the color and size
        // of the cube.

        // Create a variable to load the cube description into
        CubeDescription cubeDescription;

        // Attempt to load the JSON.
        try {
            var text = System.IO.File.ReadAllText(ctx.assetPath);

            cubeDescription = JsonUtility.FromJson <CubeDescription>(text);
        } catch (System.ArgumentException e) {
            // We failed to load the JSON. Maybe it's not valid. Report the
            // error.
            Debug.LogErrorFormat(
                "{0} is not a valid cube: {1}",
                ctx.assetPath, e.Message);
            return;
        } catch (System.Exception e) {
            // We caught some other kind of exception, and can't continue.
            // Re-throw the error.
            throw e;
        }

        // Create a generic cube object, which we'll make changes to and
        // save as a new asset.
        var cubeObject = GameObject.CreatePrimitive(PrimitiveType.Cube);

        // Get the last part of the file path, and use it as the cube's
        // name
        string name =
            System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath);

        // Next, we'll create a cube that's the right size. The default
        // cube mesh is 1x1x1; we'll scale it based on the size that was
        // passed in.

        // Copy the default cube mesh.
        var cubeMesh =
            Instantiate(cubeObject.GetComponent <MeshFilter>().sharedMesh);

        // Create a matrix that scales vertices by the given X, Y and Z
        // amounts.
        var scaleMatrix = Matrix4x4.Scale(cubeDescription.size);

        // Get a copy of the vertices in the mesh.
        var vertices = cubeMesh.vertices;

        // For each of these vertices, apply the scale by multiplying the
        // matrix against the vertex.
        for (int v = 0; v < vertices.Length; v++)
        {
            vertices[v] = scaleMatrix.MultiplyPoint(vertices[v]);
        }

        // Store these scaled vertices in the mesh.
        cubeMesh.vertices = vertices;

        // Tell the cube's MeshFilter to use this new mesh.
        cubeObject.GetComponent <MeshFilter>().sharedMesh = cubeMesh;

        // Give the mesh a name.
        cubeMesh.name = name + " Mesh";

        // Create a new material, using the Standard shader (which is the
        // default)
        var cubeMaterial = new Material(Shader.Find("Standard"));

        // Apply the color that we loaded.
        cubeMaterial.color = cubeDescription.color;

        // Give it a name, too.
        cubeMaterial.name = name + " Material";

        // Tell the cube's MeshRenderer to use this material.
        cubeObject.GetComponent <MeshRenderer>().material = cubeMaterial;

        // Now we store the objects we just created as assets.

        // First, store the GameObject (the collection of components that
        // uses and renders the mesh and material), and mark it as the
        // "main" object.
        ctx.AddObjectToAsset(name, cubeObject);
        ctx.SetMainObject(cubeObject);

        // We also need to store the mesh and material as well.
        ctx.AddObjectToAsset(cubeMaterial.name, cubeMaterial);
        ctx.AddObjectToAsset(cubeMesh.name, cubeMesh);
    }
Пример #14
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var currentTime = DateTime.Now.Ticks;

            if (ctx.assetPath != path)
            {
                ctx.LogImportError("The sgpostsubgraph extension may only be used internally by Shader Graph.");
                return;
            }

            if (SubGraphDatabase.instance == null)
            {
                SubGraphDatabase.instance = ScriptableObject.CreateInstance <SubGraphDatabase>();
            }
            var database = SubGraphDatabase.instance;

            var allSubGraphGuids = AssetDatabase.FindAssets($"t:{nameof(SubGraphAsset)}").ToList();

            allSubGraphGuids.Sort();
            var subGraphMap  = new Dictionary <string, SubGraphData>();
            var graphDataMap = new Dictionary <string, GraphData>();

            foreach (var subGraphData in database.subGraphs)
            {
                if (allSubGraphGuids.BinarySearch(subGraphData.assetGuid) >= 0)
                {
                    subGraphMap.Add(subGraphData.assetGuid, subGraphData);
                }
            }

            var dirtySubGraphGuids = new List <string>();

            foreach (var subGraphGuid in allSubGraphGuids)
            {
                var subGraphAsset = AssetDatabase.LoadAssetAtPath <SubGraphAsset>(AssetDatabase.GUIDToAssetPath(subGraphGuid));
                if (!subGraphMap.TryGetValue(subGraphGuid, out var subGraphData))
                {
                    subGraphData = new SubGraphData();
                }

                if (subGraphAsset.importedAt > subGraphData.processedAt)
                {
                    dirtySubGraphGuids.Add(subGraphGuid);
                    subGraphData.Reset();
                    subGraphData.processedAt = currentTime;
                    var subGraphPath = AssetDatabase.GUIDToAssetPath(subGraphGuid);
                    var textGraph    = File.ReadAllText(subGraphPath, Encoding.UTF8);
                    var graphData    = new GraphData {
                        isSubGraph = true, assetGuid = subGraphGuid
                    };
                    JsonUtility.FromJsonOverwrite(textGraph, graphData);
                    subGraphData.children.AddRange(graphData.GetNodes <SubGraphNode>().Select(x => x.subGraphGuid).Distinct());
                    subGraphData.assetGuid     = subGraphGuid;
                    subGraphMap[subGraphGuid]  = subGraphData;
                    graphDataMap[subGraphGuid] = graphData;
                }
                else
                {
                    subGraphData.ancestors.Clear();
                    subGraphData.descendents.Clear();
                    subGraphData.isRecursive = false;
                }
            }

            database.subGraphs.Clear();
            database.subGraphs.AddRange(subGraphMap.Values);
            database.subGraphs.Sort((s1, s2) => s1.assetGuid.CompareTo(s2.assetGuid));
            database.subGraphGuids.Clear();
            database.subGraphGuids.AddRange(database.subGraphs.Select(x => x.assetGuid));

            var permanentMarks = new HashSet <string>();
            var stack          = new Stack <string>(allSubGraphGuids.Count);

            // Detect recursion, and populate `ancestors` and `descendents` per sub graph.
            foreach (var rootSubGraphData in database.subGraphs)
            {
                var rootSubGraphGuid = rootSubGraphData.assetGuid;
                stack.Push(rootSubGraphGuid);
                while (stack.Count > 0)
                {
                    var subGraphGuid = stack.Pop();
                    if (!permanentMarks.Add(subGraphGuid))
                    {
                        continue;
                    }

                    var subGraphData = subGraphMap[subGraphGuid];
                    if (subGraphData != rootSubGraphData)
                    {
                        subGraphData.ancestors.Add(rootSubGraphGuid);
                        rootSubGraphData.descendents.Add(subGraphGuid);
                    }
                    foreach (var childSubGraphGuid in subGraphData.children)
                    {
                        if (childSubGraphGuid == rootSubGraphGuid)
                        {
                            rootSubGraphData.isRecursive = true;
                        }
                        else
                        {
                            stack.Push(childSubGraphGuid);
                        }
                    }
                }
                permanentMarks.Clear();
            }

            // Next up we build a list of sub graphs to be processed, which will later be sorted topologically.
            var sortedSubGraphs = new List <SubGraphData>();

            foreach (var subGraphGuid in dirtySubGraphGuids)
            {
                var subGraphData = subGraphMap[subGraphGuid];
                if (permanentMarks.Add(subGraphGuid))
                {
                    sortedSubGraphs.Add(subGraphData);
                }

                // Note that we're traversing up the graph via ancestors rather than descendents, because all Sub Graphs using the current sub graph needs to be re-processed.
                foreach (var ancestorGuid in subGraphData.ancestors)
                {
                    if (permanentMarks.Add(ancestorGuid))
                    {
                        var ancestorSubGraphData = subGraphMap[ancestorGuid];
                        sortedSubGraphs.Add(ancestorSubGraphData);
                    }
                }
            }
            permanentMarks.Clear();

            // Sort topologically. At this stage we can assume there are no loops because all recursive sub graphs have been filtered out.
            sortedSubGraphs.Sort((s1, s2) => s1.descendents.Contains(s2.assetGuid) ? 1 : s2.descendents.Contains(s1.assetGuid) ? -1 : 0);

            // Finally process the topologically sorted sub graphs without recursion.
            var registry       = new FunctionRegistry(new ShaderStringBuilder(), true);
            var messageManager = new MessageManager();

            foreach (var subGraphData in sortedSubGraphs)
            {
                try
                {
                    var subGraphPath = AssetDatabase.GUIDToAssetPath(subGraphData.assetGuid);
                    if (!graphDataMap.TryGetValue(subGraphData.assetGuid, out var graphData))
                    {
                        var textGraph = File.ReadAllText(subGraphPath, Encoding.UTF8);
                        graphData = new GraphData {
                            isSubGraph = true, assetGuid = subGraphData.assetGuid
                        };
                        JsonUtility.FromJsonOverwrite(textGraph, graphData);
                    }

                    graphData.messageManager = messageManager;
                    ProcessSubGraph(subGraphMap, registry, subGraphData, graphData);
                    if (messageManager.nodeMessagesChanged)
                    {
                        var subGraphAsset = AssetDatabase.LoadAssetAtPath <SubGraphAsset>(AssetDatabase.GUIDToAssetPath(subGraphData.assetGuid));
                        foreach (var pair in messageManager.GetNodeMessages())
                        {
                            var node = graphData.GetNodeFromTempId(pair.Key);
                            foreach (var message in pair.Value)
                            {
                                MessageManager.Log(node, subGraphPath, message, subGraphAsset);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    subGraphData.isValid = false;
                    var subGraphAsset = AssetDatabase.LoadAssetAtPath <SubGraphAsset>(AssetDatabase.GUIDToAssetPath(subGraphData.assetGuid));
                    Debug.LogException(e, subGraphAsset);
                }
                finally
                {
                    subGraphData.processedAt = currentTime;
                    messageManager.ClearAll();
                }
            }

            // Carry over functions used by sub-graphs that were not re-processed in this import.
            foreach (var subGraphData in database.subGraphs)
            {
                foreach (var functionName in subGraphData.functionNames)
                {
                    if (!registry.sources.ContainsKey(functionName))
                    {
                        registry.sources.Add(functionName, database.functionSources[database.functionNames.BinarySearch(functionName)]);
                    }
                }
            }

            var functions = registry.sources.ToList();

            functions.Sort((p1, p2) => p1.Key.CompareTo(p2.Key));
            database.functionNames.Clear();
            database.functionSources.Clear();
            foreach (var pair in functions)
            {
                database.functionNames.Add(pair.Key);
                database.functionSources.Add(pair.Value);
            }

            ctx.AddObjectToAsset("MainAsset", database);
            ctx.SetMainObject(database);

            SubGraphDatabase.instance = null;
        }
Пример #15
0
 public void SetMainObject(UnityEngine.Object obj)
 {
     m_Context.SetMainObject(obj);
 }
Пример #16
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            {
                var ext = Path.GetExtension(ctx.assetPath).ToLower();
                if (ext == ".vox")
                {
                    fileType = VoxelBase.FileType.vox;
                }
                else if (ext == ".qb")
                {
                    fileType = VoxelBase.FileType.qb;
                }
                else
                {
                    return;
                }
            }

            #region DefaultScale
            if (dataVersion == 0 &&
                importScale == Vector3.one &&
                AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(ctx.assetPath) == null)
            {
                var x = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleX", 1f);
                var y = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleY", 1f);
                var z = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleZ", 1f);
                importScale = new Vector3(x, y, z);
            }
            #endregion

            Action <string> LogImportError = (log) =>
            {
#if UNITY_2018_1_OR_NEWER
                ctx.LogImportError(log);
#else
                Debug.LogError(log);
#endif
            };

            var gameObject  = new GameObject(Path.GetFileNameWithoutExtension(ctx.assetPath));
            var voxelObject = gameObject.AddComponent <VoxelObject>();
            {
                voxelObject.legacyVoxImport               = legacyVoxImport;
                voxelObject.importMode                    = importMode;
                voxelObject.importScale                   = importScale;
                voxelObject.importOffset                  = importOffset;
                voxelObject.combineFaces                  = combineFaces;
                voxelObject.ignoreCavity                  = ignoreCavity;
                voxelObject.shareSameFace                 = shareSameFace;
                voxelObject.voxelStructure                = outputStructure ? ScriptableObject.CreateInstance <VoxelStructure>() : null;
                voxelObject.generateLightmapUVs           = generateLightmapUVs;
                voxelObject.generateLightmapUVsAngleError = generateLightmapUVsAngleError;
                voxelObject.generateLightmapUVsAreaError  = generateLightmapUVsAreaError;
                voxelObject.generateLightmapUVsHardAngle  = generateLightmapUVsHardAngle;
                voxelObject.generateLightmapUVsPackMargin = generateLightmapUVsPackMargin;
                voxelObject.generateTangents              = generateTangents;
                voxelObject.meshFaceVertexOffset          = meshFaceVertexOffset;
                voxelObject.loadFromVoxelFile             = loadFromVoxelFile;
                voxelObject.generateMipMaps               = generateMipMaps;
            }
            var objectCore = new VoxelObjectCore(voxelObject);
            try
            {
                if (!objectCore.Create(ctx.assetPath, null))
                {
                    LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                    DestroyImmediate(gameObject);
                    return;
                }
            }
            catch
            {
                LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                DestroyImmediate(gameObject);
                return;
            }

            #region Correspondence in Issue ID 947055 Correction in case before correction is applied
            for (int i = 0; i < voxelObject.materials.Count; i++)
            {
                if (voxelObject.materials[i] != null)
                {
                    voxelObject.materials[i].hideFlags |= HideFlags.NotEditable;
                }
            }
            if (voxelObject.atlasTexture != null)
            {
                voxelObject.atlasTexture.hideFlags |= HideFlags.NotEditable;
            }
            if (voxelObject.mesh != null)
            {
                voxelObject.mesh.hideFlags |= HideFlags.NotEditable;
            }
            #endregion

            #region Material
            {
                materials     = new Material[voxelObject.materialIndexes.Count];
                materialNames = new string[voxelObject.materialIndexes.Count];
                for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                {
                    var index    = voxelObject.materialIndexes[i];
                    var material = voxelObject.materials[index];
                    material.name    = string.Format("mat{0}", index);
                    materials[i]     = material;
                    materialNames[i] = material.name;
                }
                if (remappedMaterials != null)
                {
                    remappedMaterials = remappedMaterials.Where(item => item.material != null).ToArray();
                }
            }
            #endregion

            #region Collider
            switch (colliderType)
            {
            case ColliderType.Box:
                gameObject.AddComponent <BoxCollider>();
                break;

            case ColliderType.Sphere:
                gameObject.AddComponent <SphereCollider>();
                break;

            case ColliderType.Capsule:
                gameObject.AddComponent <CapsuleCollider>();
                break;

            case ColliderType.Mesh:
                gameObject.AddComponent <MeshCollider>();
                break;
            }
            #endregion

#if UNITY_2017_3_OR_NEWER
            ctx.AddObjectToAsset(gameObject.name, gameObject);
            ctx.AddObjectToAsset(voxelObject.mesh.name = "mesh", voxelObject.mesh);
            {
                var materials = new List <Material>();
                for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                {
                    var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                    materials.Add(material);
                    if (remappedMaterials != null)
                    {
                        var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                        if (index >= 0)
                        {
                            materials[i] = remappedMaterials[index].material;
                            continue;
                        }
                    }
                    ctx.AddObjectToAsset(material.name, material);
                }
                gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
            }
            ctx.AddObjectToAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
            if (voxelObject.voxelStructure != null)
            {
                ctx.AddObjectToAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
            }

            VoxelObject.DestroyImmediate(voxelObject);

            ctx.SetMainObject(gameObject);
#else
            ctx.SetMainAsset(gameObject.name, gameObject);
            ctx.AddSubAsset(voxelObject.mesh.name = "mesh", voxelObject.mesh);
            for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
            {
                var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                ctx.AddSubAsset(material.name, material);
            }
            ctx.AddSubAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
            if (voxelObject.voxelStructure != null)
            {
                ctx.AddSubAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
            }

            VoxelObject.DestroyImmediate(voxelObject);
#endif
            dataVersion = EditorDataVersion;
        }
Пример #17
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
#if YARNSPINNER_DEBUG
            UnityEngine.Profiling.Profiler.enabled = true;
#endif

            var project = ScriptableObject.CreateInstance <YarnProject>();

            project.name = Path.GetFileNameWithoutExtension(ctx.assetPath);

            // Start by creating the asset - no matter what, we need to
            // produce an asset, even if it doesn't contain valid Yarn
            // bytecode, so that other assets don't lose their references.
            ctx.AddObjectToAsset("Project", project);
            ctx.SetMainObject(project);

            foreach (var script in sourceScripts)
            {
                string path = AssetDatabase.GetAssetPath(script);
                if (string.IsNullOrEmpty(path))
                {
                    // This is, for some reason, not a valid script we can
                    // use. Don't add a dependency on it.
                    continue;
                }
                ctx.DependsOnSourceAsset(path);
            }

            // Parse declarations
            var localDeclarationsCompileJob = CompilationJob.CreateFromFiles(ctx.assetPath);
            localDeclarationsCompileJob.CompilationType = CompilationJob.Type.DeclarationsOnly;

            IEnumerable <Declaration> localDeclarations;

            compileError = null;

            try
            {
                var result = Compiler.Compiler.Compile(localDeclarationsCompileJob);
                localDeclarations = result.Declarations;
            }
            catch (ParseException e)
            {
                ctx.LogImportError($"Error in Yarn Project: {e.Message}");
                compileError = $"Error in Yarn Project {ctx.assetPath}: {e.Message}";
                return;
            }

            // Store these so that we can continue displaying them after
            // this import step, in case there are compile errors later.
            // We'll replace this with a more complete list later if
            // compilation succeeds.
            serializedDeclarations = localDeclarations
                                     .Where(decl => decl.DeclarationType == Declaration.Type.Variable)
                                     .Select(decl => new SerializedDeclaration(decl)).ToList();

            // We're done processing this file - we've parsed it, and
            // pulled any information out of it that we need to. Now to
            // compile the scripts associated with this project.

            var scriptImporters = sourceScripts.Where(s => s != null).Select(s => AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(s)) as YarnImporter);

            // First step: check to see if there's any parse errors in the
            // files.
            var scriptsWithParseErrors = scriptImporters.Where(script => script.isSuccessfullyParsed == false);

            if (scriptsWithParseErrors.Count() != 0)
            {
                // Parse errors! We can't continue.
                string failingScriptNameList = string.Join("\n", scriptsWithParseErrors.Select(script => script.assetPath));
                compileError = $"Parse errors exist in the following files:\n{failingScriptNameList}";
                return;
            }

            // Get paths to the scripts we're importing, and also map them
            // to their corresponding importer
            var pathsToImporters = scriptImporters.ToDictionary(script => script.assetPath, script => script);

            if (pathsToImporters.Count == 0)
            {
                return; // nothing further to do here
            }

            // We now now compile!
            var job = CompilationJob.CreateFromFiles(pathsToImporters.Keys);
            job.VariableDeclarations = localDeclarations;

            CompilationResult compilationResult;

            try
            {
                compilationResult = Compiler.Compiler.Compile(job);
            }
            catch (TypeException e)
            {
                ctx.LogImportError($"Error compiling: {e.Message}");
                compileError = e.Message;

                var importer = pathsToImporters[e.FileName];
                importer.parseErrorMessage = e.Message;
                EditorUtility.SetDirty(importer);

                return;
            }
            catch (ParseException e)
            {
                ctx.LogImportError(e.Message);
                compileError = e.Message;

                var importer = pathsToImporters[e.FileName];
                importer.parseErrorMessage = e.Message;
                EditorUtility.SetDirty(importer);

                return;
            }

            if (compilationResult.Program == null)
            {
                ctx.LogImportError("Internal error: Failed to compile: resulting program was null, but compiler did not throw a parse exception.");
                return;
            }

            // Store _all_ declarations - both the ones in this
            // .yarnproject file, and the ones inside the .yarn files
            serializedDeclarations = localDeclarations
                                     .Concat(compilationResult.Declarations)
                                     .Where(decl => decl.DeclarationType == Declaration.Type.Variable)
                                     .Select(decl => new SerializedDeclaration(decl)).ToList();

            // Clear error messages from all scripts - they've all passed
            // compilation
            foreach (var importer in pathsToImporters.Values)
            {
                importer.parseErrorMessage = null;
            }

            // Will we need to create a default localization? This variable
            // will be set to false if any of the languages we've
            // configured in languagesToSourceAssets is the default
            // language.
            var shouldAddDefaultLocalization = true;

            foreach (var pair in languagesToSourceAssets)
            {
                // Don't create a localization if the language ID was not
                // provided
                if (string.IsNullOrEmpty(pair.languageID))
                {
                    Debug.LogWarning($"Not creating a localization for {project.name} because the language ID wasn't provided. Add the language ID to the localization in the Yarn Project's inspector.");
                    continue;
                }

                IEnumerable <StringTableEntry> stringTable;

                // Where do we get our strings from? If it's the default
                // language, we'll pull it from the scripts. If it's from
                // any other source, we'll pull it from the CSVs.
                if (pair.languageID == defaultLanguage)
                {
                    // We'll use the program-supplied string table.
                    stringTable = GenerateStringsTable();

                    // We don't need to add a default localization.
                    shouldAddDefaultLocalization = false;
                }
                else
                {
                    try
                    {
                        if (pair.stringsFile == null)
                        {
                            // We can't create this localization because we
                            // don't have any data for it.
                            Debug.LogWarning($"Not creating a localization for {pair.languageID} in the Yarn Project {project.name} because a text asset containing the strings wasn't found. Add a .csv file containing the translated lines to the Yarn Project's inspector.");
                            continue;
                        }

                        stringTable = StringTableEntry.ParseFromCSV(pair.stringsFile.text);
                    }
                    catch (System.ArgumentException e)
                    {
                        Debug.LogWarning($"Not creating a localization for {pair.languageID} in the Yarn Project {project.name} because an error was encountered during text parsing: {e}");
                        continue;
                    }
                }

                var newLocalization = ScriptableObject.CreateInstance <Localization>();
                newLocalization.LocaleCode = pair.languageID;

                newLocalization.AddLocalizedStrings(stringTable);

                project.localizations.Add(newLocalization);
                newLocalization.name = pair.languageID;

                if (pair.assetsFolder != null)
                {
                    var assetsFolderPath = AssetDatabase.GetAssetPath(pair.assetsFolder);

                    if (assetsFolderPath == null)
                    {
                        // This was somehow not a valid reference?
                        Debug.LogWarning($"Can't find assets for localization {pair.languageID} in {project.name} because a path for the provided assets folder couldn't be found.");
                    }
                    else
                    {
                        var stringIDsToAssets = FindAssetsForLineIDs(stringTable.Select(s => s.ID), assetsFolderPath);

#if YARNSPINNER_DEBUG
                        var stopwatch = System.Diagnostics.Stopwatch.StartNew();
#endif

                        newLocalization.AddLocalizedObjects(stringIDsToAssets.AsEnumerable());

#if YARNSPINNER_DEBUG
                        stopwatch.Stop();
                        Debug.Log($"Imported {stringIDsToAssets.Count()} assets for {project.name} \"{pair.languageID}\" in {stopwatch.ElapsedMilliseconds}ms");
#endif
                    }
                }

                ctx.AddObjectToAsset("localization-" + pair.languageID, newLocalization);


                if (pair.languageID == defaultLanguage)
                {
                    // If this is our default language, set it as such
                    project.baseLocalization = newLocalization;
                }
                else
                {
                    // This localization depends upon a source asset. Make
                    // this asset get re-imported if this source asset was
                    // modified
                    ctx.DependsOnSourceAsset(AssetDatabase.GetAssetPath(pair.stringsFile));
                }
            }

            if (shouldAddDefaultLocalization)
            {
                // We didn't add a localization for the default language.
                // Create one for it now.

                var developmentLocalization = ScriptableObject.CreateInstance <Localization>();

                developmentLocalization.LocaleCode = defaultLanguage;

                var stringTableEntries = compilationResult.StringTable.Select(x => new StringTableEntry
                {
                    ID         = x.Key,
                    Language   = defaultLanguage,
                    Text       = x.Value.text,
                    File       = x.Value.fileName,
                    Node       = x.Value.nodeName,
                    LineNumber = x.Value.lineNumber.ToString(),
                    Lock       = YarnImporter.GetHashString(x.Value.text, 8),
                });

                developmentLocalization.AddLocalizedStrings(stringTableEntries);

                project.baseLocalization = developmentLocalization;

                project.localizations.Add(project.baseLocalization);

                developmentLocalization.name = $"Default ({defaultLanguage})";

                ctx.AddObjectToAsset("default-language", developmentLocalization);
            }

            // Store the compiled program
            byte[] compiledBytes = null;

            using (var memoryStream = new MemoryStream())
                using (var outputStream = new Google.Protobuf.CodedOutputStream(memoryStream))
                {
                    // Serialize the compiled program to memory
                    compilationResult.Program.WriteTo(outputStream);
                    outputStream.Flush();

                    compiledBytes = memoryStream.ToArray();
                }

            project.compiledYarnProgram = compiledBytes;

#if YARNSPINNER_DEBUG
            UnityEngine.Profiling.Profiler.enabled = false;
#endif
        }
Пример #18
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            Debug.Log("OnImportAsset to " + ctx.assetPath);

            try
            {
                // Parse
                var parser = new GltfParser();
                parser.ParsePath(ctx.assetPath);

                // Build Unity Model
                var externalObjectMap = GetExternalObjectMap()
                                        .Select(kv => (kv.Key.name, kv.Value))
                ;

                var context = new ImporterContext(parser, null, externalObjectMap);
                context.InvertAxis = m_reverseAxis;
                context.Load();
                context.ShowMeshes();

                // Texture
                foreach (var info in context.TextureFactory.Textures)
                {
                    if (!info.IsUsed)
                    {
                        continue;
                    }
                    if (!info.IsExternal)
                    {
                        var texture = info.Texture;
                        ctx.AddObjectToAsset(texture.name, texture);
                    }
                }

                // Material
                foreach (var info in context.MaterialFactory.Materials)
                {
                    if (!info.UseExternal)
                    {
                        var material = info.Asset;
                        ctx.AddObjectToAsset(material.name, material);
                    }
                }

                // Mesh
                foreach (var mesh in context.Meshes.Select(x => x.Mesh))
                {
                    ctx.AddObjectToAsset(mesh.name, mesh);
                }

                // Animation
                foreach (var clip in context.AnimationClips)
                {
                    ctx.AddObjectToAsset(clip.name, clip);
                }

                // Root
                ctx.AddObjectToAsset(context.Root.name, context.Root);
                ctx.SetMainObject(context.Root);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
            }
        }
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var width         = 8;
            var height        = 8;
            var mipmapEnabled = true;
            var textureFormat = TextureFormat.ARGB32;
            //var srgbTexture = true;

            // Check if the input textures are valid to be used to build the texture array.
            var isValid = Verify(ctx, false);

            if (isValid)
            {
                // Use the texture assigned to the first slice as "master".
                // This means all other textures have to use same settings as the master texture.
                var sourceTexture = m_Textures[0];
                width         = sourceTexture.width;
                height        = sourceTexture.height;
                textureFormat = sourceTexture.format;

                var sourceTexturePath = AssetDatabase.GetAssetPath(sourceTexture);
                var textureImporter   = (TextureImporter)AssetImporter.GetAtPath(sourceTexturePath);
                mipmapEnabled = textureImporter.mipmapEnabled;
                //srgbTexture = textureImporter.sRGBTexture;
            }

            // Create the texture array.
            // When the texture array asset is being created, there are no input textures added yet,
            // thus we do Max(1, Count) to make sure to add at least 1 slice.
            var texture3D = new Texture3D(width, height, Mathf.Max(1, m_Textures.Count), textureFormat, mipmapEnabled);//, !srgbTexture);

            texture3D.wrapMode   = m_WrapMode;
            texture3D.filterMode = m_FilterMode;
            texture3D.anisoLevel = m_AnisoLevel;

            if (isValid)
            {
                // If everything is valid, copy source textures over to the texture array.

                // Graphics.CopyTexture does not work with Texture3D, I submitted bug-report:
                //   (Case 1208825) 2019.3: Graphics.CopyTexture does not work with Texture3D
                // When Unity Technologies fixed this bug, I can use this code to copy data instead:
                //for (var n = 0; n < m_Textures.Count; ++n)
                //{
                //    var source = m_Textures[n];
                //    Graphics.CopyTexture(source, 0, texture3D, n);
                //}

                var colorData = new Color32[width * height * texture3D.depth];

                for (var n = 0; n < m_Textures.Count; ++n)
                {
                    var source       = m_Textures[n];
                    var sourcePixels = source.GetPixels32();
                    System.Array.Copy(sourcePixels, 0, colorData, width * height * n, sourcePixels.Length);
                }

                texture3D.SetPixels32(colorData);
                texture3D.Apply();
            }
            else
            {
                // If there is any error, copy a magenta colored texture into every slice.
                // I was thinking to only make the invalid slice magenta, but then it's way less obvious that
                // something isn't right with the texture array. Thus I mark the entire texture array as broken.

                var errorPixels = new Color32[width * height];
                for (var n = 0; n < errorPixels.Length; ++n)
                {
                    errorPixels[n] = Color.magenta;
                }

                var texture3DPixels = new Color32[width * height * texture3D.depth];

                for (var n = 0; n < texture3D.depth; ++n)
                {
                    System.Array.Copy(errorPixels, 0, texture3DPixels, width * height * n, errorPixels.Length);
                }

                texture3D.SetPixels32(texture3DPixels);
                texture3D.Apply();
            }

            // Mark all input textures as dependency to the texture array.
            // This causes the texture array to get re-generated when any input texture changes or when the build target changed.
            for (var n = 0; n < m_Textures.Count; ++n)
            {
                var source = m_Textures[n];
                if (source != null)
                {
                    var path = AssetDatabase.GetAssetPath(source);
                    ctx.DependsOnSourceAsset(path);
                }
            }

            ctx.AddObjectToAsset("Texture3D", texture3D);
            ctx.SetMainObject(texture3D);

            if (!isValid)
            {
                // Run the verify step again, but this time we have the main object asset.
                // Console logs should ping the asset, but they don't in 2019.3 beta, bug?
                Verify(ctx, true);
            }
        }
Пример #20
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            // Parse JSON.
            var text = File.ReadAllText(ctx.assetPath);
            var sets = InputActionSet.FromJson(text);
            ////TODO: catch errors

            ////TODO: make sure action names are unique

            // Create asset.
            var asset = ScriptableObject.CreateInstance <InputActionAsset>();

            asset.m_ActionSets = sets;
            ctx.AddObjectToAsset("<root>", asset);
            ctx.SetMainObject(asset);

            // Create subasset for each action.
            for (var i = 0; i < sets.Length; ++i)
            {
                var set         = sets[i];
                var haveSetName = !string.IsNullOrEmpty(set.name);

                foreach (var action in set.actions)
                {
                    var actionObject = ScriptableObject.CreateInstance <InputActionReference>();

                    actionObject.m_Asset      = asset;
                    actionObject.m_SetName    = set.name;
                    actionObject.m_ActionName = action.name;

                    var objectName = action.name;
                    if (haveSetName)
                    {
                        objectName = string.Format("{0}/{1}", set.name, action.name);
                    }

                    actionObject.name = objectName;
                    ctx.AddObjectToAsset(objectName, actionObject);
                }
            }

            // Generate wrapper code, if enabled.
            if (m_GenerateWrapperCode)
            {
                var wrapperFilePath = m_WrapperCodePath;
                if (string.IsNullOrEmpty(wrapperFilePath))
                {
                    var assetPath = ctx.assetPath;
                    var directory = Path.GetDirectoryName(assetPath);
                    var fileName  = Path.GetFileNameWithoutExtension(assetPath);
                    wrapperFilePath = Path.Combine(directory, fileName) + ".cs";
                }

                var options = new InputActionCodeGenerator.Options
                {
                    sourceAssetPath = ctx.assetPath,
                    namespaceName   = m_WrapperCodeNamespace,
                    className       = Path.GetFileNameWithoutExtension(ctx.assetPath)
                };

                if (InputActionCodeGenerator.GenerateWrapperCode(wrapperFilePath, sets, options))
                {
                    // Inform database that we modified a source asset *during* import.
                    AssetDatabase.ImportAsset(wrapperFilePath);
                }
            }
        }
        /// <summary>
        /// Common method performing the import of the asset
        /// </summary>
        /// <param name="ctx">Asset importer context.</param>
        public override void OnImportAsset(AssetImportContext ctx)
        {
            engine.TextureGenerationType = TextureImporterType.Default;

            Texture cookieTextureCube = null;
            Texture cookieTexture2D   = null;

            string iesFilePath  = Path.Combine(Path.GetDirectoryName(Application.dataPath), ctx.assetPath);
            string errorMessage = engine.ReadFile(iesFilePath);

            if (string.IsNullOrEmpty(errorMessage))
            {
                iesMetaData.FileFormatVersion      = engine.FileFormatVersion;
                iesMetaData.IESPhotometricType     = engine.GetPhotometricType();
                iesMetaData.Manufacturer           = engine.GetKeywordValue("MANUFAC");
                iesMetaData.LuminaireCatalogNumber = engine.GetKeywordValue("LUMCAT");
                iesMetaData.LuminaireDescription   = engine.GetKeywordValue("LUMINAIRE");
                iesMetaData.LampCatalogNumber      = engine.GetKeywordValue("LAMPCAT");
                iesMetaData.LampDescription        = engine.GetKeywordValue("LAMP");

                (iesMetaData.IESMaximumIntensity, iesMetaData.IESMaximumIntensityUnit) = engine.GetMaximumIntensity();

                string warningMessage;

                (warningMessage, cookieTextureCube) = engine.GenerateCubeCookie(iesMetaData.CookieCompression, (int)iesMetaData.iesSize);
                if (!string.IsNullOrEmpty(warningMessage))
                {
                    ctx.LogImportWarning($"Cannot properly generate IES Cube texture: {warningMessage}");
                }
                cookieTextureCube.IncrementUpdateCount();

                (warningMessage, cookieTexture2D) = engine.Generate2DCookie(iesMetaData.CookieCompression, iesMetaData.SpotAngle, (int)iesMetaData.iesSize, iesMetaData.ApplyLightAttenuation);
                if (!string.IsNullOrEmpty(warningMessage))
                {
                    ctx.LogImportWarning($"Cannot properly generate IES 2D texture: {warningMessage}");
                }
                cookieTexture2D.IncrementUpdateCount();
            }
            else
            {
                ctx.LogImportError($"Cannot read IES file '{iesFilePath}': {errorMessage}");
            }

            string iesFileName = Path.GetFileNameWithoutExtension(ctx.assetPath);

            var iesObject = ScriptableObject.CreateInstance <IESObject>();

            iesObject.iesMetaData = iesMetaData;
            GameObject lightObject = new GameObject(iesFileName);

            lightObject.transform.localEulerAngles = new Vector3(90f, 0f, iesMetaData.LightAimAxisRotation);

            Light light = lightObject.AddComponent <Light>();

            light.type      = (iesMetaData.PrefabLightType == IESLightType.Point) ? LightType.Point : LightType.Spot;
            light.intensity = 1f;  // would need a better intensity value formula
            light.range     = 10f; // would need a better range value formula
            light.spotAngle = iesMetaData.SpotAngle;

            ctx.AddObjectToAsset("IES", iesObject);
            ctx.SetMainObject(iesObject);

            IESImporter.createRenderPipelinePrefabLight?.Invoke(ctx, iesFileName, iesMetaData.UseIESMaximumIntensity, iesMetaData.IESMaximumIntensityUnit, iesMetaData.IESMaximumIntensity, light, (iesMetaData.PrefabLightType == IESLightType.Point) ? cookieTextureCube : cookieTexture2D);

            if (cookieTextureCube != null)
            {
                cookieTextureCube.name = iesFileName + "-Cube-IES";
                ctx.AddObjectToAsset(cookieTextureCube.name, cookieTextureCube);
            }
            if (cookieTexture2D != null)
            {
                cookieTexture2D.name = iesFileName + "-2D-IES";
                ctx.AddObjectToAsset(cookieTexture2D.name, cookieTexture2D);
            }
        }
        public static async void OnImportGltfAsset(AssetImportContext context)
        {
            var importedObject = await GltfUtility.ImportGltfObjectFromPathAsync(context.assetPath);

            if (importedObject == null ||
                importedObject.GameObjectReference == null)
            {
                Debug.LogError("Failed to import glTF object");
                return;
            }

            var gltfAsset = (GltfAsset)ScriptableObject.CreateInstance(typeof(GltfAsset));

            gltfAsset.GltfObject = importedObject;
            gltfAsset.name       = $"{gltfAsset.GltfObject.Name}{Path.GetExtension(context.assetPath)}";
            gltfAsset.Model      = importedObject.GameObjectReference;
            context.AddObjectToAsset("main", gltfAsset.Model);
            context.SetMainObject(importedObject.GameObjectReference);
            context.AddObjectToAsset("glTF data", gltfAsset);

            bool reImport = false;

            for (var i = 0; i < gltfAsset.GltfObject.textures?.Length; i++)
            {
                GltfTexture gltfTexture = gltfAsset.GltfObject.textures[i];

                if (gltfTexture == null)
                {
                    continue;
                }

                var path = AssetDatabase.GetAssetPath(gltfTexture.Texture);

                if (string.IsNullOrWhiteSpace(path))
                {
                    var textureName = gltfTexture.name;

                    if (string.IsNullOrWhiteSpace(textureName))
                    {
                        textureName = $"Texture_{i}";
                        gltfTexture.Texture.name = textureName;
                    }

                    context.AddObjectToAsset(textureName, gltfTexture.Texture);
                }
                else
                {
                    if (!gltfTexture.Texture.isReadable)
                    {
                        var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
                        if (textureImporter != null)
                        {
                            textureImporter.isReadable = true;
                            textureImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings {
                                format = TextureImporterFormat.RGBA32
                            });
                            textureImporter.SaveAndReimport();
                            reImport = true;
                        }
                    }
                }
            }

            if (reImport)
            {
                var importer = AssetImporter.GetAtPath(context.assetPath);
                importer.SaveAndReimport();
                return;
            }

            for (var i = 0; i < gltfAsset.GltfObject.meshes?.Length; i++)
            {
                GltfMesh gltfMesh = gltfAsset.GltfObject.meshes[i];

                string meshName = string.IsNullOrWhiteSpace(gltfMesh.name) ? $"Mesh_{i}" : gltfMesh.name;

                gltfMesh.Mesh.name = meshName;
                context.AddObjectToAsset($"{meshName}", gltfMesh.Mesh);
            }

            if (gltfAsset.GltfObject.materials != null)
            {
                foreach (GltfMaterial gltfMaterial in gltfAsset.GltfObject.materials)
                {
                    if (context.assetPath.EndsWith(".glb"))
                    {
                        context.AddObjectToAsset(gltfMaterial.name, gltfMaterial.Material);
                    }
                    else
                    {
                        var relativePath = Path.GetFullPath(Path.GetDirectoryName(context.assetPath)).Replace(Path.GetFullPath(Application.dataPath), "Assets");
                        relativePath = Path.Combine(relativePath, $"{gltfMaterial.name}.mat");
                        AssetDatabase.CreateAsset(gltfMaterial.Material, relativePath);
                        gltfMaterial.Material = AssetDatabase.LoadAssetAtPath <Material>(relativePath);
                    }
                }
            }
        }
Пример #23
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            if (ctx == null)
            {
                return;
            }

            var path = ctx.assetPath;

            AlembicStream.DisconnectStreamsWithPath(path);

            var fileName       = Path.GetFileNameWithoutExtension(path);
            var previousGoName = fileName;

            if (!string.IsNullOrEmpty(rootGameObjectName))
            {
                previousGoName = rootGameObjectName;
            }
            var go = new GameObject(previousGoName);

            var streamDescriptor = ScriptableObject.CreateInstance <AlembicStreamDescriptor>();

            streamDescriptor.name      = go.name + "_ABCDesc";
            streamDescriptor.PathToAbc = path;
            streamDescriptor.Settings  = StreamSettings;

            using (var abcStream = new AlembicStream(go, streamDescriptor))
            {
                abcStream.AbcLoad(true, true);

                abcStream.GetTimeRange(ref abcStartTime, ref abcEndTime);
                if (firstImport)
                {
                    startTime = abcStartTime;
                    endTime   = abcEndTime;
                }
                streamDescriptor.abcStartTime = abcStartTime;
                streamDescriptor.abcEndTime   = abcEndTime;

                var streamPlayer = go.AddComponent <AlembicStreamPlayer>();
                streamPlayer.StreamDescriptor = streamDescriptor;
                streamPlayer.StartTime        = StartTime;
                streamPlayer.EndTime          = EndTime;

                var subassets = new Subassets(ctx);
                subassets.Add(streamDescriptor.name, streamDescriptor);
                GenerateSubAssets(subassets, abcStream.abcTreeRoot, streamDescriptor);

                AlembicStream.ReconnectStreamsWithPath(path);

                var prevIdName = fileName;
                if (!string.IsNullOrEmpty(rootGameObjectId))
                {
                    prevIdName = rootGameObjectId;
                }

                ctx.AddObjectToAsset(prevIdName, go);
                ctx.SetMainObject(go);
            }

            firstImport = false;
        }
Пример #24
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var graphAsset   = ScriptableObject.CreateInstance <SubGraphAsset>();
            var subGraphPath = ctx.assetPath;
            var subGraphGuid = AssetDatabase.AssetPathToGUID(subGraphPath);

            graphAsset.assetGuid = subGraphGuid;
            var textGraph      = File.ReadAllText(subGraphPath, Encoding.UTF8);
            var messageManager = new MessageManager();
            var graphData      = new GraphData
            {
                isSubGraph = true, assetGuid = subGraphGuid, messageManager = messageManager
            };

            MultiJson.Deserialize(graphData, textGraph);

            try
            {
                ProcessSubGraph(graphAsset, graphData);
            }
            catch (Exception e)
            {
                graphAsset.isValid = false;
                Debug.LogException(e, graphAsset);
            }
            finally
            {
                if (messageManager.AnyError())
                {
                    graphAsset.isValid = false;
                    foreach (var pair in messageManager.GetNodeMessages())
                    {
                        var node = graphData.GetNodeFromId(pair.Key);
                        foreach (var message in pair.Value)
                        {
                            MessageManager.Log(node, subGraphPath, message, graphAsset);
                        }
                    }
                }
                messageManager.ClearAll();
            }

            Texture2D texture = Resources.Load <Texture2D>("Icons/sg_subgraph_icon");

            ctx.AddObjectToAsset("MainAsset", graphAsset, texture);
            ctx.SetMainObject(graphAsset);

            var metadata = ScriptableObject.CreateInstance <ShaderSubGraphMetadata>();

            metadata.hideFlags         = HideFlags.HideInHierarchy;
            metadata.assetDependencies = new List <UnityEngine.Object>();

            AssetCollection assetCollection = new AssetCollection();

            MinimalGraphData.GatherMinimalDependenciesFromFile(assetPath, assetCollection);

            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.IncludeInExportPackage))
                {
                    // this sucks that we have to fully load these assets just to set the reference,
                    // which then gets serialized as the GUID that we already have here.  :P

                    var dependencyPath = AssetDatabase.GUIDToAssetPath(asset.Key);
                    if (!string.IsNullOrEmpty(dependencyPath))
                    {
                        metadata.assetDependencies.Add(
                            AssetDatabase.LoadAssetAtPath(dependencyPath, typeof(UnityEngine.Object)));
                    }
                }
            }
            ctx.AddObjectToAsset("Metadata", metadata);

            // declare dependencies
            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.SourceDependency))
                {
                    ctx.DependsOnSourceAsset(asset.Key);

                    // I'm not sure if this warning below is actually used or not, keeping it to be safe
                    var assetPath = AssetDatabase.GUIDToAssetPath(asset.Key);

                    // Ensure that dependency path is relative to project
                    if (!string.IsNullOrEmpty(assetPath) && !assetPath.StartsWith("Packages/") && !assetPath.StartsWith("Assets/"))
                    {
                        Debug.LogWarning($"Invalid dependency path: {assetPath}", graphAsset);
                    }
                }

                // NOTE: dependencies declared by GatherDependenciesFromSourceFile are automatically registered as artifact dependencies
                // HOWEVER: that path ONLY grabs dependencies via MinimalGraphData, and will fail to register dependencies
                // on GUIDs that don't exist in the project.  For both of those reasons, we re-declare the dependencies here.
                if (asset.Value.HasFlag(AssetCollection.Flags.ArtifactDependency))
                {
                    ctx.DependsOnArtifact(asset.Key);
                }
            }
        }
Пример #25
0
    public override void OnImportAsset(AssetImportContext ctx)
    {
        var item = LoadItemFromFile(ctx.assetPath);

        var root = new GameObject(Path.GetFileNameWithoutExtension(ctx.assetPath));

        ctx.AddObjectToAsset("root", root);
        ctx.SetMainObject(root);

        for (int a = 0; a < item.Arrangements.Count; a++)
        {
            var arrangement = item.Arrangements[a];

            var diffuseTexture = LoadTexture(
                string.Format("{0}_Diffuse", arrangement.Id), arrangement.DiffuseTexture);
            var normalTexture = LoadTexture(
                string.Format("{0}_Normal", arrangement.Id), arrangement.NormalTexture);
            var gearstackTexture = LoadTexture(
                string.Format("{0}_Gearstack", arrangement.Id), arrangement.GearstackTexture);

            ctx.AddObjectToAsset(diffuseTexture.name, diffuseTexture);
            ctx.AddObjectToAsset(normalTexture.name, normalTexture);
            ctx.AddObjectToAsset(gearstackTexture.name, gearstackTexture);

            var material = new Material(Shader.Find("Standard 2-Sided"));
            material.name = string.Format("{0}_Material", arrangement.Id);
            material.SetTexture("_MainTex", diffuseTexture);
            material.SetTexture("_BumpMap", normalTexture);
            ctx.AddObjectToAsset(material.name, material);

            for (int b = 0; b < arrangement.Bobs.Count; b++)
            {
                var bob = arrangement.Bobs[b];
                for (int p = 0; p < bob.Bits.Count; p++)
                {
                    var    bit  = bob.Bits[p];
                    string name = string.Format("{0}_{1}", arrangement.Id, p);

                    var indices = bob.Indices.Skip(bit.StartIndex)
                                  .Take(bit.EndIndex - bit.StartIndex).ToArray();
                    if (!bob.IsTriangleList)
                    {
                        indices = ConvertTriangleStripToTriangleList(indices);
                    }

                    // remove loose vertices
                    int minIndex = indices.Min();
                    int maxIndex = indices.Max();
                    var vertices = bob.Vertices.Skip(minIndex)
                                   .Take(maxIndex - minIndex + 1).ToArray();
                    indices = indices.Select(i => i - minIndex).ToArray();

                    var obj = CreateMesh(name, vertices, indices);
                    obj.transform.SetParent(root.transform);

                    var mesh = obj.GetComponent <MeshFilter>().sharedMesh;
                    ctx.AddObjectToAsset(mesh.name, mesh);

                    obj.GetComponent <MeshRenderer>().sharedMaterial = material;
                }
            }
        }
    }
Пример #26
0
        /// <summary>
        /// Import a .ftex file.
        /// </summary>
        /// <param name="ctx"></param>
        public override void OnImportAsset(AssetImportContext ctx)
        {
            #region Readers
            var filepathSansExtension = Path.GetDirectoryName(assetPath) + "\\" + Path.GetFileNameWithoutExtension(assetPath);

            List <BinaryReader> binaryReaders = new List <BinaryReader>();
            binaryReaders.Add(new BinaryReader(new FileStream(assetPath, FileMode.Open)));

            for (int i = 1; i < 7; i++)
            {
                var file = filepathSansExtension + "." + i + ".ftexs";

                if (!File.Exists(file))
                {
                    break;
                }

                var fileStream = new FileStream(file, FileMode.Open);
                binaryReaders.Add(new BinaryReader(fileStream));
            }
            #endregion

            try
            {
                var readFunctions = (from reader in binaryReaders select new FoxLib.GrTexture.ReadFunctions(reader.ReadUInt16, reader.ReadUInt32, reader.ReadUInt64, reader.ReadByte, reader.ReadBytes, (numberOfBytes => SkipBytes(reader, numberOfBytes)), (bytePos => MoveStream(reader, bytePos)))).ToArray();

                FoxLib.GrTexture.GrTexture grTexture = FoxLib.GrTexture.Read(readFunctions);

                var textureFormat = GrTextureUtils.GetTextureFormat(grTexture.PixelFormat, grTexture.Depth);
                var isLinear      = GrTextureUtils.GetLinear(grTexture.TextureType);

                if (grTexture.TextureType == FoxLib.GrTexture.TextureType.Cube)
                {
                    #region Cube
                    var texture = new Cubemap(grTexture.Width, UnityEngine.Experimental.Rendering.GraphicsFormat.R8G8B8A8_SRGB, UnityEngine.Experimental.Rendering.TextureCreationFlags.MipChain);

                    var textureData = DirectXTexHelper.Decompress(grTexture.Width, grTexture.Height, GrTextureUtils.GetDXGIFormat(grTexture.PixelFormat), grTexture.MipMapCount, grTexture.DDSData);

                    for (int i = 0; i < textureData.Length; i++)
                    {
                        var faceData = textureData[i];

                        {
                            var colours = new Color[faceData.Length / 4];

                            for (int j = 0; j < faceData.Length / 4; j++)
                            {
                                var data = faceData.Skip(j * 4).Take(4).ToArray();

                                float R = data[0];
                                float G = data[1];
                                float B = data[2];
                                float A = data[3];

                                float nrmR = R / 255.0f;
                                float nrmG = G / 255.0f;
                                float nrmB = B / 255.0f;
                                float nrmA = A / 255.0f;

                                colours[j] = new Color(nrmR,
                                                       nrmG,
                                                       nrmB,
                                                       nrmA);
                            }

                            texture.SetPixels(colours, (CubemapFace)i);
                        }
                    }

                    texture.Apply(true);

                    ctx.AddObjectToAsset("ftex", texture);
                    ctx.SetMainObject(texture);

                    #endregion
                }
                else
                {
                    if (grTexture.Depth == 1)
                    {
                        #region 2D

                        var hasMipmaps = grTexture.MipMapCount > 1;
                        var texture    = new Texture2D(grTexture.Width, grTexture.Height, textureFormat, hasMipmaps, isLinear);

                        if (hasMipmaps)
                        {
                            if (texture.mipmapCount > grTexture.MipMapCount)
                            {
                                var    length      = grTexture.DDSData.Length;
                                IntPtr pixelBuffer = DirectXTexHelper.GenerateNecessaryMipMapsAndFlipImage(grTexture.Width, grTexture.Height, GrTextureUtils.GetDXGIFormat(grTexture.PixelFormat), grTexture.MipMapCount, grTexture.DDSData, ref length);
                                texture.LoadRawTextureData(pixelBuffer, length);
                            }
                            else
                            {
                                texture.LoadRawTextureData(grTexture.DDSData);
                            }
                        }
                        else
                        {
                            byte[] newPixelData = DirectXTexHelper.Flip2DImage(grTexture.Width, grTexture.Height, GrTextureUtils.GetDXGIFormat(grTexture.PixelFormat), grTexture.MipMapCount, grTexture.DDSData);
                            texture.LoadRawTextureData(newPixelData);
                            texture.Apply();
                        }

                        ctx.AddObjectToAsset("ftex", texture, texture);
                        ctx.SetMainObject(texture);

                        #endregion
                    }
                    else
                    {
                        #region 3D

                        var texture = GrTextureUtils.CreateTexture3D(grTexture.Width, grTexture.Height, grTexture.Depth, GrTextureUtils.GetTextureFormat(grTexture.PixelFormat, grTexture.Depth), grTexture.DDSData);

                        ctx.AddObjectToAsset("ftex", texture);
                        ctx.SetMainObject(texture);
                        #endregion
                    }
                }

                this.userData = "NrtFlag: " + grTexture.NrtFlag + ", TextureType: " + grTexture.TextureType + ", UnknownFlags: " + grTexture.UnknownFlags;
            }
            finally
            {
                foreach (var reader in binaryReaders)
                {
                    reader.Close();
                }
            }
        }
Пример #27
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            try
            {
                PCache pcache = PCache.FromFile(ctx.assetPath);

                PointCacheAsset cache = ScriptableObject.CreateInstance <PointCacheAsset>();
                cache.name = "PointCache";
                ctx.AddObjectToAsset("PointCache", cache);
                ctx.SetMainObject(cache);

                List <InProperty> inProperties = new List <InProperty>();
                Dictionary <string, OutProperty>    outProperties = new Dictionary <string, OutProperty>();
                Dictionary <OutProperty, Texture2D> surfaces      = new Dictionary <OutProperty, Texture2D>();

                foreach (var prop in pcache.properties)
                {
                    OutProperty p_out;
                    if (outProperties.ContainsKey(prop.ComponentName))
                    {
                        p_out      = outProperties[prop.ComponentName];
                        p_out.Size = Math.Max(p_out.Size, prop.ComponentIndex + 1);
                    }
                    else
                    {
                        p_out = new OutProperty(prop.Type, prop.ComponentName, prop.ComponentIndex + 1);
                        outProperties.Add(prop.ComponentName, p_out);
                    }

                    inProperties.Add(new InProperty(prop.Type, prop.Name, prop.ComponentIndex, p_out));
                }


                int width, height;
                FindBestSize(pcache.elementCount, out width, out height);

                // Output Surface Creation
                foreach (var kvp in outProperties)
                {
                    TextureFormat surfaceFormat = TextureFormat.Alpha8;
                    switch (kvp.Value.PropertyType)
                    {
                    case "uchar":
                        if (kvp.Value.Size == 1)
                        {
                            surfaceFormat = TextureFormat.Alpha8;
                        }
                        else
                        {
                            surfaceFormat = TextureFormat.RGBA32;
                        }
                        break;

                    case "float":
                        if (kvp.Value.Size == 1)
                        {
                            surfaceFormat = TextureFormat.RHalf;
                        }
                        else
                        {
                            surfaceFormat = TextureFormat.RGBAHalf;
                        }
                        break;

                    default: throw new NotImplementedException("Types other than uchar/float are not supported yet");
                    }

                    Texture2D surface = new Texture2D(width, height, surfaceFormat, false);
                    surface.name = kvp.Key;
                    surfaces.Add(kvp.Value, surface);
                }

                cache.PointCount = pcache.elementCount;
                cache.surfaces   = new Texture2D[surfaces.Count];

                Dictionary <OutProperty, Color> outValues = new Dictionary <OutProperty, Color>();
                foreach (var kvp in outProperties)
                {
                    outValues.Add(kvp.Value, new Color());
                }

                for (int i = 0; i < pcache.elementCount; i++)
                {
                    int idx = 0;
                    foreach (var prop in inProperties)
                    {
                        float val = 0.0f;
                        switch (prop.PropertyType)
                        {
                        case "uchar":
                            val = Mathf.Clamp01(((byte)pcache.buckets[idx][i]) / 255.0f);
                            break;

                        case "float":
                            val = ((float)pcache.buckets[idx][i]);
                            break;

                        default: throw new NotImplementedException("Types other than uchar/float are not supported yet");
                        }

                        SetPropValue(prop.Index, outValues, prop.OutProperty, val);
                        idx++;
                    }
                    foreach (var kvp in outProperties)
                    {
                        surfaces[kvp.Value].SetPixel(i % width, i / width, outValues[kvp.Value]);
                    }
                }

                int k = 0;

                foreach (var kvp in surfaces)
                {
                    kvp.Value.Apply();
                    kvp.Value.hideFlags = HideFlags.HideInHierarchy;
                    ctx.AddObjectToAsset(kvp.Key.Name, kvp.Value);
                    cache.surfaces[k] = kvp.Value;
                    k++;
                }
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);
            }
        }
        public override void OnImportAsset(AssetImportContext ctx)
        {
            {
                var ext = Path.GetExtension(ctx.assetPath).ToLower();
                if (ext == ".vox")
                {
                    fileType = VoxelBase.FileType.vox;
                }
                else if (ext == ".qb")
                {
                    fileType = VoxelBase.FileType.qb;
                }
                else
                {
                    return;
                }
            }

            #region DefaultScale
            if (dataVersion == 0 &&
                importScale == Vector3.one &&
                AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(ctx.assetPath) == null)
            {
                var x = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleX", 1f);
                var y = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleY", 1f);
                var z = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleZ", 1f);
                importScale = new Vector3(x, y, z);
            }
            #endregion

            Action <string> LogImportError = (log) =>
            {
#if UNITY_2018_1_OR_NEWER
                ctx.LogImportError(log);
#else
                Debug.LogError(log);
#endif
            };
            Action <VoxelBase> SetBasicOptions = (voxelObject) =>
            {
                voxelObject.legacyVoxImport               = legacyVoxImport;
                voxelObject.importMode                    = importMode;
                voxelObject.importScale                   = importScale;
                voxelObject.importOffset                  = importOffset;
                voxelObject.combineFaces                  = combineFaces;
                voxelObject.ignoreCavity                  = ignoreCavity;
                voxelObject.shareSameFace                 = shareSameFace;
                voxelObject.removeUnusedPalettes          = removeUnusedPalettes;
                voxelObject.voxelStructure                = outputStructure ? ScriptableObject.CreateInstance <VoxelStructure>() : null;
                voxelObject.generateLightmapUVs           = generateLightmapUVs;
                voxelObject.generateLightmapUVsAngleError = generateLightmapUVsAngleError;
                voxelObject.generateLightmapUVsAreaError  = generateLightmapUVsAreaError;
                voxelObject.generateLightmapUVsHardAngle  = generateLightmapUVsHardAngle;
                voxelObject.generateLightmapUVsPackMargin = generateLightmapUVsPackMargin;
                voxelObject.generateTangents              = generateTangents;
                voxelObject.meshFaceVertexOffset          = meshFaceVertexOffset;
                voxelObject.loadFromVoxelFile             = loadFromVoxelFile;
                voxelObject.generateMipMaps               = generateMipMaps;
            };

            Action <VoxelBaseCore> Export = (core) =>
            {
                if (export)
                {
                    var fullPath = Application.dataPath + ctx.assetPath.Remove(0, "Assets".Length);
                    fullPath = fullPath.Remove(fullPath.LastIndexOf('.')) + ".dae";
                    core.ExportDaeFile(fullPath, false);
                }
            };

            var gameObject = new GameObject(Path.GetFileNameWithoutExtension(ctx.assetPath));
            if (string.IsNullOrEmpty(gameObjectName))
            {
                gameObjectName = gameObject.name;
            }
            if (meshMode == MeshMode.Combine)
            {
                #region Combine
                var voxelObject = gameObject.AddComponent <VoxelObject>();
                SetBasicOptions(voxelObject);
                var objectCore = new VoxelObjectCore(voxelObject);
                try
                {
                    if (!objectCore.Create(ctx.assetPath, null))
                    {
                        LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                        DestroyImmediate(gameObject);
                        return;
                    }
                }
                catch
                {
                    LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                    DestroyImmediate(gameObject);
                    return;
                }

                #region Correspondence in Issue ID 947055 Correction in case before correction is applied
                foreach (var material in voxelObject.materials)
                {
                    if (material != null)
                    {
                        material.hideFlags |= HideFlags.NotEditable;
                    }
                }
                if (voxelObject.atlasTexture != null)
                {
                    voxelObject.atlasTexture.hideFlags |= HideFlags.NotEditable;
                }
                if (voxelObject.mesh != null)
                {
                    voxelObject.mesh.hideFlags |= HideFlags.NotEditable;
                }
                #endregion

                #region Material
                {
                    materials     = new Material[voxelObject.materialIndexes.Count];
                    materialNames = new string[voxelObject.materialIndexes.Count];
                    for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                    {
                        var index    = voxelObject.materialIndexes[i];
                        var material = voxelObject.materials[index];
                        material.name    = string.Format("mat{0}", index);
                        materials[i]     = material;
                        materialNames[i] = material.name;
                    }
                    if (remappedMaterials != null)
                    {
                        remappedMaterials = remappedMaterials.Where(item => item.material != null && materialNames.Contains(item.name)).ToArray();
                    }
                }
                #endregion

                #region Collider
                switch (colliderType)
                {
                case ColliderType.Box:
                    gameObject.AddComponent <BoxCollider>();
                    break;

                case ColliderType.Sphere:
                    gameObject.AddComponent <SphereCollider>();
                    break;

                case ColliderType.Capsule:
                    gameObject.AddComponent <CapsuleCollider>();
                    break;

                case ColliderType.Mesh:
                    gameObject.AddComponent <MeshCollider>();
                    break;
                }
                #endregion

                Export(objectCore);

#if UNITY_2017_3_OR_NEWER
                ctx.AddObjectToAsset(gameObjectName, gameObject);
                ctx.AddObjectToAsset(voxelObject.mesh.name = "mesh", voxelObject.mesh);
                {
                    var list = new List <Material>();
                    for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                    {
                        var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                        list.Add(material);
                        if (remappedMaterials != null)
                        {
                            var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                            if (index >= 0)
                            {
                                list[i] = remappedMaterials[index].material;
                                continue;
                            }
                        }
                        ctx.AddObjectToAsset(material.name, material);
                    }
                    gameObject.GetComponent <MeshRenderer>().sharedMaterials = list.ToArray();
                }
                ctx.AddObjectToAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddObjectToAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
                }

                VoxelObject.DestroyImmediate(voxelObject);

                ctx.SetMainObject(gameObject);
#else
                ctx.SetMainAsset(gameObjectName, gameObject);
                ctx.AddSubAsset(voxelObject.mesh.name = "mesh", voxelObject.mesh);
                for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                {
                    var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                    ctx.AddSubAsset(material.name, material);
                }
                ctx.AddSubAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddSubAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
                }

                VoxelObject.DestroyImmediate(voxelObject);
#endif
                #endregion
            }
            else if (meshMode == MeshMode.Individual)
            {
                #region Individual
                var voxelObject = gameObject.AddComponent <VoxelChunksObject>();
                SetBasicOptions(voxelObject);
                {
                    voxelObject.createContactChunkFaces = createContactChunkFaces;
                    voxelObject.materialMode            = materialMode;
                }
                var objectCore = new VoxelChunksObjectCore(voxelObject);
                {
                    objectCore.chunkNameFormat = "{0}";
                }
                try
                {
                    if (!objectCore.Create(ctx.assetPath, null))
                    {
                        LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                        DestroyImmediate(gameObject);
                        return;
                    }
                }
                catch
                {
                    LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                    DestroyImmediate(gameObject);
                    return;
                }

                #region Correspondence in Issue ID 947055 Correction in case before correction is applied
                if (voxelObject.materials != null)
                {
                    foreach (var material in voxelObject.materials)
                    {
                        if (material != null)
                        {
                            material.hideFlags |= HideFlags.NotEditable;
                        }
                    }
                }
                if (voxelObject.atlasTexture != null)
                {
                    voxelObject.atlasTexture.hideFlags |= HideFlags.NotEditable;
                }
                foreach (var chunk in voxelObject.chunks)
                {
                    if (chunk.materials != null)
                    {
                        foreach (var material in chunk.materials)
                        {
                            if (material != null)
                            {
                                material.hideFlags |= HideFlags.NotEditable;
                            }
                        }
                    }
                    if (chunk.atlasTexture != null)
                    {
                        chunk.atlasTexture.hideFlags |= HideFlags.NotEditable;
                    }
                    if (chunk.mesh != null)
                    {
                        chunk.mesh.hideFlags |= HideFlags.NotEditable;
                    }
                }
                #endregion

                #region Material
                {
                    if (materialMode == VoxelChunksObject.MaterialMode.Combine)
                    {
                        materials     = new Material[voxelObject.materialIndexes.Count];
                        materialNames = new string[voxelObject.materialIndexes.Count];
                        for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                        {
                            var index    = voxelObject.materialIndexes[i];
                            var material = voxelObject.materials[index];
                            material.name    = string.Format("mat{0}", index);
                            materials[i]     = material;
                            materialNames[i] = material.name;
                        }
                    }
                    else if (materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        List <Material> list = new List <Material>();
                        foreach (var chunk in voxelObject.chunks)
                        {
                            for (int i = 0; i < chunk.materialIndexes.Count; i++)
                            {
                                var index    = chunk.materialIndexes[i];
                                var material = chunk.materials[index];
                                material.name = chunk.gameObject.name + string.Format("_mat{0}", index);
                                if (!list.Contains(material))
                                {
                                    list.Add(material);
                                }
                            }
                        }
                        materials     = list.ToArray();
                        materialNames = new string[list.Count];
                        for (int i = 0; i < list.Count; i++)
                        {
                            materialNames[i] = list[i].name;
                        }
                    }
                    if (remappedMaterials != null)
                    {
                        remappedMaterials = remappedMaterials.Where(item => item.material != null && materialNames.Contains(item.name)).ToArray();
                    }
                }
                #endregion

                #region Collider
                foreach (var chunk in voxelObject.chunks)
                {
                    switch (colliderType)
                    {
                    case ColliderType.Box:
                        chunk.gameObject.AddComponent <BoxCollider>();
                        break;

                    case ColliderType.Sphere:
                        chunk.gameObject.AddComponent <SphereCollider>();
                        break;

                    case ColliderType.Capsule:
                        chunk.gameObject.AddComponent <CapsuleCollider>();
                        break;

                    case ColliderType.Mesh:
                        chunk.gameObject.AddComponent <MeshCollider>();
                        break;
                    }
                }
                #endregion

                Export(objectCore);

#if UNITY_2017_3_OR_NEWER
                ctx.AddObjectToAsset(gameObjectName, gameObject);
                foreach (var chunk in voxelObject.chunks)
                {
                    ctx.AddObjectToAsset(chunk.mesh.name = chunk.gameObject.name + "_mesh", chunk.mesh);
                }
                {
                    if (materialMode == VoxelChunksObject.MaterialMode.Combine)
                    {
                        var materials = new List <Material>();
                        for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                        {
                            var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                            materials.Add(material);
                            if (remappedMaterials != null)
                            {
                                var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                if (index >= 0)
                                {
                                    materials[i] = remappedMaterials[index].material;
                                    continue;
                                }
                            }
                            ctx.AddObjectToAsset(material.name, material);
                        }
                        foreach (var chunk in voxelObject.chunks)
                        {
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                        }
                        ctx.AddObjectToAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
                    }
                    else if (materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        foreach (var chunk in voxelObject.chunks)
                        {
                            var materials = new List <Material>();
                            for (int i = 0; i < chunk.materialIndexes.Count; i++)
                            {
                                var material = chunk.materials[chunk.materialIndexes[i]];
                                materials.Add(material);
                                if (remappedMaterials != null)
                                {
                                    var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                    if (index >= 0)
                                    {
                                        materials[i] = remappedMaterials[index].material;
                                        continue;
                                    }
                                }
                                ctx.AddObjectToAsset(material.name, material);
                            }
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                            ctx.AddObjectToAsset(chunk.atlasTexture.name = chunk.gameObject.name + "_tex", chunk.atlasTexture);
                        }
                    }
                }
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddObjectToAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
                }

                foreach (var chunk in voxelObject.chunks)
                {
                    VoxelChunksObjectChunk.DestroyImmediate(chunk.GetComponent <VoxelChunksObjectChunk>());
                }
                VoxelObject.DestroyImmediate(voxelObject);

                ctx.SetMainObject(gameObject);
#else
                ctx.SetMainAsset(gameObjectName, gameObject);
                foreach (var chunk in voxelObject.chunks)
                {
                    ctx.AddSubAsset(chunk.mesh.name = chunk.gameObject.name + "_mesh", chunk.mesh);
                }
                {
                    if (materialMode == VoxelChunksObject.MaterialMode.Combine)
                    {
                        var materials = new List <Material>();
                        for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                        {
                            var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                            materials.Add(material);
                            if (remappedMaterials != null)
                            {
                                var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                if (index >= 0)
                                {
                                    materials[i] = remappedMaterials[index].material;
                                    continue;
                                }
                            }
                            ctx.AddSubAsset(material.name, material);
                        }
                        foreach (var chunk in voxelObject.chunks)
                        {
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                        }
                        ctx.AddSubAsset(voxelObject.atlasTexture.name = "tex", voxelObject.atlasTexture);
                    }
                    else if (materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        foreach (var chunk in voxelObject.chunks)
                        {
                            var materials = new List <Material>();
                            for (int i = 0; i < chunk.materialIndexes.Count; i++)
                            {
                                var material = chunk.materials[chunk.materialIndexes[i]];
                                materials.Add(material);
                                if (remappedMaterials != null)
                                {
                                    var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                    if (index >= 0)
                                    {
                                        materials[i] = remappedMaterials[index].material;
                                        continue;
                                    }
                                }
                                ctx.AddSubAsset(material.name, material);
                            }
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                            ctx.AddSubAsset(chunk.atlasTexture.name = chunk.gameObject.name + "_tex", chunk.atlasTexture);
                        }
                    }
                }
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddSubAsset(voxelObject.voxelStructure.name = "structure", voxelObject.voxelStructure);
                }

                foreach (var chunk in voxelObject.chunks)
                {
                    VoxelChunksObjectChunk.DestroyImmediate(chunk.GetComponent <VoxelChunksObjectChunk>());
                }
                VoxelObject.DestroyImmediate(voxelObject);
#endif
                #endregion
            }

            dataVersion = EditorDataVersion;
        }
Пример #29
0
        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 builder = new UniVRM10.EditorUnityBuilder();
                var assets  = builder.ToUnityAsset(model, assetPath, this);

                // Texture
                var externalTextures = this.GetExternalUnityObjects <UnityEngine.Texture2D>();
                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 <UnityEngine.Material>();
                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);
            }
        }
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var path = ctx.assetPath;
            var name = Path.GetFileNameWithoutExtension(path);

            var text  = File.ReadAllText(path);
            var lines = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

            var definitionFile = ScriptableObject.CreateInstance <OdinAttributeDefinitionFile>();

            definitionFile.name = name;

            ctx.AddObjectToAsset(name, definitionFile);
            ctx.SetMainObject(definitionFile);

            string globalCondition = string.Empty;
            Type   currentType     = null;
            OdinAttributeDefinition currentDefinition = null;

            for (int lineIndex = 0; lineIndex < lines.Length; ++lineIndex)
            {
                // Strip leading spaces
                string line = lines[lineIndex].Trim();

                if (line[0] == '?')                   // If the first character is a ? then this is a condition
                {
                    var substring = line.Substring(1);
                    if (currentDefinition == null)
                    {
                        if (string.IsNullOrEmpty(globalCondition))
                        {
                            globalCondition = substring;
                        }
                        else
                        {
                            Debug.LogError($"Only a single global condition per OAD. '{substring}' ignored.");
                        }
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(globalCondition) && string.IsNullOrEmpty(currentDefinition.requiredCondition))
                        {
                            currentDefinition.requiredCondition = substring;
                        }
                        else
                        {
                            if (!string.IsNullOrEmpty(globalCondition))
                            {
                                Debug.LogError($"Global condition is already set. Local '{substring}' ignored.");
                            }
                            if (!string.IsNullOrEmpty(currentDefinition.requiredCondition))
                            {
                                Debug.LogError($"Local condition is already set. '{substring}' ignored.");
                            }
                        }
                    }
                }
                else if (line[0] == '%')                   // If the first character is a % sign then it's a type
                {
                    var substring = line.Substring(1);
                    var type      = OdinAttributeDefinition.GetTypeFromString(substring);
                    if (type == null)
                    {
                        Debug.LogError($"{substring} could not be converted to a type.");
                        break;
                    }

                    currentType            = type;
                    currentDefinition      = ScriptableObject.CreateInstance <OdinAttributeDefinition>();
                    currentDefinition.name = $"{type.FullName}_OAD";
                    currentDefinition.type = type;

                    ctx.AddObjectToAsset(currentDefinition.name, currentDefinition);

                    definitionFile.definitions.Add(currentDefinition);
                }
                else if (line[0] == '+')
                {
                    var substring = line.Substring(1);
                    if (currentDefinition == null)
                    {
                        Debug.LogError($"{substring}: no active type.");
                        break;
                    }

                    currentDefinition.addedSelfAttributeStrings.Add(substring);
                }
                else if (line[0] == '-')
                {
                    var substring = line.Substring(1);
                    if (currentDefinition == null)
                    {
                        Debug.LogError($"{substring}: no active type.");
                        break;
                    }

                    if (line.Length >= 2 && line[1] == '-')                       // -- Means remove all attributes from this type
                    {
                        currentDefinition.removeAllSelfAttributes = true;
                        if (line.Length >= 3 && line[2] == '-')                           // --- Means remove all attributes from this type and all it's members
                        {
                            currentDefinition.removeAllMemberAttributes = true;
                        }
                    }
                    else
                    {
                        currentDefinition.removedSelfAttributeStrings.Add(substring);
                    }
                }
                // TODO: Add '-' to allow removing attributes
                else if (line[0] == '*')                   // *memberName+new LabelWidthAttribute
                {
                    var substring = line.Substring(1);
                    if (currentDefinition == null)
                    {
                        Debug.LogError($"{substring}: no active type.");
                        break;
                    }

                    int plusIndex  = substring.IndexOf('+');
                    int minusIndex = substring.IndexOf('-');

                    // Definitely not valid
                    if (plusIndex == -1 && minusIndex == -1)
                    {
                        Debug.LogError($"{substring}: No member action found (+,-).");
                        break;
                    }

                    if (plusIndex >= 0)
                    {
                        string memberSubstring = substring.Substring(0, plusIndex);
                        if (plusIndex + 1 >= substring.Length)
                        {
                            Debug.LogError($"{substring}: No attribute found");
                            break;
                        }

                        string attributeSubstring = substring.Substring(plusIndex + 1);

                        List <string> attributes = null;
                        if (!currentDefinition.addedMemberAttributeStrings.TryGetValue(memberSubstring, out attributes))
                        {
                            currentDefinition.addedMemberAttributeStrings[memberSubstring] = attributes = new List <string>();
                        }

                        attributes.Add(attributeSubstring);
                    }
                    else
                    {
                        string memberSubstring = substring.Substring(0, minusIndex);
                        if (minusIndex + 1 >= substring.Length)
                        {
                            Debug.LogError($"{substring}: No attribute found");
                            break;
                        }

                        string attributeSubstring = substring.Substring(minusIndex + 1);
                        if (attributeSubstring.Trim() == "-")                           // Found '--', remove all attributes from member name
                        {
                            currentDefinition.removeMemberAttributesAll.Add(memberSubstring);
                        }
                        else
                        {
                            List <string> attributes = null;
                            if (!currentDefinition.removedMemberAttributeStrings.TryGetValue(memberSubstring, out attributes))
                            {
                                currentDefinition.removedMemberAttributeStrings[memberSubstring] = attributes = new List <string>();
                            }

                            attributes.Add(attributeSubstring);
                        }
                    }
                }
                else if (line[0] == ';')
                {
                    continue;
                }
            }

            foreach (var definition in definitionFile.definitions)
            {
                if (string.IsNullOrEmpty(definition.requiredCondition))
                {
                    definition.requiredCondition = globalCondition;
                }
            }
        }