I’m running Unity 2022.2.14f and I have the following scenario.
All my models (modeled via Blender and exported to FBX) have one material named “ColorPalette”.
In Unity, the name of the material is “ColorPalette_Summer”.
Using a custom AssetPostprocessor I try to achieve this algorithm without getting the warning “Importer (FBX) generated inconsistent result for asset …”:
Using the method OnAssignMaterialModel I do:
Check, if there’s a material called “ColorPalette”. If not, return null, else:
Check, if the ModelImporter already has an external map set (which you usually do manually in the import inspector for the model). If yes: return null, else:
We now know that there’s a material called “ColorPalette” and it was not remapped yet, so we assign our own material.
This is how it looks in code:
public class DefaultColorPalette : AssetPostprocessor
{
private const string ColorPaletteSummerGuid = "178b74dc53be54709b84d85209d03744";
private Material? OnAssignMaterialModel(Material material, Renderer renderer)
{
if (material.name != "ColorPalette")
{
return null;
}
var importer = (ModelImporter)assetImporter;
var existingRemaps = importer.GetExternalObjectMap();
var hasColorPaletteRemap = existingRemaps.Any(kvp => kvp.Key.name == "ColorPalette");
if (hasColorPaletteRemap)
{
return null;
}
importer.AddRemap(new(typeof(Material), "ColorPalette"), FindColorPaletteSummer());
return null;
}
private Material? FindColorPaletteSummer()
{
var path = AssetDatabase.GUIDToAssetPath(ColorPaletteSummerGuid);
return AssetDatabase.LoadAssetAtPath<Material>(path);
}
}
Now, I want to support reassigning the material manually in the Inspector, because for certain models I don’t want to use the ColorPalette_Summer material but a different one with a different shader.
A couple of things that could be improved in your script: importer.AddRemap(new(typeof(Material), "ColorPalette"), FindColorPaletteSummer());
You should probably not add it to the settings during the import. Your postprocessor is deterministic, which means that for the same settings, it’ll always produce the same result. If you’re changing the settings during the process, you’re breaking this determinism.
In that case, I think your method should just return the value of FindColorPaletteSummer because this is what you’re using when no specific remap is used.
Inside the FindColorPaletteSummer method, you should declare dependencies to this other Material you are using. If it gets moved in your project or is not accessible yet (maybe because it was not imported at the moment your fbx file is) then you would return null and use the default one instead, which is not the result you want here.
private Material? FindColorPaletteSummer()
{
GUID.TryParse(ColorPaletteSummerGuid, out var guid);
context.DependsOnSourceAsset(guid);
var path = AssetDatabase.GUIDToAssetPath(ColorPaletteSummerGuid);
return AssetDatabase.LoadAssetAtPath<Material>(path);
}
Once you’ve changed your code, don’t forget to also override the GetVersion method in your AssetPostProcessor and set the version to something greater than 1.
This will tell the AssetDatabase that all your FBX files are now obsolete and should be considered a new version because the import mechanism has changed.
The bad side effect is that all your FBX files will re-import, the bright side is that they won’t be compared to any previous import and so you shouldn’t have any inconsistent result message anymore.
Hi ManuelRauber, I believe the issue with this code may actually be with these lines:
if (hasColorPaletteRemap)
{
return null;
}
The reason being; you are running that code inside OnAssignMaterialModel(), which implies that you want to either override the “default generated material” with something you return, or let it use the default (returning null). This means that when your code does find an existing remap, you ignore it and instead let it auto-generate again. As a result, you should end up in a state where the settings (remaps) are the same, but the materials actually being assigned to renderers are the “default generated” ones, rather than the remapped material target.
So instead, you may want to try this code:
if (hasColorPaletteRemap)
{
return existingRemaps.First(kvp => kvp.Key.name == "ColorPalette").Value as Material;
}
The other issue that could be coming up here is if your AssetPostprocessor doesn’t have a version which you are incrementing every time you change your code - which means the processing may yield different results without actually notifying Unity that you expected that (by increasing the version). You can specify a version number by overriding the GetVersion() function.