Beispiel #1
0
    static void _process_model(string character_name, string folder, string filename)
    {
        //var abs_folder = Application.dataPath + "/" + folder;
        folder = "Assets/" + folder;

        var asset = AssetDatabase.LoadAssetAtPath <GameObject>(folder + "/" + filename);

        // Create a game object in the hierarchy.
        var holder = GameObject.Find("Mixamo");

        if (holder == null)
        {
            holder = new GameObject("Mixamo");
        }
        //var model = GameObject.Instantiate(asset, holder.transform);
        var model = (GameObject)PrefabUtility.InstantiatePrefab(asset, UnityEngine.SceneManagement.SceneManager.GetActiveScene());

        model.transform.parent = holder.transform;
        model.name             = character_name;

        // Collect all the materials.
        var  meshes       = asset.GetComponentsInChildren <SkinnedMeshRenderer>();
        bool has_eyes     = false;
        var  material_set = new HashSet <Material>();

        foreach (var mesh in meshes)
        {
            var obj_name = mesh.name;
            // Sometimes Adobe Fuse model has an "Eyes" object *or* and "Eyelashes" object
            // and the one it doesn't have is called "default".
            if (obj_name == "Eyes")
            {
                has_eyes = true;
            }
            foreach (var mat in mesh.sharedMaterials)
            {
                material_set.Add(mat);
            }
        }
        // Create materials list
        var materials = new List <Material>();

        foreach (var m in material_set)
        {
            materials.Add(m);
        }

        // Create Eyes and Eyelashes materials from the Body material.
        var body_mat   = materials.Find(m => m.name.Contains("_Body"));
        var mat_prefix = body_mat.name.Split('_')[0];

        if (body_mat != null)
        {
            var bodyPath      = folder + "/Materials/" + body_mat.name + ".mat";
            var eyePath       = folder + "/Materials/" + mat_prefix + "_Eyes_Diffuse.mat";
            var eyelashesPath = folder + "/Materials/" + mat_prefix + "_Eyelashes_Diffuse.mat";
            AssetDatabase.CopyAsset(bodyPath, eyePath);
            AssetDatabase.CopyAsset(bodyPath, eyelashesPath);
            materials.Add(AssetDatabase.LoadAssetAtPath <Material>(eyePath));
            materials.Add(AssetDatabase.LoadAssetAtPath <Material>(eyelashesPath));
        }

        // Rename the "default" object to the correct value.
        {
            var default_object = model.transform.Find("default");
            if (default_object != null)
            {
                if (has_eyes)
                {
                    default_object.name = "Eyelashes";
                }
                else
                {
                    default_object.name = "Eyes";
                }
            }
        }

        // Set materials for Eyes and Eyelashes objects.
        model.transform.Find("Eyes").GetComponent <SkinnedMeshRenderer>().material      = materials.Find(m => m.name.Contains("_Eyes"));
        model.transform.Find("Eyelashes").GetComponent <SkinnedMeshRenderer>().material = materials.Find(m => m.name.Contains("_Eyelashes"));

        // Configure each material.
        foreach (var m in materials)
        {
            foreach (var part in _parts)
            {
                if (!m.name.Contains(part.Name))
                {
                    continue;
                }

                // Set rendering mode.
                m.SetFloat("_Mode", (float)part.BlendMode);

                // Set textures. Use Body for Eyes and Eyelashes.
                var tp = part.Name;
                if (part.Name == "_Eyes" || part.Name == "_Eyelashes")
                {
                    tp = "_Body";
                }
                m.SetTexture("_MainTex", AssetDatabase.LoadAssetAtPath <Texture>(folder + "/Textures/" + mat_prefix + tp + "_BaseColor.png"));
                m.SetTexture("_MetallicGlossMap", AssetDatabase.LoadAssetAtPath <Texture>(folder + "/Textures/" + mat_prefix + tp + "_MetallicAndSmoothness.png"));
                m.SetTexture("_BumpMap", AssetDatabase.LoadAssetAtPath <Texture>(folder + "/Textures/" + mat_prefix + tp + "_Normal.png"));
                m.SetTexture("_OcclusionMap", AssetDatabase.LoadAssetAtPath <Texture>(folder + "/Textures/" + mat_prefix + tp + "_AmbientOcclusion.png"));

                // Configure the part parameters.
                m.SetFloat("_GlossMapScale", part.GlossScale);
                m.SetFloat("_BumpScale", part.BumpScale);

                if (part.BlendMode == BlendMode.Cutout)
                {
                    m.SetFloat("_Cutoff", part.CutoffAlpha);
                }

                // Find which parameters are which...
                //m.SetFloat("_Glossiness", 0.1f);
                //m.SetFloat("_GlossMapScale", 0.2f);
                //m.SetFloat("_SmoothnessTextureChannel", 0.3f);
                //m.SetFloat("_Metallic", 0.4f);
                //m.SetFloat("_SpecularHighlights", 0.5f);
                //m.SetFloat("_GlossyReflections", 0.6f);
            }
        }

        // Create prefab to hold changes.
        var old_model = model;
        var prefab    = PrefabUtility.CreatePrefab(folder + "/" + character_name + ".prefab", old_model);

        // Recreate the instance from the new prefab.
        model = (GameObject)PrefabUtility.InstantiatePrefab(prefab, UnityEngine.SceneManagement.SceneManager.GetActiveScene());
        model.transform.parent = holder.transform;

        // Remove the original prefab.
        GameObject.DestroyImmediate(old_model);

        // Must do this so that the changes are immediately visible in the editor.
        foreach (var m in materials)
        {
            MaterialUpdater.MaterialChanged(m, MaterialUpdater.WorkflowMode.Metallic);
        }

        // Select the new game object.
        _expand_hierarchy_object(holder);
        Selection.activeGameObject = model;
    }
