If I use AssetDatabase.LoadAssetAtPath inside packages it will return null. Is there a specific way on handling asset loading inside packages?
Somewhere around here in a closed topic it was mentioned that the path should be without the version number. Ok fair enough but why AssetDatabase.GetAssetPath still returns with the version number. Or is there an additional helper method to strip it?
I can do my own I would just like to know if this kind of confusing behaviour is intended.
So even with the stripped version number it doesn’t load at all.
What is the correct way of loading assets inside packages? Someone mentioned that you should copy the asset from the package path to the Unity project assets folder and load it from where. Really? That seems like a really dumb idea that just gets messy.
So, in case you have the com.unity.2d.animation package installed, loading a file from there would be done via:
var yellowDot = AssetDatabase.LoadAssetAtPath("Packages/com.unity.2d.animation/Editor/Assets/SkinningModule/dotYellow.png", typeof(Texture2D));
And now yellowDot should be a Texture2D that you can use
In case you don’t know the path to the file, but know what the name should be you can use this code snippet to output what the path is:
var allAssetPaths = AssetDatabase.GetAllAssetPaths();
var fileName = "dotYellow.png";
for(int i = 0; i < allAssetPaths.Length; ++i)
{
if (allAssetPaths[i].EndsWith(fileName))
Debug.Log(allAssetPaths[i]);
}
@van800 if you only have an absolute path, we so far had to
find all package.json in project (all the PackMan APIs, even the internal database ones, are way slower)
get their Path.GetFullPath
this gives you a mapping of virtual assetDB path to full path (e.g. “Packages/com.my.package/” => “C:/packages/MyPackage/”)
use that to map full paths back to relative ones
Slow but works…
If you have a virtual path to begin with you can just use
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(assetPath)
var virtualPath = "Packages/" + packageInfo.name;
var absolutePath = packageInfo.resolvedPath;
You know the package info (name + local file path) already when using “Show in Unity”?
So why not just construct “Packages//relativePath/to/asset/to/show”?
What am I missing ^^?
What I’ve done in another project is (if the file is not inn assets):
I use a cached list of packages infos from packman to find the package that starts with the absolute file path and then remove the package path from my absolute file path and add “Packages//relative/path”, like this:
if (PackageFilter.TryGetPackage(fp, out var package))
{
var rel = "Packages/" + package.name + "/" + fp.Substring(package.resolvedPath.Length);
result = rel;
return File.Exists(result);
}
I have made a generated solution with 100 local packages, each having 500 C# scripts and 500 . So 100000 assets total. For context in Unity 2021.2.0b10 first “Initial Asset Database Refresh” took 45 minutes. I don’t have enough patience to wait for processing of even bigger project.
I have the following test to measure iterating over all assets:
[Test]
public void Test()
{
var sw = new Stopwatch();
sw.Start();
foreach (var asset in AssetDatabase.GetAllAssetPaths())
{
var t = new FileInfo(Path.GetFullPath(asset)).FullName;
}
UnityEngine.Debug.Log(sw.Elapsed.Milliseconds);
sw.Reset();
}
The test logs 707 ms for me.
I have also checked “Show in Unity” feature manually on the same solution - it feels fast enough.