LoadAssetAtPath doesn't seem to work for ScriptableObject asset in AssetPostProcessor
Hello there !
I have been trying to implement a very simple AssetPostProcessor to force the collider type on Tile assets during import, depending on the path of the asset. We are starting to have hundreds of tiles and something like this would really help.
When I reimport my tile asset, the asset path is logged successfully but LoadAssetAtPath always returns null. I've been looking for solutions and alternatives for a while now but I really can't figure out what's is wrong in this code. Any tips ?
Edit : I'm on Unity 2019.4.10f1, this script is in an Editor assembly. I also tried LoadMainAssetAtPath and tried to log values in the assetImporter (name, userData are all empty...)
Thanks a lot
class TileAssetImporter : AssetPostprocessor
{
void OnPreprocessAsset()
{
if (assetPath.Contains("Collider_"))
{
Tile tile = AssetDatabase.LoadAssetAtPath<Tile>(assetPath);
Debug.Log(assetPath);
if (null != tile)
{
if (assetPath.Contains("None"))
{
tile.colliderType = Tile.ColliderType.None;
}
else if (assetPath.Contains("Sprite"))
{
tile.colliderType = Tile.ColliderType.Sprite;
}
else
{
tile.colliderType = Tile.ColliderType.Grid;
}
EditorUtility.SetDirty(tile);
AssetDatabase.SaveAssets();
}
else
{
Debug.LogError("Could not load Tile asset");
}
}
}
}
Answer by Karim-Largelabs · Sep 20, 2020 at 03:59 PM
Update for those who my be facing a similar issue : I wasn't able to make it work using OnPreProcessAsset. I suspect a regression because it used to work in Unity 2018.3 (I'm now using 2019.4.10f1)
However, I can load my ScriptableObject (here, a Tile) during post process and do what I want that way. I don't consider this to be the best solution, it looks quite unelegant and I still don't understand what was going on with the previous code, but hey, it works now. The dirty flags are here so that I won't enter an infinite loop, since AssetDatabase.SaveAssets() will end up reimporting and this code will therefore be called again. Source code :
class TileAssetImporter : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
bool hasDirtyAssets = false;
foreach (string path in importedAssets)
{
if (path.Contains("Collider_"))
{
Tile tile = AssetDatabase.LoadAssetAtPath<Tile>(path);
bool isDirty = false;
if (null != tile)
{
if (path.Contains("None"))
{
if(tile.colliderType != Tile.ColliderType.None)
{
tile.colliderType = Tile.ColliderType.None;
isDirty = true;
}
}
else if (path.Contains("Sprite"))
{
if (tile.colliderType != Tile.ColliderType.Sprite)
{
tile.colliderType = Tile.ColliderType.Sprite;
isDirty = true;
}
}
else
{
if (tile.colliderType != Tile.ColliderType.Grid)
{
tile.colliderType = Tile.ColliderType.Grid;
isDirty = true;
}
}
if(true == isDirty)
{
hasDirtyAssets = true;
Debug.Log("TILE IMPORTER - changed tile collider to " + tile.colliderType.ToString() + " for " + path);
EditorUtility.SetDirty(tile);
}
}
}
}
if(true == hasDirtyAssets)
{
AssetDatabase.SaveAssets();
}
}
}
}
Your answer
Follow this Question
Related Questions
Get asset file from scriptableobject (Nested Scriptableobjects) 2 Answers
How can I get a sub asset? 1 Answer
ScriptableObject Instances Referencing One Set of Prefabs - Changing One SO Changes The same prefab 1 Answer
AssetDatabase.LoadAssetAtPath Not finding assets 0 Answers
How to "Lock" scriptable objects from losing their [SerializeField] values 0 Answers