domzorg
(domzorg)
April 13, 2017, 8:50am
1
In version 4.14 the TryLoad function worked without any problem for blueprint objects.
Since version 4.15, the object isn’t loaded.
AKPickupObject* UKObjectManagerDefinition::GetPickupObject(FString UID)
{
if (ObjectLookupTable)
{
const FKBasicObjectDefinitionStruct* Data = ObjectLookupTable->FindRow<FKBasicObjectDefinitionStruct>(*UID, TEXT(""));
if (Data)
{
if (Data->Object.IsPending())
{
UObject* Asset = Data->Object.ToStringReference().TryLoad();
if (Asset == nullptr)
{
UE_LOG(LogKSGM, Log, TEXT("UKObjectManagerDefinition::GetPickupObject: Still couldn't load Data->Object"));
}
}
UBlueprint* Blueprint = Data->Object.Get();
if (Blueprint)
{
check(Blueprint->GeneratedClass->IsChildOf(AKPickupObject::StaticClass()));
UClass* Class = Blueprint->GeneratedClass;
AKPickupObject *PickupObject = CastChecked<AKPickupObject>(Class->GetDefaultObject());
return PickupObject;
}
}
}
return NULL;
}
UTexture2D* UKObjectManagerDefinition::GetPickupObjectTexture(FString UID)
{
if (ObjectLookupTable)
{
const FKBasicObjectDefinitionStruct* Data = ObjectLookupTable->FindRow<FKBasicObjectDefinitionStruct>(*UID, TEXT(""));
if (Data)
{
if (Data->Icon.IsPending())
{
UObject* Asset = Data->Icon.ToStringReference().TryLoad();
if (Asset == nullptr)
{
UE_LOG(LogKSGM, Log, TEXT("UKObjectManagerDefinition::GetPickupObjectTexture: Still couldn't load Data->Icon"));
}
}
// Add the icon to root to avoid the element from being destroyed by the GC
if (Data->Icon.IsValid() && !Data->Icon->IsRooted())
Data->Icon->AddToRoot();
return Data->Icon.Get();
}
}
// Not found, return the unknown object texture
return UKObjectManagerDefinition::GetPickupObjectUnknownTexture();
}
The objects are stored in a data table.
For loading the icon with GetPickupObjectTexture(FString UID), no problem.
But loading the blueprint object with GetPickupObject(FString UID), always return NULL.
I don’t think if it is linked with the new option for Nativization.
Thanks for your help.
It looks like you’re referencing the Blueprint asset directly, rather than reference its generated class. That won’t work in a cooked build.
domzorg
(domzorg)
April 14, 2017, 7:01am
3
Ok.
It was working in version 4.14. I changed nothing.
What do I need to change in order to take the reference from the DataTable object ?
domzorg
(domzorg)
April 14, 2017, 4:12pm
4
I’ve found a way to load the objects using FindObject function.
AKPickupObject* UKObjectManagerDefinition::GetPickupObject(FString UID)
{
if (ObjectLookupTable)
{
const FKBasicObjectDefinitionStruct* Data = ObjectLookupTable->FindRow<FKBasicObjectDefinitionStruct>(*UID, TEXT(""));
if (Data)
{
/* @todo Check with epic why we do need to call the
* TryLoad function before using FindObject
* If not, the FindObject always return NULL.
*/
if (Data->Object.IsPending())
{
UObject* Asset = Data->Object.ToStringReference().TryLoad();
}
FString objectName = Data->Object.ToStringReference().ToString() + FString("_C");
UClass* blueprintClass = FindObject<UClass>(ANY_PACKAGE, *objectName);
if (blueprintClass->IsChildOf(AKPickupObject::StaticClass()))
{
AKPickupObject *PickupObject = CastChecked<AKPickupObject>(blueprintClass->GetDefaultObject());
return PickupObject;
}
UE_LOG(LogKSGM, Log, TEXT("UKObjectManagerDefinition::GetPickupObject: Couldn't load Data->Object <%s>"), *objectName);
}
}
UE_LOG(LogKSGM, Log, TEXT("UKObjectManagerDefinition::GetPickupObject: Invalid data table. Check the BasicObjectData."));
return NULL;
}
But there is a strange behaviour.
If I don’t call
if (Data->Object.IsPending())
{
UObject* Asset = Data->Object.ToStringReference().TryLoad();
}
before the call
UClass* blueprintClass = FindObject<UClass>(ANY_PACKAGE, *objectName);
it always returns NULL.
What is doing TryLoad(), even if the function call always return NULL, to make FindObject() returning the right object instead of NULL ?
You probably want to use FStringClassReference
instead for your class reference, then you can just call TryLoadClass
on it to get your class reference. The type given to the template parameter would be the instance type of the class, AKPickupObject
in your case.
I’m pretty sure that an FStringAssetReference
property can’t auto-convert to a FStringClassReference
, so you may have to export your Data Table, make the property change, convert the class references to use the _C BP reference (so they reference the class rather than the BP), and then re-import your Data Table.
domzorg
(domzorg)
April 15, 2017, 6:26am
6
Ok I’ll try.
Thank you for your answer.