どうやって使うの?何に使うの?
PlayerPrefs を使って、ゲームのデータを永続化したりするのに、
BaseModel を継承した Model を作って、やりとりを簡潔にしましょう。
というもの。
以下がその BaseModel。
やってることは
1. Register メソッドで登録された ReactiveProperty を監視、値の変更があったら PlayerPrefs に保存
2. 次回 Awake 時に PlayerPrefs の情報と、 Register された情報をもとに、インスタンスと、そのデータを復元
BaseModel のコードの後に、その使用例を載せておきます。
BaseModel
usingSystem.Collections.Generic;usingUnityEngine;usingSystem.Linq;usingUniRx;namespaceModels{abstractpublicclassBaseModel:MonoBehaviour{publicclassModel{publicintid;publicList<FloatReactiveProperty>floatAttrs=newList<FloatReactiveProperty>();publicList<IntReactiveProperty>intAttrs=newList<IntReactiveProperty>();publicList<StringReactiveProperty>stringAttrs=newList<StringReactiveProperty>();protectedvoidRegister(IntReactivePropertyattr){intAttrs.Add(attr);}protectedvoidRegister(FloatReactivePropertyattr){floatAttrs.Add(attr);}protectedvoidRegister(StringReactivePropertyattr){stringAttrs.Add(attr);}virtualprotectedvoidInitInstance(){}virtualprotectedvoidRegisterAttributes(){}protectedstringmodelName{get{returnthis.GetType().ToString().Split(newchar[]{'+'})[0];}}publicModel(){InitInstance();RegisterAttributes();floatAttrs.ForEach(a=>{a.AsObservable().Skip(1).Do(_=>Debug.Log(_)).Do(value=>PlayerPrefs.SetFloat(modelName+floatAttrs.IndexOf(a).ToString()+"float"+id,value)).Subscribe(_=>PlayerPrefs.Save());});intAttrs.ForEach(a=>{a.AsObservable().Skip(1).Do(_=>Debug.Log(_)).Do(value=>PlayerPrefs.SetInt(modelName+intAttrs.IndexOf(a).ToString()+"int"+id,value)).Subscribe(_=>PlayerPrefs.Save());});stringAttrs.ForEach(a=>{a.AsObservable().Skip(1).Do(_=>Debug.Log(_)).Do(value=>PlayerPrefs.SetString(modelName+stringAttrs.IndexOf(a).ToString()+"string"+id,value)).Subscribe(_=>PlayerPrefs.Save());});PlayerPrefs.SetInt(modelName+"count",id+1);}}virtualprotectedModelInstantiate(){returnnewModel();}publicvoidAwake(){stringmodelName=this.GetType().ToString();intinstanceCount=PlayerPrefs.HasKey(modelName+"count")?PlayerPrefs.GetInt(modelName+"count"):0;Enumerable.Range(0,instanceCount).ToList().ForEach(i=>{Modelinstance=Instantiate();instance.floatAttrs.ForEach(a=>{a.Value=PlayerPrefs.GetFloat(modelName+instance.floatAttrs.IndexOf(a).ToString()+"float"+instance.id);});instance.intAttrs.ForEach(a=>{a.Value=PlayerPrefs.GetInt(modelName+instance.intAttrs.IndexOf(a).ToString()+"int"+instance.id);});instance.stringAttrs.ForEach(a=>{a.Value=PlayerPrefs.GetString(modelName+instance.stringAttrs.IndexOf(a).ToString()+"string"+instance.id);});});}}}
使用例
Score(BaseModelの継承先)
usingSystem.Linq;usingUniRx;namespaceModels{publicclassScore:BaseModel{newpublicclassModel:BaseModel.Model{publicIntReactivePropertyscore=newIntReactiveProperty();publicboolisHighScore{get{returnscore.Value>100;}}overrideprotectedvoidRegisterAttributes(){Register(score);}// 共通部分overrideprotectedvoidInitInstance(){id=instances.Count;instances.Add(this);}}staticReactiveCollection<Model>instances=newReactiveCollection<Model>();publicstaticReactiveCollection<Model>All(){returnnewReactiveCollection<Model>(instances);}publicstaticintcount{get{returnAll().Count;}}publicstaticModelFirst(){returninstances.First();}overrideprotectedBaseModel.ModelInstantiate(){returnnewModel();}newpublicvoidAwake(){base.Awake();if(All().Count==0){// new Model();}}}}
Presenter
usingUnityEngine;usingModels;publicclassPresenter:MonoBehaviour{voidStart(){if(Score.count==0){Score.Modelscore=newScore.Model();}Debug.Log(Score.All().Count);Debug.Log(Score.First().score.Value);}}
まだ改善の余地がたくさんあると思うので、まさかりください。
C# 全然わからん。