- Home /
Could not load copied asset via AssetDatabase.LoadAssetAtPath
I am using AssetDatabase.CopyAsset
method to create a copy of a prefab as part of an AssetPostProcessor
implementation:
AssetDatabase.CopyAsset(sourcePrefabLocation, targetPrefabLocation);
AssetDatabase.ImportAsset(
targetPrefabLocation,
ImportAssetOptions.DontDownloadFromCacheServer|ImportAssetOptions.ForceUpdate);
AssetDatabase.SaveAssets();
This works fine, the asset is copied. However, later in the same post-processor, I want to load the copied asset, so I am using:
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(targetPrefabLocation);
Unfortunately, the prefab
variable is always null
. I used the following code to list all prefab assets, just to find out that the copied prefab is not enlisted. That would actually explain why the LoadAssetAtPath
fails to load the asset.
AssetDatabase.GetAllAssetPaths().Where(x => x.Contains(".prefab")).Aggregate(new StringBuilder().AppendLine(), (sb, s) => sb.AppendLine(s))
So, what should I do to make the AssetDatabase
include the copied asset?
Answer by Unity-Wenchao · Oct 30, 2017 at 08:30 AM
I found a solution to this problem: string oldpath = {XXXX}; string newpath = {XXX}; AssetDatabase.CopyAsset(oldpath, newpath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); AssetDatabase.ImportAsset(newpath); AssetDatabase.LoadXXX // It can get the right asset now
Thank you for providing an answer. I have used a similar approach, so I assume yours works as well. Anyway, I have moved on to using the experimental asset importers that came with Unity 2017. They too have their quirks, but are closer to what I initially wanted to achieve.
Answer by ArturoSR · Aug 31, 2017 at 06:22 PM
@ivaylo5ev Hello there, probably you need to "Refresh" the project so the new asset shows up, there is a method to do that, cheers.
Hello @$$anonymous$$oSR. I am doing this inside a script, which is an AssetPostProcessor. I create the asset in the post-processor and I want to load it within the same execution flow. I tried calling AssetDatabase.Refresh
before my AssetDatabase.LoadAssetAtPath
but to no avail. So the flow is:
AssetDatabase.CopyAsset
AssetDatabase.ImportAsset
AssetDatabase.SaveAssets
AssetDatabase.Refresh
AssetDatabase.LoadAssetAtPath
Am I missing something?
Answer by x4637x · Oct 30, 2017 at 08:54 AM
Had the same problem once. Then I changed to used GameObject prefab = AssetDatabase.LoadAssetAtPath(targetPrefabLocation,typeof(GameObject)) as GameObject;
and it works for me.
This certainly doesn't solve anything. The generic version he's using just calls this method:
public static T LoadAssetAtPath<T>(string assetPath) where T : Object
{
return (T)((object)AssetDatabase.LoadAssetAtPath(assetPath, typeof(T)));
}
If any of the two methods is more reliable it's the generic one as it doesn't use an as cast which could silently fail.
I just quickly check my old code again, noticed you are right. Another difference though is I am using where T : ScriptableObject
ins$$anonymous$$d of Object
. Will it be possible that this is a deserialized problem? Also, need to mention I am not calling the AssetDatabase.Refresh()
anywhere in my code.
Answer by SpookyCat · Dec 13, 2017 at 05:47 PM
Did you find a solution for this, I have the same problem, I copy texture files into the project but it seems Unity waits till after the OnPostProcessAllAssets completes before it actually does import the textures into the asset database. Even using Refresh etc. makes no difference, I can't see a way to force Unity to import the textures now and update the database so I can make changes to them.
Hello @SpookyCat. I did not find anything appealing - I got this working by a similar to @Unity-Wenchao' s solution for a short time. Anyway, I have moved on to using the experimental asset importers that came with Unity 2017. They too have their quirks, but are way closer to what I initially wanted to achieve.