2016-04-29 10 views
7

Sto sovrascrivendo alcune risorse materiale utilizzando uno script dell'editor e i materiali sovrascrivono correttamente. Riesco a vedere le nuove proprietà del materiale che vengono applicate e quando clicco su singoli materiali posso vedere nuove texture applicate ecc. Tuttavia, quando premo play, i miei materiali vengono ripristinati allo stato di pre-modifica, La stessa cosa accade quando premo CTR + S. I miei materiali tornarono tutti a quello che erano.apportare modifiche alle risorse materiali in unity3d

Come posso salvare le modifiche nel database e persistere quando premo play?

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; 
} 
} 
+0

Hai provato la mia soluzione? Ha funzionato? – Programmer

+0

Lo controllerò domani mattina. era lontano da un computer questo fine settimana. Grazie per la pubblicazione e ti farò sapere se funziona. FYI. Ho provato a impostare la risorsa materiale sporca e quindi salvarla durante la chiamata di aggiornamento più tardi, ma ciò non ha aiutato. Proverò il trucco con il cubo e riferirò. – konrad

+0

sei sicuro di avere più di 10kb di spazio libero sulla tua partizione Unity? Sono sicuro che lo fai, ma devo chiedere ... –

risposta

1

Dopo di sovrascrivere i materiali, richiamare le seguenti funzioni

UnityEditor.EditorUtility.SetDirty(AssetName); 
UnityEditor.AssetDatabase.SaveAssets(); 
UnityEditor.AssetDatabase.Refresh(); 

Se il metodo precedente non ha funzionato, un altro metodo che potrebbe funzionare è quello di creare un semplice cubo, assegnare il materiale caricato al cubo quindi modificare il Renderer.sharedMaterial del cubo anziché Renderer.material. Di solito, la modifica di sharedMaterial modifica il materiale originale in modo permanente ma non so se si applica ai materiali caricati da AssetDatabase. Questo dovrebbe essere fatto all'interno della tua funzione OverrideMaterial. La funzione GameObject.CreatePrimitive(PrimitiveType.Cube); deve essere chiamata una sola volta.

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. 
+0

così ho provato entrambi questi suggerimenti e sto ancora ottenendo gli stessi risultati. Aggiornerò la mia domanda con la soluzione che hai suggerito, forse non la sto implementando correttamente. – konrad