Json数据怎么映射到蓝图了?蓝图的文件都是uasset文件,有点类似二进制的文件,从应用层想把数据进行互相映射,没有提供相应的API,那就另想别的方法,所有的资源运行都在内存中,所以直接从内存中去操作!蓝图的Struct在内存中的映射和代码层的Struct在内存中的映射其实是一样的,数据结构有点类似单向链表,具体的有知道的,麻烦告知一下,不慎感激!
既然有了解决方案,下一步就是代码操作了,代码直接奉上!
// Fill out your copyright notice in the Description page of Project Settings.
#include "JsonConverter.h"
#include "Engine/Blueprint.h"
#include "Runtime/CoreUObject/Public/UObject/UnrealType.h"
#include "Engine/UserDefinedStruct.h"
JsonConverter *GetJsonConverter()
{
static JsonConverter conv;
return &conv;
}
JsonConverter::JsonConverter()
{
}
JsonConverter::~JsonConverter()
{
}
//---------Json映射到Struct-------------------------
void JsonConverter::ImportJasonToUStruct(const FString &content, UCustomStruct *msgUObject)
{
if (content.IsEmpty() || msgUObject == nullptr)
{
return;
}
UClass *tmpClass = msgUObject->GetClass();
UStructProperty *StructProperty = (UStructProperty *)tmpClass->FindPropertyByName(FName(TEXT("Table")));
if (StructProperty == nullptr)
{
return;
}
void *StructAddress = StructProperty->ContainerPtrToValuePtr(msgUObject);
TSharedPtr JsonObject;
TSharedRef> Reader = TJsonReaderFactory<>::Create(content);
if (FJsonSerializer::Deserialize(Reader, JsonObject))
{
TMap> JsonValues = JsonObject->Values;
for (auto &Iter: JsonValues)
{
UProperty *Property = GetProperty(StructProperty->Struct, Iter.Key);
if (Property == nullptr)
{
continue;
}
void* Address = Property->ContainerPtrToValuePtr(StructAddress);
JsonDataReflectUObjectData(Iter.Key, JsonObject, Iter.Value->Type, Property, Address);
}
}
}
void JsonConverter::JsonDataReflectUObjectData(const FString &JsonKey, TSharedPtr JsonValue, EJson ValueType, UProperty *Property, void *Address)
{
if (ValueType == EJson::Null || ValueType == EJson::None || JsonKey.IsEmpty() || !JsonValue.IsValid())
{
return;
}
switch (ValueType)
{
case EJson::Boolean:
{
bool value = false;
if (JsonValue->TryGetBoolField(JsonKey, value))
{
((UBoolProperty *)Property)->SetPropertyValue_InContainer(Address, value);
}
}
break;
case EJson::Number:
{
int32 value;
if (JsonValue->TryGetNumberField(JsonKey, value))
{
((UIntProperty *)Property)->SetPropertyValue_InContainer(Address, value);
}
}
break;
case EJson::String:
{
FString StrValue;
if (JsonValue->TryGetStringField(JsonKey, StrValue))
{
//CastChecked(Property)->SetPropertyValue_InContainer(Address, StrValue);
((UStrProperty*)Property)->SetPropertyValue_InContainer(Address, StrValue);
}
}
break;
case EJson::Array:
{
const TArray> *JsonArray;
if (JsonValue->TryGetArrayField(JsonKey, JsonArray))
{
DeserializeJsonArray(*JsonArray, Property, Address);
}
}
break;
case EJson::Object:
{
const TSharedPtr* JsonObject;
if (JsonValue->TryGetObjectField(JsonKey, JsonObject))
{
DeserializeJsonObject(JsonKey, *JsonObject, Property, Address);
}
}
break;
}
}
void JsonConverter::DeserializeJsonArray(const TArray> &JsonArray, UProperty *Property, void *StructAddress)
{
UArrayProperty *ArrProperty = Cast(Property);
FScriptArrayHelper ArrHelper(ArrProperty, StructAddress);
ArrHelper.EmptyValues();
TMap> JsonValues;
const TSharedPtr* FileMessageObject;
for (int i = 0; i < JsonArray.Num(); i++)
{
if (JsonArray[i].Get()->TryGetObject(FileMessageObject))
{
const int32 NewEntryIndex = ArrHelper.AddValue();
uint8 *EntryAddress = ArrHelper.GetRawPtr(NewEntryIndex);
JsonValues = (*FileMessageObject)->Values;
for (auto &Iter : JsonValues)
{
if (ArrProperty->Inner->IsA())
{
UStructProperty *PropertyStruct = Cast(ArrProperty->Inner);
UProperty *Property = GetProperty(PropertyStruct->Struct, Iter.Key);
JsonDataReflectUObjectData(Iter.Key, *FileMessageObject, Iter.Value->Type, Property, EntryAddress);
}
}
}
}
}
void JsonConverter::DeserializeJsonObject(const FString &JsonKey, TSharedPtr JsonObject, UProperty *Property, void *StructAddress)
{
if (JsonKey.IsEmpty() || !JsonObject.IsValid())
{
return;
}
const TArray> *JsonArray;
if (!JsonObject->TryGetArrayField(JsonKey, JsonArray))
{
return;
}
DeserializeJsonArray(*JsonArray, Property, StructAddress);
}
UProperty* JsonConverter::GetProperty(UStruct *StructClass, const FString &Name)
{
for (UProperty* Property = StructClass->PropertyLink; Property != NULL; Property = Property->PropertyLinkNext)
{
if (Property->GetName().Contains(Name))
{
return Property;
}
}
return NULL;
}
//-------------------------------------------------
//--------------Struct映射到JsonString-----------------
FString JsonConverter::ExportToJasonFromUStruct(UCustomStruct *msgUObject)
{
FString JsonString = TEXT("");
if (msgUObject == nullptr)
{
return JsonString;
}
UStructProperty *StructProperty = (UStructProperty *)msgUObject->GetClass()->FindPropertyByName(FName(TEXT("Table")));
void *StructAddress = StructProperty->ContainerPtrToValuePtr(msgUObject);
if (StructProperty == nullptr)
{
return JsonString;
}
TSharedRef>> JsonWriter = TJsonWriterFactory>::Create(&JsonString);
JsonWriter->WriteObjectStart();
UScriptStruct *Struct = StructProperty->Struct;
for (TFieldIterator It(Struct); It; ++It)
{
UProperty *Property = *It;
FString Name = Property->GetName();
for (int32 Index = 0; Index < Property->ArrayDim; Index++)
{
void *ValuePtr = Property->ContainerPtrToValuePtr(StructAddress, Index);
{
ExportChildProperty(Property, JsonWriter, ValuePtr);
}
}
}
JsonWriter->WriteObjectEnd();
JsonWriter->Close();
UE_LOG(LogTemp, Warning, TEXT("JsonString = %s"), *JsonString);
return JsonString;
}
void JsonConverter::ExportChildProperty(UProperty *Property, TSharedRef>> &JsonWriter, void *Address)
{
FString Key = GetPropertyName(Property);
if (Property->IsA())
{
bool Value = ((UBoolProperty *)Property)->GetPropertyValue_InContainer(Address);
JsonWriter->WriteValue(Key, Value);
}
else if (Property->IsA() || Property->IsA() || Property->IsA()
|| Property->IsA() || Property->IsA())
{
double Value = ((UIntProperty *)Property)->GetPropertyValue_InContainer(Address);
UE_LOG(LogTemp, Warning, TEXT("Key = %s Value = %f"), *Key, Value);
JsonWriter->WriteValue(Key, Value);
}
else if (Property->IsA())
{
FString Value = ((UStrProperty *)Property)->GetPropertyValue_InContainer(Address);
UE_LOG(LogTemp, Warning, TEXT("Key = %s Value = %s"), *Key, *Value);
JsonWriter->WriteValue(Key, Value);
}
else if (Property->IsA())
{
UArrayProperty *ArrayProperty = Cast(Property);
FScriptArrayHelper Helper(ArrayProperty, Address);
FString Key = GetPropertyName(Property);
JsonWriter->WriteArrayStart(Key);
UProperty *CurProperty = nullptr;
UE_LOG(LogTemp, Warning, TEXT("Number = %d"), Helper.Num());
for (int32 i = 0; i < Helper.Num(); i++)
{
if (ArrayProperty->Inner->IsA())
{
UStructProperty *PropertyStruct = Cast(ArrayProperty->Inner);
if (PropertyStruct != nullptr)
{
JsonWriter->WriteObjectStart();
UStruct *P = PropertyStruct->Struct;
void *Address = (void *)Helper.GetRawPtr(i);
for (UProperty* Property = P->PropertyLink; Property != NULL; Property = Property->PropertyLinkNext)
{
ExportChildProperty(Property, JsonWriter, Address);
}
JsonWriter->WriteObjectEnd();
}
}
}
JsonWriter->WriteArrayEnd();
}
}
FString JsonConverter::GetPropertyName(UProperty *Property)
{
FString PropertyName = Property->GetName();
FString Left;
FString Right;
if (PropertyName.Split("_", &Left, &Right))
{
return Left;
}
return "";
}
//-----------------------------------------------------