- Home /
Embedding objects inside a material
I have a shader that takes a gradient texture as an input.
I have a custom material editor that allows me to input gradients into a Unity gradient field.
The gradient is converted into a texture and set in the shader.
However once I click play, the texture disappears.
Also the gradient disappears when I change the selected object or click play.
I read a bit on AssetDatabase.AddObjectToAsset thinking that perhaps I could embed the texture and the object that holds the gradients.
Ideally I should have:
-In editor I can change the gradients which change the textures. The gradients are always saved so I can return and tweak it.
-In a build the textures should already exist. I don't want to create a texture at runtime
Does anyone have any ideas around this? I want to not create extra assets.
Answer by lassade · Jan 15, 2016 at 02:18 AM
You can use AssetDatabase.AddObjectToAsset as well as AssetDatabase.CreateAsset to save the textures.
After creating these assets make sure to assign the texture reference to the material field and then do a AssetDatabase.ImportAsset, Every time you do some modification to the objects do a EditorUtility.SetDirty([your asset]) to unity know that asset needs to be saved.
I have an editor script that does something similar with materials and custom textures. Later I will post it here.
Edit
using UnityEngine; using UnityEditor;
[CustomEditor(typeof(MyCustomScriptableObject))]
public class MyCustomEditor : Editor
{
MyCustomScriptableObject edit;
// Use this for initialization
void Awake()
{
edit = target as MyCustomScriptableObject;
}
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
DrawDefaultInspector();
// if any thing changes the texture will be rebuild
if (EditorGUI.EndChangeCheck())
{
Create();
EditorUtility.SetDirty (edit);
EditorUtility.SetDirty (edit.texture);
}
}
void Create()
{
var pixels = texture.GetPixels ();
var length = lights.Length;
// update texture
for (var x = 0; x < texture.width; x++) {
for (var y = 0; y < texture.height; y++) {
//pixels[y*texture.width + x] = ...;
}
}
texture.SetPixels (pixels);
texture.Apply();
}
[MenuItem("Assets/Create/Some Asset")]
public static void CreateAsset()
{
// create asset with the right at selected folder
// search for ScriptableObjectUtility in unity wiki for this script
var asset = ScriptableObjectUtility.CreateAsset<MyCustomScriptableObject>();
// creating the texture
var texture = new Texture2D(256, 128, TextureFormat.RGB24, false, false);
texture.name = "texture";
texture.wrapMode = TextureWrapMode.Clamp;
asset.texture = texture;
// save the texture
AssetDatabase.AddObjectToAsset(texture, asset);
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(asset));
}
}
Thanks for this. Really cleared everything up and now have exactly what I wanted. :)
Your answer
