I am automating how to serialize a class with [Serializable]
attribute to Json in Unity.
I tried to get the FieldInfo
by reflection and pass that value to parse it as Json, but it failed. Empty curly braces are output.
Problem Code
public static class SerializeHelper
{
public static void SerializeObjectField()
{
var fieldsInfo = GameInfo.Instance.GetType().GetFields(
BindingFlags.Public | BindingFlags.Instance);
foreach (var fieldInfo in fieldsInfo)
{
ToJson(fieldInfo);
}
}
private static void ToJson(FieldInfo fieldInfo)
{
var json = JsonUtility.ToJson(fieldInfo, true);
Debug.Log(json); // Empty curly braces are output
}
}
public class GameInfo : MonoBehaviour
{
// Sigleton Pattern
public Gold gold = new();
public int Gold
{
get => gold.Amount;
set => gold.Amount = value;
}
// ...
}
[Serializable]
public class Gold
{
[SerializeField] private int amount;
public int Amount
{
get => amount;
set => amount = value;
}
}
If I write it manually without using reflection, it outputs just fine.
Correct Code
// ...
var json = JsonUtility.ToJson(GameInfo.Instance.gold, true);
Debug.Log(json);
// ...
Output
{
"amount": 43 // Create a button that increments by 1 for every click
}
Can you please tell me what I am doing wrong when using reflection?
CodePudding user response:
You are missing one call, property info gives you a description of a field/property, which is related to class definition but has no reference to your actual instance.
To actually get the value you need to call GetValue method on the property info
try replacing
var json = JsonUtility.ToJson(fieldInfo, true);
with something similar to:
var json = JsonUtility.ToJson(fieldInfo.GetValue(instanceReference), true);
A working example below:
public class ReflectionTest : MonoBehaviour
{
[System.Serializable]
public class TestClass
{
public string myString = "test";
}
public TestClass testClassInstance = new TestClass();
void OnValidate()
{
var fieldInfo = this.GetType().GetField("testClassInstance");
var value = fieldInfo.GetValue(this);
var valueString = JsonUtility.ToJson(value);
Debug.Log($"after serialization {valueString}");
}
}