Hi Jamie,
When will the directory watcher trigger an update? When the asset is saved?
I didn’t see any change until I reloaded the editor and looked at the asset again.
I am looking for a nice function to call that will cause the assetregistry to re-scan my uasset and re-update it’s cache preferably prior to saving.
Our use case for the assets is unusual:
We have an editor object which is created through the usual AssetTypeActions and through a factory.
In addition we create new objects with NewObject, setting them to RF_Public and putting them into the same package as the editor object.
The user can view the additional objects through a menu item exposed by the assettypeaction for the editor object.
The additional objects are UStaticMesh and UMaterialInstanceConstant. The editor object references them.
The assetregistry scans our uasset and caches information about the UStaticMesh and UMaterialInstanceConstant.
If we create new UStaticMesh and new UMaterialInstanceConstant and the references to the old ones are removed a garbage collect and save package will delete the old UStaticMesh and UMaterialInstanceConstant.
We have control over when these new static meshes and materials are created. We were calling FAssetRegistry::AssetCreated for the new meshes and materials but we only called FAssetRegistry::AssetDeleted for the old meshes.
The AssetRegistry retained the materials in it’s cache and presented out of date information regardless of whether the asset was saved or not. The correct information would only be shown if the editor was closed and reopened and the assetregistry was re-scanned.
I didn’t have control of when the materials were being garbage collected but I came up with a method that worked:
TArray< UObject* > SubObjects;
GetObjectsWithOuter(pFoundAsset->GetOutermost(), SubObjects, false, RF_ClassDefaultObject);
TMap AssetData;
for (int i = 0; i < SubObjects.Num(); i++)
{
AssetData.Add(SubObjects[i]->GetPathName(), new FAssetData(SubObjects[i]));
}
CollectGarbage( GARBAGE_COLLECTION_KEEPFLAGS );
SubObjects.Empty();
GetObjectsWithOuter(pFoundAsset->GetOutermost(), SubObjects, false, RF_ClassDefaultObject);
for (int i = 0; i < SubObjects.Num(); i++)
{
AssetData.Remove(SubObjects[i]->GetPathName());
}
for (TMap::TIterator AssetDataIter = AssetData.CreateIterator(); AssetDataIter; ++AssetDataIter)
{
FAssetRegistryModule::AssetDeleted(AssetDataIter->Value);
}
-
The code gets the list of objects before garbage collection and stores a FAssetData and a string for the object.
-
Garbage collection is triggered.
-
The new list is captured and the new items are removed from the list therefore leaving any old objects in the list.
-
A new AssetDeleted function was implemented that used a FAssetData pointer and which called FAssetRegistry::RemoveAssetData();
After this the assetregistry cache is updated and accurate information reported.
This meant we could clean up the asset registry after garbage collection without requiring pointers to the original data.
I admit our use case is not exactly the ue4 way but it works
Is there a cleaner alternative that would work? Is there a way to trigger a assetregistry update of our uasset after a garbage collect and without having to call AssetDeleted or AssetCreated?
Thanks
Kevin