I’ve tried several methods that made sense to me, but I can’t seem to find a way to use an editor script to assign a texture asset to a material asset.
In the editor script, I have a reference to the material (via renderer.sharedMaterial), and I’m actually writing the texture to disk into the asset folder (from a PNG encoded Texture2D), so I have its path.
I tried assigning the return values of AssetDatabase.LoadAssetAtPath(), as well as EditorUtility.FindAsset(). I also was sure to Refresh() the asset database and even used Thread.Sleep() for several seconds to make sure the new texture had time to import before attempting to assign it.
Coincidentally, I recently did a similar thing, except that in my case I was actually creating a brand new material.
The only way that storing worked for me, was when I would assign the texture to the material before I would save the asset using AssetDatabase.CreateAsset(…).
I would imagine that in your case, you could do something like:
Material src = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material));
src.mainTexture = newTexture;
AssetDatabase.CreateAsset(materialPath, typeof(Material));
(with the usual ‘untested’ disclaimer ;P). This would overwrite the old material with the new value.
Actually, the more I think about this, I’m not sure how this would work in my situation… I’m writing the texture out to disk using .NET calls (writing out the bytes returned from EncodeToPNG()), so at that point, it seems to me there’d be no “connection” between the Texture2D I’m dealing with and the material I assign it to. So I guess what I need to know is how did you get your handle to the texture asset before you assigned it to the material?
Okay, sorry to spam this thread, but never mind! I just figured out my problem: LoadAssetAtPath works after all. Since I was using .NET to write out the file, I had stored the full path to the texture file, which is what .NET methods require, obviously. But LoadAssetAtPath() requires the path to the asset to be relative to the project folder. In other words, the full path wouldn’t work and that’s why it was returning null. So lesson here is: when using AssetDatabase or EditorUtility methods, always use the relative path! (I know, it says that right in the docs…but I was going on very little sleep at the time. :))
Thanks for helping me keep going here! Your suggestion set me to thinking.
My object variable “relatedMaterial” was initialized with a Texture in memory. Then, when I was saving the Texture file I wasn’t reloading the object variable.
So when I was assigning the texture to the material, the reference was on the texture in Memory and not the saved one.
Noob error. I’m now reloading the texture in the variable right after saving it.