2016-04-29 11 views
7

Nadpisuję niektóre zasoby materiałowe za pomocą skryptu edytora, a materiały ładują się z łatwością. Widzę, jak nowe właściwości materiału są stosowane i kiedy klikam na pojedyncze materiały, widzę nowe tekstury zastosowane itp. Jednak po naciśnięciu play, moje materiały zostają zresetowane do stanu pre-edit, To samo dzieje się, gdy uderzę CTR + S. Moje materiały zostały zresetowane z powrotem do tego, czym były.wprowadzanie zmian w zasobach materialnych w unity3d

W jaki sposób mogę spowodować, że zmiany zostaną zapisane w bazie danych i utrzymają się po uruchomieniu gry?

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

Czy wypróbowałeś moje rozwiązanie? Zadziałało? – Programmer

+0

Sprawdzę to jutro rano. w ten weekend był z dala od komputera. Dzięki za publikację i dam ci znać, czy to działa. FYI. Próbowałem ustawić brudne zasoby materialne, a następnie zapisałem je podczas odświeżania później, ale to nie pomogło. Spróbuję lewy z kostką i zgłoś się. – konrad

+0

jesteś pewien, że masz więcej niż 10kb wolnego miejsca na partycji Unity? Jestem pewien, że tak, ale musicie zapytać ... –

Odpowiedz

1

Po nadpisać materiały, należy zadzwonić pod następujące funkcje

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

Jeśli metoda powyżej nie działa, innej metody, które mogłyby pracy jest tworzyć prosty sześcian, przypisać materiał załadowany do kostki, następnie zmodyfikuj Renderer.sharedMaterial kostki zamiast Renderer.material. Zwykle modyfikowanie sharedMaterial zmienia na stałe oryginalny materiał, ale nie wiem, czy dotyczy ładowanych materiałów z AssetDatabase. Powinno to zostać wykonane wewnątrz funkcji OverrideMaterial. Funkcja GameObject.CreatePrimitive(PrimitiveType.Cube); powinna być wywoływana tylko raz.

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

więc spróbowałem obu tych sugestii i nadal otrzymuję te same wyniki. Zaktualizuję moje pytanie proponowanym rozwiązaniem, być może nie wprowadzam go poprawnie. – konrad