1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UE5, BlueprintでJSONデータを取り扱う

Last updated at Posted at 2021-10-29

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でもJsonObjectJsonValueに分けて管理されているようです

が、二つ分のコードを書くのがイヤだったので、JsonObject一本でコントロールできるように変更しました

さいごに

ほぼコピペです

JsonValueの管理を回避するために、Array型の戻り値を調整したところだけががんばったところです

参考

Git : Cl1608Ho/JsonBlueprint

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?