PUNRpcでの状態の同期のサンプル
設計なんもわからん
流れ
送信側
UIがイベントを発火(UseCaseのメソッドを呼ぶ)
UseCaseは自分側のNetWork GameObjectにイベント送信
NetWork Object はイベントを購読しRpc実行
受信側
NetWork ObjectはRpcが実行される
NetWork ObjectからUseCaseなりにイベント送信
イベントを購読しているUIがイベントを受け取り情報を更新
// 送信側
public class NotifyUpdateHogeEvent {
public static NotifyUpdateHogeEvent Default = new NotifyUpdateHogeEvent();
}
// 受信側
public class HogeUpdatedEvent {
public static HogeUpdatedEvent Default = new HogeUpdatedEvent();
}NetWork Object
NetWork Objectはイベントのやり取りをするだけ
public class HogePUNObject: MonoBehaviourPunCallbacks {
[PunRPC]
void OnHogeUpdatedEvent() {
MessageBroker.Default.Publish(Event.HogeUpdatedEvent.Default);
}
private void Awake() {
MessageBroker.Default
.Receive<Event.NotifyHogeUpdateEvent>()
.Subscribe(_ => {
photonView.RPC(nameof(OnHogeUpdatedEvent), RpcTarget.All);
});
}
}UseCase
UniRx の MessageBroker を使っているがなんでもいい
(Repositoryを通じてNetWork Objectとやりとりすべき?)
public interface IHogeUseCase { ... }
public class HogeUseCase: IHogeUseCase {
[Inject]
private IHogeRepository _repo;
...
public IObservable<Event.HogeUpdatedEvent> OnHogeUpdated() {
return MessageBroker.Default.Receive<Event.HogeUpdatedEvent>();
}
public void NotifyHogeUpdate() {
MessageBroker.Default.Publish(Event.NotifyHogeUpdateEvent.Default);
}
}UI
例ではUIWidgetsを使っているがuGUIでも同じ,
Start()
でリスナーを書く
(補足: UIWidget + Zenject
)
class HogePage : ZenjectStatefulWidget<HogePage, HogePageState> {
[Inject]
public IHogeUseCase HogeUseCase;
}
class HogePageState : State<HogePage> {
[Inject]
public HogePage HogePage { get; }
...
private OnHogeButtonClicked() {
widget.HogeUseCase.NotifyHogeUpdate();
}
private UpdateHoge() {}
public override void initState() {
base.initState();
widget.MatchingUseCase
.OnHogeUpdated()
.Subscribe(_ => UpdateHoge());
}
}参考文献
2019年をふわっとまとめる 〜Unityにおけるアーキテクチャの自分なりの解〜
usecase層より下層でのやりとりでObservableを扱うことについて
ここらへんも参考にしたい