对象所有权
简介
在 VRChat 中,每个网络 GameObject 都有一个所有者。所有权决定了哪个玩家可以修改和更新网络对象。理解和管理所有权对于在实例中的所有玩家 之间正确同步对象至关重要。
工作原理
- 第一个加入实例的玩家默认成为所有网络对象的拥有者。
- 所有权可以动态地从一个人转移到另一个人。
- 只有网络对象的拥有者才能修改其同步的 Udon 变量。
- 如果拥有者离开实例,VRChat 会自动分配新的拥有者。
转移所有权
你可以使用 Udon 转移对象的所有权:
Networking.SetOwner(VRCPlayerApi player, GameObject obj);
示例:更改对象所有权
如果你希望玩家在交互时取得对象的所有权:
public override void Interact()
{
Networking.SetOwner(Networking.LocalPlayer, gameObject);
}
在此函数运行后,本地玩家将成为对象的新拥有者。
所有权事件
VRChat 提供两个与所有权相关的关键事件:
OnOwnershipRequest
此事件在所有权转移之前调用,允许你批准或拒绝请求。
public override bool OnOwnershipRequest(VRCPlayerApi requestingPlayer, VRCPlayerApi newOwner)
{
return true; // 批准转移
}
OnOwnershipTransferred
当对象的所有权更改时触发。你可以使用此事件在所有权转移时更新 UI 元素或其他行为。
public override void OnOwnershipTransferred(VRCPlayerApi newOwner)
{
Debug.Log($"新拥有者: {newOwner.displayName}");
}
转移事件图
下图显示事件的顺序,以便你了解成功转移对象所有权的步骤。
实例主控者
实例主控者是拥有任何从未手动设置或转移所有权的对象的玩家。你可以通过 VRCPlayerApi.isMaster 检查玩家是否为主控者。
玩家是否为实例主控者不应用于限制对世界某些功能的访问。为此,请考虑使用"实例拥有者"。
主控者选择遵循以下规则:
- 实例中始终有一个有效的主控者。
- 第一个进入先前为空实例的玩家将成为初始主控者。
- 当前主控者离开实例时,主控者会更改。
- 如果主控者在 Android 上且将 VRChat 置于后台太久,主控者也可能会更改。
- 当当前主控者离开时,在调用
OnPlayerLeft之前,会从实例中的其他玩家中选择一个新的主控者。 - 你不能依赖任何特定玩家成为主控者。新主控者将根据服务器端的各种标准(平台、网络条件等)进行选择。
这些是 VRChat 目前对网络主控者行为做出的唯一保证。任何其他观察到的行为都可能发生变化。
尽可能不要依赖主控者!
建议对网络逻辑使用所有权检查而不是检查实例主控者。 在某些情况下,主控者可能在一段时间内无响应,在此期间事件可能无法执行。
最佳实践
- 如果你希望玩家能够更改对象上的变量,请务必先检查或请求所有权。
- 确保与所有权相关的逻辑考虑到玩家断线和后来加入者。
- 尽可能避免依赖实例主控者——使用正确的所有权处理方式。
下一步
有关更多详细信息,请探索这些网络主题: