Day1
大纲
虚幻智能指针
共享指针
共享引用
JSON解析 对象型、数组型、解析Json文件、书写Json、读取场景Actor保存到Json
任务 : 封装高德地图天气系统插件给蓝图使用
内容
虚幻智能指针
创建共享指针
// //创建共享指针
//TSharedPtr<FMyClass> pMyClass = MakeShareable(new FMyClass);
TSharedPtr<FMyClass> pMyClass(new FMyClass);
//检查有效性
if (pMyClass)
{
}
TSharedPtr<FMyClass> p2;
//比较
if (pMyClass == p2)
{
}
//获取引用计数(当前共享指针管理的内存有多少人在用)
UE_LOG(LogTemp, Log, TEXT("%d"), pMyClass.GetSharedReferenceCount());
p2 = pMyClass;
UE_LOG(LogTemp, Log, TEXT(" == %d"), pMyClass.GetSharedReferenceCount());
//释放
pMyClass = nullptr;
UE_LOG(LogTemp, Log, TEXT(" == %d"), p2.GetSharedReferenceCount());
共享引用
// //创建共享指针
//TSharedPtr<FMyClass> pMyClass = MakeShareable(new FMyClass);
TSharedPtr<FMyClass> pMyClass(new FMyClass);
//检查有效性
if (pMyClass)
{
}
TSharedPtr<FMyClass> p2;
//比较
if (pMyClass == p2)
{
}
//获取引用计数(当前共享指针管理的内存有多少人在用)
UE_LOG(LogTemp, Log, TEXT("%d"), pMyClass.GetSharedReferenceCount());
p2 = pMyClass;
UE_LOG(LogTemp, Log, TEXT(" == %d"), pMyClass.GetSharedReferenceCount());
//释放
pMyClass = nullptr;
UE_LOG(LogTemp, Log, TEXT(" == %d"), p2.GetSharedReferenceCount());
弱指针
// //创建共享指针
//TSharedPtr<FMyClass> pMyClass = MakeShareable(new FMyClass);
TSharedPtr<FMyClass> pMyClass(new FMyClass);
//检查有效性
if (pMyClass)
{
}
TSharedPtr<FMyClass> p2;
//比较
if (pMyClass == p2)
{
}
//获取引用计数(当前共享指针管理的内存有多少人在用)
UE_LOG(LogTemp, Log, TEXT("%d"), pMyClass.GetSharedReferenceCount());
p2 = pMyClass;
UE_LOG(LogTemp, Log, TEXT(" == %d"), pMyClass.GetSharedReferenceCount());
//释放
pMyClass = nullptr;
UE_LOG(LogTemp, Log, TEXT(" == %d"), p2.GetSharedReferenceCount());
循环引用 : 智能指针引用计数为0才会释放
弱指针
JSON解析
对象型JSON
//解析对象型JSON
FString JsonStr = TEXT("{\"name\":\"二狗\", \"age\" : 39}");
//创建接收Json对象的数据
TSharedPtr<FJsonObject> JsonObject;
//借助解析工厂,解析Json文本串到阅读器
TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(JsonStr);
//借助解析器,完成解析
//反向序列化:从其它格式数据到内存对象格式数据
if (FJsonSerializer::Deserialize(JsonReader, JsonObject))
{
//读取数据?
UE_LOG(LogTemp, Log, TEXT("%s"), *JsonObject->GetStringField(TEXT("name")));
//检查是否存在某个字段
float age = 0;
if (JsonObject->TryGetNumberField(TEXT("age"), age))
{
UE_LOG(LogTemp, Log, TEXT("== %f"), age);
}
}
数组型JSON
//数组型JSon
FString JsonStr =TEXT("[\"二狗\", 34, true, {\"name\":\"二狗\", \"age\" : 39}, [49]]");
TArray<TSharedPtr<FJsonValue>> JsonValues;
TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(JsonStr);
if (FJsonSerializer::Deserialize(JsonReader, JsonValues))
{
//读取元素
UE_LOG(LogTemp, Log, TEXT("%s"), *JsonValues[0]->AsString());
//
float Num = 0;
if (JsonValues[1]->TryGetNumber(Num))
{
UE_LOG(LogTemp, Log, TEXT("%f"), Num);
}
TSharedPtr<FJsonObject> JsonObject = JsonValues[3]->AsObject();
UE_LOG(LogTemp, Log, TEXT("%s"), *JsonObject->GetStringField(TEXT("name")));
//解析数组
UE_LOG(LogTemp, Log, TEXT("%f"), JsonValues[4]->AsArray()[0]->AsNumber());
}
从磁盘解析JSON
//从磁盘解析json
FString JsonStr;
if (FFileHelper::LoadFileToString(JsonStr, TEXT("d:\\a.json")))
{
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(JsonStr);
if (FJsonSerializer::Deserialize(JsonReader, JsonObject))
{
TArray<TSharedPtr<FJsonValue>> person = JsonObject->GetArrayField(TEXT("person"));
TArray<TSharedPtr<FJsonValue>> teachers = person[0]->AsObject()->GetArrayField(TEXT("teachers"));
TSharedPtr<FJsonObject> liu = teachers[1]->AsObject()->GetObjectField(TEXT("liu"));
TArray<TSharedPtr<FJsonValue>> hobby = liu->GetArrayField(TEXT("hobby"));
for (auto hb : hobby)
{
UE_LOG(LogTemp, Log, TEXT("%s"), *hb->AsString());
}
}
}
序列化Json 对象型
//序列化json 对象型
TSharedPtr<FJsonObject> JsonObject(new FJsonObject);
//设置字段
JsonObject->SetStringField(TEXT("name"), TEXT("二狗"));
JsonObject->SetNumberField(TEXT("age"), 40);
//构建书写器
FString JsonStr;
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&JsonStr);
//序列化
if (FJsonSerializer::Serialize(JsonObject.ToSharedRef(), JsonWriter))
{
UE_LOG(LogTemp, Log, TEXT("%s"), *JsonStr);
}
序列化Json 数组型
//数组型
TArray<TSharedPtr<FJsonValue>> JsonValues;
JsonValues.Add(MakeShareable(new FJsonValueString(TEXT("二狗"))));
JsonValues.Add(MakeShareable(new FJsonValueNumber(49)));
JsonValues.Add(MakeShareable(new FJsonValueBoolean(true)));
FString JsonStr;
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&JsonStr);
if (FJsonSerializer::Serialize(JsonValues, JsonWriter))
{
UE_LOG(LogTemp, Log, TEXT("%s"), *JsonStr);
}
案例 : 读取场景中的Actor的坐标、缩放、旋转保存到JSON文件
TArray<TSharedPtr<FJsonValue>> JsonValues;
TArray<AActor*> Actors;
//获取场景所有Actor
UGameplayStatics::GetAllActorsOfClass(this, AActor::StaticClass(), Actors);
for (auto ac : Actors)
{
//新建一个对象型 Json
TSharedPtr<FJsonObject> JsonObject(new FJsonObject);
JsonObject->SetStringField(TEXT("Name"), ac->GetName());
TSharedPtr<FJsonObject> Position(new FJsonObject);
Position->SetNumberField(TEXT("X"), ac->GetActorLocation().X);
Position->SetNumberField(TEXT("Y"), ac->GetActorLocation().Y);
Position->SetNumberField(TEXT("Z"), ac->GetActorLocation().Z);
JsonObject->SetObjectField(TEXT("Position"), Position);
TSharedPtr<FJsonObject> Rotation(new FJsonObject);
Rotation->SetNumberField(TEXT("Pitch"), ac->GetActorRotation().Pitch);
Rotation->SetNumberField(TEXT("Yaw"), ac->GetActorRotation().Yaw);
Rotation->SetNumberField(TEXT("Roll"), ac->GetActorRotation().Roll);
JsonObject->SetObjectField(TEXT("Rotation"), Rotation);
TSharedPtr<FJsonObject> Scale(new FJsonObject);
Scale->SetNumberField(TEXT("X"), ac->GetActorScale().X);
Scale->SetNumberField(TEXT("Y"), ac->GetActorScale().Y);
Scale->SetNumberField(TEXT("Z"), ac->GetActorScale().Z);
JsonObject->SetObjectField(TEXT("Scale"), Scale);
JsonValues.Add(MakeShareable(new FJsonValueObject(JsonObject)));
}
FString JsonStr;
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&JsonStr);
if (FJsonSerializer::Serialize(JsonValues, JsonWriter))
{
FFileHelper::SaveStringToFile(JsonStr, TEXT("d:\\b.json"));//保存到文件
}
插件
蓝图无法直接操作C++的东西 , 使用C++包裹一层在蓝图里面调用
纯标记 : 每次调用都会执行一次引脚
侵入式指针
API & 节点
TIPS
面试 : 循环引用
Json和虚幻数组的区别 , 不是同质类型
多思考这个游戏我来做这个功能怎么做
时间膨胀值 : 局部和全局
时空穿梭 :