在unity3d中更改材料资产

kon*_*rad 7 c# unity-game-engine

我使用编辑器脚本覆盖了一些材料资产,材料很好地覆盖了.我可以看到新材料属性被应用,当我点击单个材料时,我可以看到应用了新的纹理等.但是当我点击播放时,我的素材重置为预编辑状态,当我点击CTR + S时会发生同样的事情.我的材料都重新回到原来的样子.

如何将更改保存到数据库并在我点击播放时保持不变?

using UnityEngine;
using UnityEditor;
using Newtonsoft.Json;
using Unify.Utilities;
using System.Collections.Generic;
using System;
using System.IO;

public class ProcessMaterials : MonoBehaviour
{
    [MenuItem("Unify/ProcessMaterials")]
    static void UnifyProcessMaterials()
    {
    ImportTextures();
    ApplyMaterials();
    }

private static void ImportTextures()
{
    // check if folder exists and create one if not
    if (!AssetDatabase.IsValidFolder("Assets/Resources"))
    {
        AssetDatabase.CreateFolder("Assets", "Resources");
    }

    // load settings file
    TextAsset ta = Resources.Load("UnifySettings") as TextAsset;
    string json = ta.text;
    List<List<UnifyObject>> unifyObj = JsonConvert.DeserializeObject<List<List<UnifyObject>>>(json);
    List<UnifyObject> allMats = unifyObj[3];

    // copy textures over to unity folders
    HashSet<string> uniqueTextures = new HashSet<string>();
    foreach (UnifyObject obj in allMats)
    {
        if (obj.DiffuseTexture != null && uniqueTextures.Add(obj.DiffuseTexture))
        {
            CopyImageAsset(obj.DiffuseTexture);
        }
        if (obj.BumpTexture != null && uniqueTextures.Add(obj.BumpTexture))
        {
            CopyImageAsset(obj.BumpTexture);
        }
        if (obj.TransparencyTexture != null && uniqueTextures.Add(obj.TransparencyTexture))
        {
            CopyImageAsset(obj.TransparencyTexture);
        }
        if (obj.EnvironmentTexture != null && uniqueTextures.Add(obj.EnvironmentTexture))
        {
            CopyImageAsset(obj.EnvironmentTexture);
        }
    }
}

private static void CopyImageAsset(string sourceFilePath)
{
    string fileName = "Resources\\" + Path.GetFileName(sourceFilePath);
    string destFile = Path.Combine(Application.dataPath, fileName);

    try
    {
        File.Copy(sourceFilePath, destFile, true);
    }
    catch (Exception) { }
}

private static void ApplyMaterials()
{
    TextAsset ta = Resources.Load("UnifySettings") as TextAsset;
    string json = ta.text;
    List<List<UnifyObject>> unifyObj = JsonConvert.DeserializeObject<List<List<UnifyObject>>>(json);

    GameObject cube;
    cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    Renderer cubeRenderer = cube.GetComponent<Renderer>();

    List<UnifyObject> allMaterials = unifyObj[3];
    foreach (UnifyObject obj in allMaterials)
    {
        // skip layers with no materials assigned/default
        if (obj.Guid != Guid.Empty.ToString())
        {
            // obj replaces all dashes in names with underscores hence material assets will have different names than in Rhino
            // if layers had dashes in their names
            string objUniqueName = obj.UniqueName.Replace("-", "_");
            Material m = (Material)AssetDatabase.LoadAssetAtPath("Assets/Resources/Model/Materials/" + objUniqueName + "Mat.mat", typeof(UnityEngine.Object));
            if (m != null)
            {
                OverrideMaterial(m, obj, cubeRenderer);
                AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(m));
            }
        }
    }
    DestroyImmediate(cube);
}

private static Material OverrideMaterial(Material m, UnifyObject obj, Renderer renderer)
{
    renderer.material = m;
    // set main color
    // set transparency
    if (obj.Transparency != "0")
    {
        Color newColor = Utilities.ConvertToUnityColor(obj.Diffuse, obj.Transparency);
        renderer.sharedMaterial.SetFloat("_Mode", 3);
        renderer.sharedMaterial.SetColor("_Color", newColor);
    }
    else
    {
        Color newColor = Utilities.ConvertToUnityColor(obj.Diffuse);
        renderer.sharedMaterial.SetColor("_Color", newColor);
    }

    // set main texture
    if (obj.DiffuseTexture != null)
    {
        renderer.sharedMaterial.mainTexture = Utilities.Texture2dFromPath(obj.DiffuseTexture);
    }

    // set bump map
    if (obj.BumpTexture != null)
    {
        Texture2D bumpTexture = Utilities.Texture2dFromPath(obj.BumpTexture);
        float strength = Convert.ToSingle("1.0");
        Texture2D normalBump = Utilities.CreateNormalMap(bumpTexture, strength);
        renderer.sharedMaterial.SetTexture("_BumpMap", normalBump);
        // need to get that value from Rhino somehow
        renderer.sharedMaterial.SetFloat("_BumpScale", 0.3f);
    }

    // set metallic
    renderer.sharedMaterial.SetFloat("_Metallic", Utilities.ConvertRange(0, 255, 0, 1, Convert.ToSingle(obj.Metallic)));

    // set emission color
    Color emissionColor = Utilities.ConvertToUnityColor(obj.EmissionColor);
    renderer.sharedMaterial.SetColor("_EmissionColor", emissionColor);
    return renderer.sharedMaterial;
}
}
Run Code Online (Sandbox Code Playgroud)

Pro*_*mer 0

覆盖材质后,调用以下函数

UnityEditor.EditorUtility.SetDirty(AssetName);
UnityEditor.AssetDatabase.SaveAssets();
UnityEditor.AssetDatabase.Refresh();
Run Code Online (Sandbox Code Playgroud)

如果上述方法不起作用,另一种可能有效的方法是创建一个简单的立方体,将加载的材质分配给立方体,然后修改Renderer.sharedMaterial立方体的 ,而不是Renderer.material。通常,修改sharedMaterial会永久更改原始材料,但我不知道是否适用于从 加载的材料AssetDatabase。这应该在您的函数内部完成OverrideMaterial。该GameObject.CreatePrimitive(PrimitiveType.Cube);函数应该只被调用一次。

GameObject cube;
cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

Renderer cubeRenderer = cube.GetComponent<Renderer>();

//Change the cube material to the material that is loaded from the disk
cubeRenderer.material = m;

//Now modify the shared array of the cube
cubeRenderer.sharedMaterial.SetFloat("_Mode", 3);
cubeRenderer.sharedMaterial.SetColor("_Color", newColor);
//cubeRenderer.sharedMaterial.
//cubeRenderer.sharedMaterial.
Run Code Online (Sandbox Code Playgroud)