[22] 虛幻引擎知識擴充 智慧指標、JSON解析、外掛

啊賢發表於2024-06-03

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才會釋放

[22] 虛幻引擎知識擴充 智慧指標、JSON解析、外掛

弱指標

[22] 虛幻引擎知識擴充 智慧指標、JSON解析、外掛

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和虛幻陣列的區別 , 不是同質型別

多思考這個遊戲我來做這個功能怎麼做

時間膨脹值 : 區域性和全域性
時空穿梭 :

疑問

相關文章