BlueprintにはJSONを直接扱う機能がない?
Blueprint上でお手軽に扱う方法はないようで、C++用に用意されているJSONを扱うためのライブラリを用いて、UObjectを拡張するなどが必要なようです
Gitに公開されているコードを参考に、ほぼほぼコピーですが、必要最低限の機能を実装してみました
環境
ソフトウェア | バージョン |
---|---|
MacOS | 10.15.7 |
UnrealEngine | 5.0.0 |
Visual Studio Code | 1.61.2 |
Xcode | 12.4 |
.NET SDK | 5.0.402 |
コード
プロジェクト名は仮にJsonTest
としています
BlueprintJsonObjectLite.h
// Fill out your copyright notice in the Description page of Project Settings.
# pragma once
# include "CoreMinimal.h"
# include "UObject/NoExportTypes.h"
# include "BlueprintJsonObjectLite.generated.h"
/**
*
*/
UCLASS()
class JSONTEST_API UBlueprintJsonObject : public UObject
{
GENERATED_BODY()
private:
TSharedPtr<FJsonObject> mJsonObject;
void SetSharedPointer(TSharedPtr<FJsonObject> JsonObject)
{
mJsonObject = JsonObject;
}
public:
UBlueprintJsonObject();
TSharedPtr<FJsonObject> ToSharedPointer();
static UBlueprintJsonObject *FromSharedPointer(TSharedPtr<FJsonObject> JsonObject);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Create JSON Object", Keywords = "Json Create Object", ShortTooltip = "Creates an empty Json Object"), Category = "Json|Object")
static UBlueprintJsonObject *Create();
UFUNCTION(BlueprintPure, meta = (DisplayName = "Parse Object String", Keywords = "Json Parse Object String", ShortTooltip = "Parses a Json Object String ({\"some\": \"example\"})"), Category = "Json|Object")
static bool Parse(FString JsonString, UBlueprintJsonObject *&JsonObject);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Stringify Object", Keywords = "Json Stringify Object", AdvancedDisplay = "PrettyPrint", ShortTooltip = "Converts a Json Object to a single string"), Category = "Json|Object")
FString Stringify(bool PrettyPrint = false);
//
// Has, Get Methods
UFUNCTION(BlueprintPure, meta = (DisplayName = "Has Boolean", Keywords = "Json Has Boolean", ShortTooltip = "Does the Json Object have this key and is it a boolean?"), Category = "Json|Object")
bool HasBoolean(FString Key);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Boolean", Keywords = "Json Get Boolean", ShortTooltip = "Gets a certain boolean from the Json Object"), Category = "Json|Object")
bool GetBoolean(FString Key, bool& Value);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Has Integer", Keywords = "Json Has Integer", ShortTooltip = "Does the Json Object have this key and is it an integer?"), Category = "Json|Object")
bool HasInteger(FString Key);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Integer", Keywords = "Json Get Integer", ShortTooltip = "Gets a certain integer from the Json Object"), Category = "Json|Object")
bool GetInteger(FString Key, int32& Value);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Has Float", Keywords = "Json Has Float", ShortTooltip = "Does the Json Object have this key and is it a float?"), Category = "Json|Object")
bool HasFloat(FString Key);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Float", Keywords = "Json Get Float", ShortTooltip = "Gets a certain float from the Json Object"), Category = "Json|Object")
bool GetFloat(FString Key, float& Value);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Has String", Keywords = "Json Has String", ShortTooltip = "Does the Json Object have this key and is it a string?"), Category = "Json|Object")
bool HasString(FString Key);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get String", Keywords = "Json Get String", ShortTooltip = "Gets a certain string from the Json Object"), Category = "Json|Object")
bool GetString(FString Key, FString& Value);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Has Object", Keywords = "Json Has Object", ShortTooltip = "Does the Json Object have this key and is it another Json Object?"), Category = "Json|Object")
bool HasObject(FString Key);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Object", Keywords = "Json Get Object", ShortTooltip = "Gets a certain Json Object from the Json Object"), Category = "Json|Object")
bool GetObject(FString Key, UBlueprintJsonObject *&Value);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Has Array", Keywords = "Json Has Array", ShortTooltip = "Does the Json Object have this key and is it a Json Array?"), Category = "Json|Object")
bool HasArray(FString Key);
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Array", Keywords = "Json Get Array", ShortTooltip = "Gets a certain Json Array from the Json Object without specifying a type"), Category = "Json|Object")
bool GetArray(FString Key, TArray<UBlueprintJsonObject *> &Values);
};
BlueprintJsonObjectLite.cpp
// Fill out your copyright notice in the Description page of Project Settings.
# include "BlueprintJsonObjectLite.h"
UBlueprintJsonObject::UBlueprintJsonObject()
{
mJsonObject = MakeShareable(new FJsonObject);
}
TSharedPtr<FJsonObject> UBlueprintJsonObject::ToSharedPointer()
{
return mJsonObject;
}
UBlueprintJsonObject *UBlueprintJsonObject::FromSharedPointer(TSharedPtr<FJsonObject> JsonObject)
{
UBlueprintJsonObject *Object = NewObject<UBlueprintJsonObject>();
Object->SetSharedPointer(JsonObject);
return Object;
}
// Blueprint
UBlueprintJsonObject *UBlueprintJsonObject::Create()
{
return NewObject<UBlueprintJsonObject>();
}
bool UBlueprintJsonObject::Parse(FString JsonString, UBlueprintJsonObject *&JsonObject)
{
TSharedPtr<FJsonObject> Object;
TSharedRef<TJsonReader<> > Reader = TJsonReaderFactory<>::Create(JsonString);
if (!FJsonSerializer::Deserialize(Reader, Object))
return false;
JsonObject = UBlueprintJsonObject::FromSharedPointer(Object);
return true;
}
FString UBlueprintJsonObject::Stringify(bool PrettyPrint)
{
FString JsonString;
if (PrettyPrint)
{
TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR> > > Writer = TJsonWriterFactory<TCHAR, TPrettyJsonPrintPolicy<TCHAR> >::Create(&JsonString);
FJsonSerializer::Serialize(mJsonObject.ToSharedRef(), Writer);
}
else
{
TSharedRef<TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > Writer = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonString);
FJsonSerializer::Serialize(mJsonObject.ToSharedRef(), Writer);
}
return JsonString;
}
bool UBlueprintJsonObject::HasBoolean(FString Key) {
return mJsonObject->HasTypedField<EJson::Boolean>(Key);
}
bool UBlueprintJsonObject::GetBoolean(FString Key, bool& Value) {
if (!HasBoolean(Key))
return false;
return mJsonObject->TryGetBoolField(Key, Value);
}
bool UBlueprintJsonObject::HasInteger(FString Key) {
if (!mJsonObject->HasTypedField<EJson::Number>(Key))
return false;
double val;
bool success = mJsonObject->TryGetNumberField(Key, val);
if (!success)
return false;
double intpart;
return std::modf(val, &intpart) == 0.0;
}
bool UBlueprintJsonObject::GetInteger(FString Key, int32& Value) {
if (!HasInteger(Key))
return false;
return mJsonObject->TryGetNumberField(Key, Value);
}
bool UBlueprintJsonObject::HasFloat(FString Key) {
return mJsonObject->HasTypedField<EJson::Number>(Key);
}
bool UBlueprintJsonObject::GetFloat(FString Key, float& Value) {
if (!HasFloat(Key))
return false;
double val;
bool success = mJsonObject->TryGetNumberField(Key, val);
if (success)
Value = val;
return success;
}
bool UBlueprintJsonObject::HasString(FString Key) {
return mJsonObject->HasTypedField<EJson::String>(Key);
}
bool UBlueprintJsonObject::GetString(FString Key, FString& Value) {
if (!HasString(Key))
return false;
return mJsonObject->TryGetStringField(Key, Value);
}
bool UBlueprintJsonObject::HasObject(FString Key) {
return mJsonObject->HasTypedField<EJson::Number>(Key);
}
bool UBlueprintJsonObject::GetObject(FString Key, UBlueprintJsonObject*& Value) {
const TSharedPtr<FJsonObject>* JsonObject;
bool Success = mJsonObject->TryGetObjectField(Key, JsonObject);
if (Success)
Value = UBlueprintJsonObject::FromSharedPointer(*JsonObject);
return Success;
}
bool UBlueprintJsonObject::HasArray(FString Key)
{
return mJsonObject->HasTypedField<EJson::Array>(Key);
}
bool UBlueprintJsonObject::GetArray(FString Key, TArray<UBlueprintJsonObject *> &Values)
{
if (!HasArray(Key))
return false;
const TArray<TSharedPtr<FJsonValue> > *vals;
bool success = mJsonObject->TryGetArrayField(Key, vals);
if (!success)
return false;
for (TSharedPtr<FJsonValue> Value : *vals)
{
TSharedPtr<FJsonObject> JsonObject = Value->AsObject();
Values.Add(UBlueprintJsonObject::FromSharedPointer(JsonObject));
}
return true;
}
用意されているライブラリ、JsonUtilities
では、同じJSONでもJsonObject
とJsonValue
に分けて管理されているようです
が、二つ分のコードを書くのがイヤだったので、JsonObject
一本でコントロールできるように変更しました
さいごに
ほぼコピペです
JsonValueの管理を回避するために、Array型の戻り値を調整したところだけががんばったところです
参考
Git : Cl1608Ho/JsonBlueprint