/// <summary>
/// APIのラッパークラスを定義
/// </summary>
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using System;
using System.IO;
public class ItemApi : MonoBehaviour{
/// <summary>
/// ローカルのJSONを返すObservableを返す
/// </summary>
public IObservable<List<ItemInfo>> GetItems()
{
var path = Application.dataPath + "/info.json";
StreamReader reader = new StreamReader(path);
string json = reader.ReadToEnd();
return ListJsonAs<ItemInfo>(json);
}
/// <summary>
/// JSON配列の処理
/// https://qiita.com/akira-sasaki/items/71c13374698b821c4d73
/// </summary>
private IObservable<List<T>> ListJsonAs<T>(string json)
{
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
return Observable.Return(wrapper.list);
}
class Wrapper<T>
{
public List<T> list;
}
}
/// <summary>
/// APIのラッパークラスにアクセスしやすくする
/// </summary>
public class App {
public static readonly App Instance = new App();
// App.Instance.Api でアクセスできるようにする
public readonly ItemApi Api = new ItemApi();
private App() {
}
}
using System;
/// <summary>
/// JSON構造の規定
/// </summary>
[Serializable]
public class ItemInfo {
public string key;
public string name;
public int sex;
public bool isRegistered;
}
/// <summary>
/// JSON取得のAPIをSubscribeし、完了したら通知する
/// </summary>
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using System;
public class ItemLoader : MonoBehaviour {
public GameObject m_Item;
// 非同期専用のSubject
private AsyncSubject<List<ItemInfo>> m_ItemInfos = new AsyncSubject<List<ItemInfo>>();
// Expression-bodied
public IObservable<List<ItemInfo>> ItemInfos => m_ItemInfos;
public void Load()
{
App.Instance.Api.GetItems().Subscribe(data => {
m_ItemInfos.OnNext(data);
m_ItemInfos.OnCompleted();
});
}
}
/// <summary>
/// 各アイテムを生成し、クリック時に実行させるActionメソッドの中身を定義
/// </summary>
using System.Collections.Generic;
using UnityEngine;
using UniRx;
public class ItemManager : MonoBehaviour {
[SerializeField] GameObject m_Item;
[SerializeField] Transform m_ItemRoot;
[SerializeField] ItemLoader m_ItemLoader;
void Start ()
{
m_ItemLoader.Load();
m_ItemLoader.ItemInfos.Subscribe(infos => CreateItem(infos));
}
void CreateItem(List<ItemInfo> infos)
{
foreach (var info in infos)
{
GameObject obj = Instantiate(m_Item, m_ItemRoot);
Item item = obj.GetComponent<Item>();
item.Draw(info);
// アクションイベントの登録(委譲元)
item.ActionOnClick += val =>
{
Debug.Log("clicked: " + val.name);
};
}
}
}
/// <summary>
/// Itemプレファブにアタッチするスクリプト
/// Itemの情報を描画
/// Actionメソッドの実行
/// </summary>
using UnityEngine;
using UnityEngine.UI;
using System;
public class Item : MonoBehaviour {
[SerializeField] Button button;
[SerializeField] Text text;
private ItemInfo m_ItemInfo;
// アクションイベントを実行する(委譲先)
public Action<ItemInfo> ActionOnClick;
public void Draw(ItemInfo info)
{
m_ItemInfo = info;
text.text = info.name;
button.GetComponent<RectTransform>().localPosition = new Vector3(int.Parse(info.key) * 100f, 100f, 0f);
}
public void OnClick()
{
ActionOnClick(m_ItemInfo);
}
}