UE网络-WithNetSharedSerializer详解
WithNetSharedSerialization是什么
在进行属性同步时, 每当一个属性发生变化都要发给关心该属性的所有Connection, 如果这些Connection共享一份, 那就可以节省很多内存, 序列化等时间.
一般与WithNetSerializer
组合使用.
自定义结构体指定WithNetSharedSerialization
1 | USTRUCT() |
将WithNetSharedSerialization
映射到EStructFlags::STRUCT_NetSharedSerialization
构建UScriptStruct
在PreInit时候,构建UScriptStruct
将WithNetSharedSerialization
属性映射到EStructFlags::STRUCT_NetSharedSerialization
构建UScriptStruct, 通过模板, 指定WithNetSharedSerialization属性.
好了, 到此为止, 已经将我们指定的WithNetSharedSerialization映射到EStructFlags::STRUCT_NetSharedSerialization上了. 即UScriptStruct.StructFlags已经包含EStructFlags::STRUCT_NetSharedSerialization属性.
将EStructFlags::STRUCT_NetSharedSerialization映射到ERepLayoutCmdFlags::IsSharedSerialization
在创建RepLayout时(例如:FRepLayout::InitFromClass), 设置RepStruct信息.
Struct类型为:FStructProperty
检测Struct->StructFlags是否包含STRUCT_NetSharedSerialization属性:
这样, 就将STRUCT_NetSharedSerialization属性映射成IsSharedSerialization, 并存储在Cmd.Flags中.
使用WithNetSharedSerialization
通过1-4,已经将WithNetSharedSerialization->EStructFlags::STRUCT_NetSharedSerialization->ERepLayoutCmdFlags::IsSharedSerialization的转化讲清楚了, 并最终存储在Cmd.Flags中. 这里所说的使用WithNetSharedSerialization其实包括EStructFlags::STRUCT_NetSharedSerialization和ERepLayoutCmdFlags::IsSharedSerialization的使用.
在序列化时候, 优先处理SharedSerialization属性
1 | //序列化流程 |
都是在需要序列化时候, 优先构建SharedSerialization属性, 比如发送RPC和属性同步.
一个结构体标记为WithNetSharedSerialization, 会进行SharedSerialization吗?
不会. 为什么呢?
只有在FRepLayout.Cmds中的属性, 才会去判断是否为IsSharedSerialization
一般情况下, 单独将结构体标记为WithNetSharedSerialization不会有任何效果, 因为该结构体在构建Replayout时候会被分割成具体的一个个基础类型(float,int, byte等), 在检测是否IsSharedSerialization时候, 该属性就丢失了.
那么怎么才能不解析一个结构体, 将该结构体作为一个基础类型放入Cmd中呢?
标记为:WithNetSerializer就不会进行分割, 然后整体放入Cmd中.
官方示例:
自己实现的实例:
结果: