UnityMirror学习笔记(7):SyncList与SyncDictionary

Mirror是一个简单高效的开源的Unity多人游戏网络框架。
官方文档链接:
https://mirror-networking.gitbook.io/docs

SyncVar在大多数情况下都能很好的实现数据同步,
然而一个脚本里最多只可以有64个SyncVar
因此需要学习SyncListSyncDictionary来更好地实现多数据、结构化数据,
在客户端和服务器之间的同步。

SyncList

声明与构造
// 这里作为 NetworkBehaviour的继承类的 成员变量
readonly SyncList<BackPackItem> backPackItems = new SyncList<BackPackItem>();
回调函数

SyncListhook函数一样,当SyncList列表中的某一项被服务器同步后,客户端就会调用一个回调函数,
通过参数的方式给出,是哪一项被同步、同步操作是什么、新旧值是什么。

当客户端执行回调的时候,列表中的对象已经发生变化了

//在Start()/或OnStartClient()中,进行回调的注册。

    readonly SyncList<BackPackItem> backPackItems = new SyncList<BackPackItem>();

    public override void OnStartClient(){
        backPackItems.Callback += BackPackItemChanges;
    }
    private void BackPackItemChanges(SyncList<BackPackItem>.Operation op, int itemIndex, BackPackItem oldItem, BackPackItem newItem){
        switch(op){
            case SyncList<BackPackItem>.Operation.OP_ADD:{//在SyncList里添加一个新对象,itemIndex是这个新对象的下标,newItem就是这个新对象的引用

                break;}
            case SyncList<BackPackItem>.Operation.OP_INSERT:{//在SyncList的itemIndex下标插入一个新对象。newItem是新的对象的引用

                break;}
            case SyncList<BackPackItem>.Operation.OP_REMOVEAT:{//将SyncList的itemIndex下标的对象移去,oldItem是对移去对象的引用

                break;}
            case SyncList<BackPackItem>.Operation.OP_SET:{//将SyncList的itemIndex下标的对象换成一个新的,newItem是新的对象,oldItem是被替换的旧的。

                break;}
            case SyncList<BackPackItem>.Operation.OP_CLEAR:{//将SyncList的所有对象全部删掉

                break;}
        }
    }

SyncDictionary

声明与构造
// 这里作为 NetworkBehaviour的继承类的 成员变量    
readonly SyncDictionary<string, BaseEquipment> equipmentItems = new Mirror.SyncDictionary<string, BaseEquipment>();
回调函数
//在Start()/或OnStartClient()中,进行回调的注册。
    public override void OnStartClient(){
        equipmentItems.Callback += EquipmentChanges;
    }
    private void EquipmentChanges(SyncDictionary<string, BaseEquipment>.Operation op, string key, BaseEquipment item){
        switch (op)
        {
            case SyncIDictionary<string, BaseEquipment>.Operation.OP_ADD:{//向字典中添加了一项
                break;}
            case SyncIDictionary<string, BaseEquipment>.Operation.OP_SET:{//向字典中改变了一项
                break;}
            case SyncIDictionary<string, BaseEquipment>.Operation.OP_REMOVE:{//从字典中移除了一项
                break;}
            case SyncIDictionary<string, BaseEquipment>.Operation.OP_CLEAR:{//将字典所有项清除
                break;}
        }
    }

使用注意

自定义的数据对象类,需要自己写序列化与反序列化的方法

无论是SyncList或是SyncDictionary,都需要真正改变项的对象,才能被Mirror探测出来发生改变。并进行同步
比如下面直接修改,是无法进行同步的,因为引用对象整体没有发生改变,仅仅是这个对象内部的属性变化了。

    synclist[0].name = "newName"

像下面这样重新创建一个新的对象实例并修改引用则可以的:

    synclist[0] = new Item(synclist[0])

当然,使用基本数据类型的SyncList是不会有这样的问题的。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值