ºÇ½ª¹¹¿·¡§
orika_ex_miyako 2024ǯ01·î04Æü(ÌÚ) 18:42:12ÍúÎò
¡¡PlayFab ¤Ê¤É¤Î¥µ¡¼¥Ð¡¼¤ËÊݸ¤·¤¿¥Ç¡¼¥¿¤Î¿¤¯¤Ï Json ·Á¼°¤Î¥Õ¥¡¥¤¥ë¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
¤½¤Î¤¿¤á¡¢¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤ä¥²¡¼¥àÆâ¤Î¾õÂÖ¤ò¸úΨŪ¤«¤Ä¡¢Àµ¤·¤¤ÊýË¡¤ò»È¤Ã¤ÆÊݸ¤ª¤è¤ÓÆÉ¤ß¹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£
¡¡Ëܵ»ö¤Ç¤Ï¡¢Json.NET¤ÈUniRx¤ÎReactiveProperty¤òÁȤ߹ç¤ï¤»¤Æ¡¢¥·¥ê¥¢¥é¥¤¥º¤È¥Ç¥·¥ê¥¢¥é¥¤¥º¤ò¹Ô¤¦¼êË¡¤ò²òÀ⤷¤Þ¤¹¡£
¡¡¡¦Unity¥²¡¼¥àÆâ¤Î¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤òJson·Á¼°¤ÇÊݸ ¡¡¡¦Êݸ¤µ¤ì¤¿Json¥Ç¡¼¥¿¤òÆÉ¤ß¹þ¤ó¤ÇUnity¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥Ç¥·¥ê¥¢¥é¥¤¥º ¡¡¡¦¥ê¥¢¥¯¥Æ¥£¥Ö¥×¥í¥°¥é¥ß¥ó¥°¥é¥¤¥Ö¥é¥êUniRx¤ÎReactiveProperty¤ò»È¤Ã¤Æ¸úΨŪ¤Ê¥Ç¡¼¥¿´ÉÍý
¡¡Ä̾ï¤ÎJson.NET¤Ç¤ÏReactiveProperty¤Î¥Ç¥·¥ê¥¢¥é¥¤¥º¤¬½ÐÍè¤Þ¤»¤ó¡£
¡¡Î㤨¤Ð¡¢°Ê²¼¤Î¤è¤¦¤ÊReactiveProperty¤ò»ý¤Ä¥¯¥é¥¹¤¬¤¢¤ë¤È¤·¤Þ¤¹¡£
[System.Serializable]
public class PlayerData {
public ReactiveProperty<int> Score { get; set; }
// ¥³¥ó¥¹¥È¥é¥¯¥¿
public PlayerData() {
// ½é´ü²½¤Ê¤ÉɬÍפ˱þ¤¸¤Æ½èÍý¤òÄɲÃ
Score = new ReactiveProperty<int>();
}
}
¡¡¤³¤Î¥¯¥é¥¹¤òÄ̾ï¤ÎJson.NET¤Ç¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤è¤¦¤È¤¹¤ë¤È¡¢¤¦¤Þ¤¯¤¤¤«¤º¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤¹¡£
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.
¡¡Json.NET¤Ë¤ª¤¤¤Æ¡¢ReactiveProperty ¤òÀµ¤·¤¯¥Ç¥·¥ê¥¢¥é¥¤¥º¤¹¤ë¤¿¤á¤Ë¤Ï¡¢JsonConveter ¥¯¥é¥¹¤ò·Ñ¾µ¤·¤¿
ReactivePropertyConverter ¤òºîÀ®¤·¡¢ReadJson ¥á¥½¥Ã¥É¤È WriteJson ¥á¥½¥Ã¥É¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Æ¼ÂÁõ¤·¤Þ¤¹¡£
¡¡°Ê²¼¤Ï¤½¤Î¥µ¥ó¥×¥ë¥³¡¼¥É¤Ç¤¹¡£
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>();
}
}
}
}
¡¡ReactivePropertyConverter ¥¯¥é¥¹¤Ï¡¢Å¬ÍѤ·¤¿¤¤ ReactiveProperty ¤Ë°À¾ðÊó¤òÉÕÍ¿¤¹¤ë¤³¤È¤ÇÍøÍѤǤ¤Þ¤¹¡£
¡¡Î㤨¤Ð¡¢Àè¤Û¤É¤Î PlayerData ¥¯¥é¥¹Æâ¤Î ReactiveProperty ¤Ë°À¾ðÊó¤òÉÕÍ¿¤·¤Þ¤¹¡£
[System.Serializable]
public class PlayerData {
[JsonConverter(typeof(ReactivePropertyConverter<int>))] // ¢«¡¡Â°À¾ðÊó¤òÉÕÍ¿
public ReactiveProperty<int> Score { get; set; }
}
¡¡¤³¤ì¤Ç¥Ç¥·¥ê¥¢¥é¥¤¥º¤È¥·¥ê¥¢¥é¥¤¥º¤¬²Äǽ¤Ê ReactiveProperty ¤Ë¤Ê¤ê¤Þ¤¹¡£
¡¡¤³¤Îµ¡Ç½¤ò³èÍѤ¹¤ë¤È Json ¤¬ ReactiveProperty ¤ËŬ¤·¤¿·Á¼°¤È¤·¤ÆÊݸ¡¦ÆÉ¤ß¹þ¤ß¤µ¤ì¤Þ¤¹¡£
{
"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);
}
}
¡¡¤³¤Î¥µ¥ó¥×¥ë¥³¡¼¥É¤Ç¤Ï¡¢ReactivePropertyConverter¤ò»ÈÍѤ·¤ÆJson.NET¤¬ReactiveProperty¤òÀµ¤·¤¯½èÍý¤Ç¤¤ë¤è¤¦¤Ë¤·¤Æ¤¤¤Þ¤¹¡£
¡¡¤³¤ì¤Ë¤è¤ê¡¢UniRx¤ÎReactiveProperty¤ò´Þ¤à¥ª¥Ö¥¸¥§¥¯¥È¤ò´Êñ¤ËJson·Á¼°¤ÇÊݸ¡¦ÆÉ¤ß¹þ¤ß¤Ç¤¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
¡¡¥¢¥×¥í¡¼¥ÁÊýË¡¡¤Î¾ì¹ç¡¢¤¹¤Ç¤ËÊݸ¤µ¤ì¤Æ¤¤¤ë Json ¥Ç¡¼¥¿¤¬Â¸ºß¤·¤Æ¤¤¤ë¤È¡¢
¥Õ¥¡¥¤¥ë¤Î·Á¼°¤¬¹ç¤ï¤Ê¤¤¤¿¤á¥¨¥é¡¼¤È¤Ê¤ê¤Þ¤¹¡£¤è¤Ã¤Æ¡¢ÅÓÃæ¤«¤é¤Î±¿ÍÑÊѹ¹¤Ï½ÐÍè¤Þ¤»¤ó¡£
¡¡ºÇ½é¤«¤é¥¢¥×¥í¡¼¥ÁÊýË¡¡¤ÇÀ©ºî¤·¤Æ¤¤¤ë¾ì¹ç¤Ë¤ÏÌäÂꤢ¤ê¤Þ¤»¤ó¤¬¡¢
¤¹¤Ç¤Ë Json ¥Õ¥¡¥¤¥ë¤¬¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤Î·Á¼°¤Ï¤½¤Î¤Þ¤Þ¤Ë¤·¤Æ¤ª¤¡¢
Êݸ¤¹¤ë¥¿¥¤¥ß¥ó¥°¤ä¡¢ÆÉ¤ß¹þ¤à¥¿¥¤¥ß¥ó¥°¤Ç ReactiveProperty ¤ËÂбþ¤µ¤»¤ëÊýË¡¤¬¤è¤¤¤Ç¤·¤ç¤¦¡£
¡¡°Ê²¼¤Ï¤½¤Î¥µ¥ó¥×¥ë¥³¡¼¥É¤Ç¤¹¡£
¡¡PlayerData ¥¯¥é¥¹¤Ë¡¢Json¤Î¥Ç¥·¥ê¥¢¥é¥¤¥º¤ª¤è¤Ó¥·¥ê¥¢¥é¥¤¥º¤Î¤¿¤á¤Î¥á¥½¥Ã¥É¤òÄɲ䷤Ƥ¤¤Þ¤¹¡£
ReactiveProperty¤ÏÈóSerializable¤È¤·¤ÆÊÝ»ý¤·¡¢Json¤Î½èÍýÁ°¸å¤ÇscoreÊÑ¿ô¤ÈscoreReactive¤ÎƱ´ü¤ò¤È¤ë¤è¤¦¤Ë¤·¤Æ¤¤¤Þ¤¹¡£
¤³¤ì¤Ë¤è¤ê¡¢Json¤Î¥·¥ê¥¢¥é¥¤¥º¡¦¥Ç¥·¥ê¥¢¥é¥¤¥º»þ¤ËReactiveProperty¤ÎÃͤâŬÀڤ˽èÍý¤Ç¤¤Þ¤¹¡£
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);
}
}
¡¡¤³¤Î¾ì¹ç¤Î Json ·Á¼°¤Ï°ìÈÌŪ¤Ê·Á¼°¤Ë¤Ê¤ê¤Þ¤¹¡£
{
"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 ¥µ¡¼¥Ð¡¼¤ØÁ÷¿®
}
}
¡¡¥µ¡¼¥Ð¡¼¤«¤é¤ÎJson¥Ç¡¼¥¿¤ò²¾Äꤷ¤Æ¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¡¢¿·¤·¤¤¥×¥ì¥¤¥ä¡¼¥Ç¡¼¥¿¤òºîÀ®¤·¤Æ¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¤¤¤Þ¤¹¡£
¡¡¥²¡¼¥àÆâ¤Ç¤Ï PlayerData Æâ¤Î ReactiveProperty ¤ò³èÍѤ·¤Æ¹ØÆÉ½èÍý¤ò¹Ô¤¤¡¢
¥µ¡¼¥Ð¡¼¤ËÁ÷¿®¤¹¤ëÁ°¤Ë Json ¤ËÃÖ¤´¹¤¨¤Æ¤«¤éÁ÷¿®¤¹¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£
- ¥«¥Æ¥´¥ê¡§
- ¿Ê³Ø/¥¹¥¯¡¼¥ë
- ¥×¥í¥°¥é¥ß¥ó¥°




¥³¥á¥ó¥È¤ò¤«¤¯