¡¡¡¦Unity¥²¡¼¥àÆâ¤Î¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤òJson·Á¼°¤ÇÊݸ ¡¡¡¦Êݸ¤µ¤ì¤¿Json¥Ç¡¼¥¿¤òÆɤ߹þ¤ó¤ÇUnity¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥Ç¥·¥ê¥¢¥é¥¤¥º ¡¡¡¦¥ê¥¢¥¯¥Æ¥£¥Ö¥×¥í¥°¥é¥ß¥ó¥°¥é¥¤¥Ö¥é¥êUniRx¤ÎReactiveProperty¤ò»È¤Ã¤Æ¸úΨŪ¤Ê¥Ç¡¼¥¿´ÉÍý
[System.Serializable] public class PlayerData { public ReactiveProperty<int> Score { get; set; } // ¥³¥ó¥¹¥È¥é¥¯¥¿ public PlayerData() { // ½é´ü²½¤Ê¤ÉɬÍפ˱þ¤¸¤Æ½èÍý¤òÄɲà Score = new ReactiveProperty<int>(); } }
ArgumentException: Could not cast or convert from System.Int64 to UniRx.ReactiveProperty`1[System.Int32]. Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable (System.Object value, System.Type initialType, System.Type targetType)
JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Int32' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly. To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
using Newtonsoft.Json; using UniRx; using System; using Newtonsoft.Json.Linq; public class ReactivePropertyConverter<T> : JsonConverter<ReactiveProperty<T>> { public override void WriteJson(JsonWriter writer, ReactiveProperty<T> value, JsonSerializer serializer) { if (value != null && value.HasValue) { // HasValue¤¬true¤Î¾ì¹ç¡¢Value¤ò½ÐÎÏ serializer.Serialize(writer, new { Value = value.Value, HasValue = true }); } else { // HasValue¤¬false¤Î¾ì¹ç¡¢null¤ò½ÐÎÏ serializer.Serialize(writer, null); } } public override ReactiveProperty<T> ReadJson(JsonReader reader, Type objectType, ReactiveProperty<T> existingValue, bool hasExistingValue, JsonSerializer serializer) { var token = JToken.Load(reader); if (token.Type == JTokenType.Null) { // JSON¤¬null¤Î¾ì¹ç¡¢¿·¤·¤¤ReactiveProperty¤òºîÀ®¤·¤ÆÊÖ¤¹ return new ReactiveProperty<T>(); } else { // JSON¤¬Ãͤò»ý¤Ã¤Æ¤¤¤ë¾ì¹ç¡¢¤½¤ÎÃͤò¸µ¤Ë¿·¤·¤¤ReactiveProperty¤òºîÀ®¤·¤ÆÊÖ¤¹ var valueToken = token["Value"]; if (valueToken != null) { var value = valueToken.ToObject<T>(serializer); return new ReactiveProperty<T>(value); } else { // "Value"¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¡¢Îã³°½èÍý¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤Î½èÍý¤ò¹Ô¤¦ // Îã: throw new JsonSerializationException("Expected 'Value' property not found."); return new ReactiveProperty<T>(); } } } }
[System.Serializable] public class PlayerData { [JsonConverter(typeof(ReactivePropertyConverter<int>))] // ¢«¡¡Â°À¾ðÊó¤òÉÕÍ¿ public ReactiveProperty<int> Score { get; set; } }
{ "Score": { "Value": 0, "HasValue": true } }
public class GameManager : MonoBehaviour { void Start() { // ¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤ÎºîÀ®¤È½é´ü²½ PlayerData player = new PlayerData { Score = new (1000) }; // ¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤òJson¤Ë¥·¥ê¥¢¥é¥¤¥º string json = JsonConvert.SerializeObject(player); // Json¥Ç¡¼¥¿¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¿·¤·¤¤¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤òºîÀ® PlayerData loadedPlayer = JsonConvert.DeserializeObject<PlayerData>(json); // ¥Ç¥·¥ê¥¢¥é¥¤¥º¸å¤Î¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤Î¥¹¥³¥¢¤òɽ¼¨ Debug.Log("Loaded Player Score: " + loadedPlayer.Score.Value); } }
using UnityEngine; [System.Serializable] public class PlayerData { [SerializeField] private int score; // ReactiveProperty¤ÏJsonUtility¤Ç¥·¥ê¥¢¥é¥¤¥º¤Ç¤¤Ê¤¤¤Î¤Ç¡¢ÈóSerializable¤È¤·¤ÆÊÝ»ý private ReactiveProperty<int> scoreReactive; // ReactiveProperty¤ò³°Éô¤Ë¸ø³«¤¹¤ë¤¿¤á¤Î¥×¥í¥Ñ¥Æ¥£ public IReadOnlyReactiveProperty<int> ScoreReactive => scoreReactive; // ¥³¥ó¥¹¥È¥é¥¯¥¿ public PlayerData(int initialScore) { // ½é´ü²½¤Ê¤ÉɬÍפ˱þ¤¸¤Æ½èÍý¤òÄɲà score = initialScore; scoreReactive = new ReactiveProperty<int>(score); } // ¥µ¡¼¥Ð¡¼¤«¤é¼èÆÀ¤·¤¿Json¥Ç¡¼¥¿¤òPlayerData¤ËÊÑ´¹¤¹¤ë¥á¥½¥Ã¥É public static PlayerData FromJson(string json) { PlayerData playerData = JsonUtility.FromJson<PlayerData>(json); // JsonUtility¤Ç¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤¿¸å¡¢score¤òReactiveProperty¤ËÀßÄê playerData.scoreReactive.Value = playerData.score; return playerData; } // ¥µ¡¼¥Ð¡¼¤ËÁ÷¤ë¤¿¤á¤ÎJson¥Ç¡¼¥¿¤òÀ¸À®¤¹¤ë¥á¥½¥Ã¥É public string ToJson() { // ¥µ¡¼¥Ð¡¼¤ËÁ÷¤ëºÝ¤Ë¤Ï¡¢ReactiveProperty¤ÎÃͤòscoreÊÑ¿ô¤ËÀßÄê score = scoreReactive.Value; return JsonUtility.ToJson(this); } }
{ "score": 0 }
using UnityEngine; using Newtonsoft.Json; public class GameManager : MonoBehaviour { void Start() { // TODO ¥µ¡¼¥Ð¡¼¤«¤é¼õ¤±¼è¤Ã¤¿Json¥Ç¡¼¥¿¤ò²¾Äꤹ¤ë string receivedJsonFromServer = "{ \"score\": 1500 }"; // PlayerData¤ÎFromJson¥á¥½¥Ã¥É¤ò»ÈÍѤ·¤ÆJson¥Ç¡¼¥¿¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º PlayerData loadedPlayer = PlayerData.FromJson(receivedJsonFromServer); // ¥Ç¥·¥ê¥¢¥é¥¤¥º¸å¤Î¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤Î¥¹¥³¥¢¤òɽ¼¨ Debug.Log("Loaded Player Score: " + loadedPlayer.ScoreReactive.Value); // ¿·¤·¤¤¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤òºîÀ® PlayerData newPlayer = new PlayerData(2000); // PlayerData¤ÎToJson¥á¥½¥Ã¥É¤ò»ÈÍѤ·¤Æ¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤òJson¤Ë¥·¥ê¥¢¥é¥¤¥º string json = newPlayer.ToJson(); // ¥·¥ê¥¢¥é¥¤¥º¤·¤¿Json¥Ç¡¼¥¿¤òɽ¼¨ Debug.Log("Serialized Player Data: " + json); // TODO ¥µ¡¼¥Ð¡¼¤ØÁ÷¿® } }