Hey guys, I’m trying to get my asset processor to automate some tasks for artists, but I can’t get it to work:
If texture is dropped in a folder:
Create a new folder named after the texture.
Create a material, assign the texture to that material.
Move the texture to the new folder.
Save the material to the new folder.
So everything runs fine, but when I check the material, no map is assigned.
public void OnPostprocessTexture(Texture2D texture)
{
string dirName = Path.GetDirectoryName(assetPath);
string absFilePath = Path.Combine(Directory.GetCurrentDirectory(), assetPath);
string fileNameWithoutExt = Path.GetFileNameWithoutExtension(assetPath);
string fileName = Path.GetFileName(assetPath);
if (dirName == ("Assets\\Data\\Shared"))
{
string newDirectory = Path.GetDirectoryName(absFilePath) + "\\" + fileNameWithoutExt;
Directory.CreateDirectory(newDirectory);
string newFilePath = dirName + "\\" + fileNameWithoutExt + "\\" + fileName;
Material newMaterial = new Material(Shader.Find("UbiHFX/Environment"));
newMaterial.SetTexture("_MainTex", texture);
string newMatPath = dirName + "\\" + fileNameWithoutExt + "\\" + fileNameWithoutExt + ".mat";
AssetDatabase.MoveAsset(assetPath, newFilePath);
AssetDatabase.CreateAsset(newMaterial, newMatPath);
}
AssetDatabase.Refresh();
}
Shader Properties:
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
}
Any thoughts on what I’m doing wrong? I have tried using “Albedo (RGB)” in place of _MainTex and that didn’t do anything either.
I think it is because you are passed a texture in memory, NOT the actual asset on disk, which is what you need to link into the material.
There was some random discussion about it here:
And I will agree, that really IS a garbage work flow!!
I have not done the actual “garbage workflow” that @Madgvox references, but perhaps it is a clue to where you need to go.
1 Like
Madgvox
December 10, 2020, 9:33pm
3
I’m not 100% sure how Unity handles asset reference in OnPostprocess*
, but one way you can check that the texture you’re working with is the actual texture is using AssetDatabase.GetAssetPath
on the texture. If it’s null, you’re not working with the asset on disk.
Another potential point of failure is moving the asset. If you don’t move the texture, does the reference persist?
1 Like
Good advice guys, yeah the texture was in memory and not the asset on disk. Figured out an alternative way to do it. Cheers
2 Likes
Madgvox
December 11, 2020, 12:41am
5
For posterity, mind giving a high-level overview of what worked for you? Want to prevent people from running into this situation !
1 Like
I am so sorry for the late response.
I was time constrained and chose to drop OnPostprocessTexture(), and rather use OnPostProcessAllAssets().
OnPostProcessAllAssets guarantees that the asset is on disk rather than still being in memory.
So basically (hastily assembled it from memory)
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
foreach (string str in importedAssets)
{
if (Path.GetExtension(str).ToLower() == ".tga")
{
DoTextureTask((Texture)AssetDatabase.LoadAssetAtPath(str, typeof(GameObject)), str);
}
}
}
public void DoTextureTask(Texture2D texture, string assetPath)
{
string dirName = Path.GetDirectoryName(assetPath);
string absFilePath = Path.Combine(Directory.GetCurrentDirectory(), assetPath);
string fileNameWithoutExt = Path.GetFileNameWithoutExtension(assetPath);
string fileName = Path.GetFileName(assetPath);
if (dirName == ("Assets\\Data\\Shared"))
{
string newDirectory = Path.GetDirectoryName(absFilePath) + "\\" + fileNameWithoutExt;
Directory.CreateDirectory(newDirectory);
string newFilePath = dirName + "\\" + fileNameWithoutExt + "\\" + fileName;
Material newMaterial = new Material(Shader.Find("UbiHFX/Environment"));
newMaterial.SetTexture("_MainTex", texture);
string newMatPath = dirName + "\\" + fileNameWithoutExt + "\\" + fileNameWithoutExt + ".mat";
AssetDatabase.MoveAsset(assetPath, newFilePath);
AssetDatabase.CreateAsset(newMaterial, newMatPath);
}
AssetDatabase.Refresh();
}
4 Likes
Thank you for posting the solution. I was running into the same issue and this was a great help!