最近在开发过程,遇到这样一个问题,我需要动态显示技能图标,而这个技能图标是根据一个值来确定的,但是这个值是在server中设置的,而图标是Client的方法,我需要同步这个变量到Client然后在显示图标.

这个功能他就是同步一个对象的某个属性,所以用nettable明显不合适,过于重了,而且需要客户端自己getvalue同时也污染宣告定义,于是在了解一番后,认识了Modifier Transmitter Data,它可以同步指定的Server对象到Clinet,但是其中也有一定的坑和需要创建一个Modifier到对象实体,其实在一些游戏开发技术就相当于添加一个网络同步组件/功能,我目前就遇到2个坑和2个注意点,稍后会说.

用例

@registerModifier()
export class modifier_server_sync extends BaseModifier
{
    OnCreated(params: object)
    {
        if (!IsServer())
        {
            return;
        }
        
        //发送数据到客户端,调用这个方法才会将 `AddCustomTransmitterData` 的数据发送到客户端哈
        this.SetHasCustomTransmitterData(true);
    }

    //发送到客户端的数据
    AddCustomTransmitterData()
    {
        return {
            A: 100,
            B: Vector(100,100,100)
        };
    }
    
    private _testA:number;
    private _testB:Vector;
    
    //处理Server发来的数据
    HandleCustomTransmitterData(data)
    {
        this._testA = data.A;
        this._testB = data.B; // Error,这里数据是错误的,得到是一个空格分隔的字符串 `100 100 100`,需要处理
        print("B: ",this._testB);
        const strs = data.B.split(" ");
        this._testB = Vector(parseFloat(strs[0]), parseFloat(strs[1]), parseFloat(strs[2]));
        
        print(this._testA);
        print(this._testB);
    }
    
    //隐藏
    IsHidden(): boolean
    {
        return true;
    }

    //不能被驱散
    IsPurgable(): boolean
    {
        return false;
    }
    
    //拥有者死亡不删除
    RemoveOnDeath(): boolean {return false;}

    //时间到不删除
    DestroyOnExpire(): boolean {return false;}
}


const unit = CreateUnitByName(..........)
unit.AddNewModifier(undefined,undefined,modifier_server_sync.name,{});

需要注意的就是Vector类型,它会被处理为stirng类型 我很少用nettable,不知道nettable会不会也是这样的行为

还有FindByName找到的场景实体,同步entindex到客户端后,客户端通过EntIndexToHScript并不能找到,我也是遇到这个问题后转换为同步Vector后发现Vector的问题,其他问题暂未发现

注意点1: 它只有在 OnCreatedOnRefresh才会触发同步,也就是意味着后续同步,需要调用ForceRefreshSendBuffRefreshToClients进行刷新来触发同步

注意点2: 客户端也需要调用SetHasCustomTransmitterData,否则不会同步