We added new enemy, skeleton meshes are loaded asynchronously, we have already 6 types of enemies that never did such a crash but with this new enemy this crash happens very rarely, but right before his spawn so i assume its because of async batch request, i changed things with async load but cant solve it yet, i post the crash and the code where that async request happens(its pretty long, since i added a lots of UE_LOG):
Crash on this assert:
Code:
void UPrimaryDataAssetsManager::AsyncLoadEnemy(const ECharacterType InCharacter, const EGameMode InGameMode, const bool bCanEvolve, TFunction<void()> InCallBack)
{
if (!GetCanAsyncLoadHappen()) return;
const FCharacterContainer& CharacterContainer = GetCharacterData(InCharacter);
TArray<FSoftObjectPath> PathsToLoad;
const TObjectPtr<UPA_CharacterContainer> CharContainer = CharacterContainer.GetCharacterContainer();
if (!IsValid(CharContainer))
{
UE_LOG(LogTemp, Error, TEXT("Invalid CharacterContainer for character %s"), *UEnum::GetValueAsString(InCharacter));
return;
}
if (!CharContainer->CharacterClass.IsNull()) PathsToLoad.Add(CharContainer->CharacterClass.ToSoftObjectPath());
else UE_LOG(LogTemp, Warning, TEXT("CharacterClass is invalid for character %s"), *UEnum::GetValueAsString(InCharacter));
if (!CharContainer->CharacterMesh.IsNull()) PathsToLoad.Add(CharContainer->CharacterMesh.ToSoftObjectPath());
else UE_LOG(LogTemp, Warning, TEXT("CharacterMesh is invalid for character %s"), *UEnum::GetValueAsString(InCharacter));
EWeapon Weapon = GetWeaponByCharacter(InCharacter);
const TObjectPtr<UPA_WeaponContainer> WeaponContainer = GetWeaponData(Weapon);
if (!IsValid(WeaponContainer))
{
UE_LOG(LogTemp, Error, TEXT("Invalid WeaponContainer for weapon %s"), *UEnum::GetValueAsString(Weapon));
return;
}
if (!WeaponContainer->WeaponClass.IsNull()) PathsToLoad.Add(WeaponContainer->WeaponClass.ToSoftObjectPath());
else UE_LOG(LogTemp, Warning, TEXT("WeaponClass is invalid for weapon %s"), *UEnum::GetValueAsString(Weapon));
if (!WeaponContainer->HandsMesh.IsNull()) PathsToLoad.Add(WeaponContainer->HandsMesh.ToSoftObjectPath());
else UE_LOG(LogTemp, Warning, TEXT("HandsMesh is invalid for weapon %s"), *UEnum::GetValueAsString(Weapon));
EWeapon SingularWeapon = GetSingularWeapon(Weapon);
if (SingularWeapon != EWeapon::None)
{
const TObjectPtr<UPA_WeaponContainer> SingularWeaponContainer = GetWeaponData(SingularWeapon);
if (IsValid(SingularWeaponContainer))
{
if (!SingularWeaponContainer->WeaponClass.IsNull()) PathsToLoad.Add(SingularWeaponContainer->WeaponClass.ToSoftObjectPath());
else UE_LOG(LogTemp, Warning, TEXT("SingularWeaponClass is invalid for weapon %s"), *UEnum::GetValueAsString(SingularWeapon));
if (!SingularWeaponContainer->WeaponMesh.IsNull()) PathsToLoad.Add(SingularWeaponContainer->WeaponMesh.ToSoftObjectPath());
else UE_LOG(LogTemp, Warning, TEXT("SingularWeaponMesh is invalid for weapon %s"), *UEnum::GetValueAsString(SingularWeapon));
}
}
else if (!WeaponContainer->WeaponMesh.IsNull()) PathsToLoad.Add(WeaponContainer->WeaponMesh.ToSoftObjectPath());
else UE_LOG(LogTemp, Warning, TEXT("WeaponMesh is invalid for weapon %s"), *UEnum::GetValueAsString(Weapon));
TArray<FSoftObjectPath> ValidPaths;
for (const FSoftObjectPath& Path : PathsToLoad) if (!Path.GetAssetPathString().IsEmpty()) ValidPaths.Add(Path);
if (ValidPaths.IsEmpty())
{
UE_LOG(LogTemp, Warning, TEXT("No valid paths to async load for character %s"), *UEnum::GetValueAsString(InCharacter));
return;
}
for (const FSoftObjectPath& Path : ValidPaths) UE_LOG(LogTemp, Warning, TEXT("Path: %s"), *Path.ToString());
TWeakObjectPtr WeakWorld = GetWorld();
TSharedPtr<FStreamableHandle> Handle = UAssetManager::GetStreamableManager().RequestAsyncLoad(ValidPaths, [this, WeakWorld, SingularWeapon, Weapon, InCharacter, InGameMode, bCanEvolve, InCallBack]
{
if (WeakWorld.IsValid() && IsAsyncAssetWorldValid(WeakWorld.Get())) AsyncLoadEnemyCallback(SingularWeapon, Weapon, InCharacter, InGameMode, bCanEvolve, InCallBack);
else UE_LOG(LogTemp, Warning, TEXT("World no longer valid during AsyncLoadEnemy callback for character %s"), *UEnum::GetValueAsString(InCharacter));
});
AddAsyncHandle(Handle);
}
If anyone has suggestions i will be glad, since i’m running out of ideas… Thanks.