Beispiel #2
0
    static void _process_model(string character_name, string folder, string filename)
    {
        //var abs_folder = Application.dataPath + "/" + folder;
        folder = "Assets/" + folder;

        var asset = AssetDatabase.LoadAssetAtPath <GameObject>(folder + "/" + filename);

        // Create a game object in the hierarchy.
        var holder = GameObject.Find("Mixamo");

        if (holder == null)
        {
            holder = new GameObject("Mixamo");
        }
        //var model = GameObject.Instantiate(asset, holder.transform);
        var model = (GameObject)PrefabUtility.InstantiatePrefab(asset, UnityEngine.SceneManagement.SceneManager.GetActiveScene());

        model.transform.parent = holder.transform;
        model.name             = character_name;

        // Collect all the materials.
        var meshes = asset.GetComponentsInChildren <SkinnedMeshRenderer>();

        bool has_eyes = meshes.Any(m => m.name == "Eyes");

        // Rename the "default" object to the correct value.
        var default_object = model.transform.Find("default");

        if (default_object != null)
        {
            if (has_eyes)
            {
                default_object.name = "Eyelashes";
            }
            else
            {
                default_object.name = "Eyes";
            }
        }

        var default_mesh = meshes.FirstOrDefault(m => m.name == "default")?.transform;

        if (default_mesh != null)
        {
            default_mesh.name = has_eyes ? "Eyelashes" : "Eyes";
            Debug.Log("Here I am!" + has_eyes + " " + default_mesh.name);
        }

        var materials = new Dictionary <string, Material>();

        bool body_mat_processed = false;

        AssetDatabase.CreateFolder(folder, "Materials");

        foreach (var mesh in meshes)
        {
            // Sometimes Adobe Fuse model has an "Eyes" object *or* and "Eyelashes" object
            // and the one it doesn't have is called "default".

            //extract embedded materials and adjust mesh
            var shared_mats = new Material[mesh.sharedMaterials.Length];

            for (var i = 0; i < mesh.sharedMaterials.Length; i++)
            {
                var mat = mesh.sharedMaterials[i];

                if (mat.name == "Bodymat")
                {
                    if (!body_mat_processed)
                    {
                        _extract_material(folder, mat, materials, "Eyesmat");
                        _extract_material(folder, mat, materials, "Eyelashesmat");
                        body_mat_processed = true;
                    }

                    if (mesh.name == "Eyes" || mesh.name == "Eyelashes")
                    {
                        shared_mats[i] = materials[mesh.name + "mat"];
                        continue;
                    }
                }

                _extract_material(folder, mat, materials);
                shared_mats[i] = materials[mat.name];
            }

            // directly applying shared_mats to the current mesh seems to be delayed and misses the last item
            // just update the model directly
            model.transform.Find(mesh.name).GetComponent <SkinnedMeshRenderer>().sharedMaterials = shared_mats;
        }



        foreach (var part in _parts)
        {
            var material_name = part.Name + "mat";

            if (!materials.ContainsKey(material_name))
            {
                continue;
            }

            var m = materials[material_name];

            // Set rendering mode.
            m.SetFloat("_Mode", (float)part.BlendMode);

            // Set textures. Use Body for Eyes and Eyelashes.
            var tp = "_" + part.Name;
            if (part.Name == "Eyes" || part.Name == "Eyelashes")
            {
                tp = "_Body";
            }
            var texBase = AssetDatabase.LoadAssetAtPath <Texture2D>(folder + "/Textures/" + character_name + tp + "_BaseColor.png");
            m.SetTexture("_MainTex", texBase);
            m.SetTexture("_MetallicGlossMap", AssetDatabase.LoadAssetAtPath <Texture>(folder + "/Textures/" + character_name + tp + "_MetallicAndSmoothness.png"));
            m.SetTexture("_BumpMap", AssetDatabase.LoadAssetAtPath <Texture>(folder + "/Textures/" + character_name + tp + "_Normal.png"));
            m.SetTexture("_OcclusionMap", AssetDatabase.LoadAssetAtPath <Texture>(folder + "/Textures/" + character_name + tp + "_AmbientOcclusion.png"));

            // Override blend mode for non-alpha hair.
            // Override a transparent BlendMode if the texture is actually opaque-only.
            if (part.BlendMode == BlendMode.Fade || part.BlendMode == BlendMode.Transparent)
            {
                // Check texture type.
                switch (texBase.format)
                {
                // Ignore formats that have alpha.
                case TextureFormat.ARGB4444:
                case TextureFormat.RGBA32:
                case TextureFormat.ARGB32:
                case TextureFormat.RGBA4444:
                case TextureFormat.BGRA32:
                case TextureFormat.RGBAHalf:
                case TextureFormat.RGBAFloat:
                case TextureFormat.PVRTC_RGBA2:
                case TextureFormat.PVRTC_RGBA4:
                case TextureFormat.ETC2_RGBA8:
                case TextureFormat.ETC2_RGBA1:
                case TextureFormat.ASTC_RGBA_4x4:
                case TextureFormat.ASTC_RGBA_5x5:
                case TextureFormat.ASTC_RGBA_6x6:
                case TextureFormat.ASTC_RGBA_8x8:
                case TextureFormat.ASTC_RGBA_10x10:
                case TextureFormat.ASTC_RGBA_12x12:
                case TextureFormat.DXT5:     // NOTE: DXT5 has alpha, DXT1 is usually non-alpha
                    break;

                default:
                    // Fall back to opaque.
                    m.SetFloat("_Mode", (float)BlendMode.Opaque);
                    break;
                }
            }

            // Configure the part parameters.
            m.SetFloat("_GlossMapScale", part.GlossScale);
            m.SetFloat("_BumpScale", part.BumpScale);

            if (part.BlendMode == BlendMode.Cutout)
            {
                m.SetFloat("_Cutoff", part.CutoffAlpha);
            }

            // Find which parameters are which...
            //m.SetFloat("_Glossiness", 0.1f);
            //m.SetFloat("_GlossMapScale", 0.2f);
            //m.SetFloat("_SmoothnessTextureChannel", 0.3f);
            //m.SetFloat("_Metallic", 0.4f);
            //m.SetFloat("_SpecularHighlights", 0.5f);
            //m.SetFloat("_GlossyReflections", 0.6f);
        }

        // Create prefab to hold changes.
        var old_model = model;
        var prefab    = PrefabUtility.SaveAsPrefabAsset(old_model, folder + "/" + character_name + ".prefab");

        // Recreate the instance from the new prefab.
        model = (GameObject)PrefabUtility.InstantiatePrefab(prefab, UnityEngine.SceneManagement.SceneManager.GetActiveScene());
        model.transform.parent = holder.transform;

        // Remove the original prefab.
        GameObject.DestroyImmediate(old_model);

        // Must do this so that the changes are immediately visible in the editor.
        foreach (var m in materials.Values)
        {
            MaterialUpdater.MaterialChanged(m, MaterialUpdater.WorkflowMode.Metallic);
        }

        // Select the new game object.
        _expand_hierarchy_object(holder);
        Selection.activeGameObject = model;
    }