FiveM 状态包指南:无事件同步数据
掌握 FiveM 状态包,实现轻松的客户端-服务器同步。复制值、变更处理器、过滤器及状态包优于经典事件的场景。
Agency Scripts
Agency Scripts 创始人兼首席开发者
什么是 State Bags?
状态袋是 FiveM 内置功能,用于在服务器和客户端间同步数据,无需编写自定义事件处理器。它们提供附加于实体、玩家或全局状态的键值存储,自动跨网络复制更改。服务器在玩家状态袋设置值时,所有需要该信息的客户端自动接收。替代了手动触发事件同步数据的常见模式,大幅减少样板代码。
玩家状态包
每个连接的玩家都有一个可通过访问的状态包 Player(source).state 在服务器端和 LocalPlayer.state 在客户端。您可以在玩家状态上设置任意键值对,自动同步到相关客户端。非常适合值班状态、职位、帮派归属或其他玩家或资源需读取的自定义状态指示。为安全起见在服务器端设置值,客户端读取以渲染UI元素或根据玩家状态调整行为。
实体状态包
除了玩家,FiveM中每个网络实体都可以附加状态包数据。访问实体状态使用 Entity(entityHandle).state 同时在客户端和服务器端使用。这对于存储车辆的元数据如燃油量、锁定状态或所有权非常有用,无需维护单独的跟踪表。当玩家接近车辆时,客户端可读取其状态包,在HUD上显示燃油量,无需向服务器请求数据。实体状态包在实体存在期间持续,实体移除时自动清理。
全局状态
GlobalState 是一个跨整个服务器和所有客户端共享的状态包。用于服务器范围的设置,如天气、时间、事件标志或经济修正。服务器设置时 GlobalState.weather = 'rain',每个连接的客户端都会收到此更新并相应反应。这比向所有玩家广播事件更高效,因为状态包自动处理新玩家连接。中途加入的玩家会立即接收当前全局状态,无需单独同步事件。
状态袋处理器
您可以通过注册处理程序来响应状态包更改,使用 AddStateBagChangeHandler此函数接受键过滤器、背包过滤器和一个在指定状态变化时触发的回调。处理程序接收背包名称、键、值及其他元数据。使用处理程序在玩家上班时触发视觉效果,更新库存数据时刷新UI,或记录状态修改以便调试。处理程序可在客户端和服务器端工作,赋予您处理状态更新的灵活性。
最佳实践与限制
状态袋不适合高频更新。设置状态袋值会触发网络同步,避免每帧更新。用于偶尔变化的数据,如状态标志、配置值和元数据,而非持续变化的值如位置或速度。保持存储值小且可序列化,因为它们通过网络传输。需要复杂对象时,将其扁平化为简单键值对或使用 JSON 字符串。数据需权威时,始终从服务器设置状态,防止客户端篡改。