Skip to main content

对象所有权

简介​

在 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 目前对网络主控者行为做出的唯一保证。任何其他观察到的行为都可能发生变化。

尽可能不要依赖主控者!

建议对网络逻辑使用所有权检查而不是检查实例主控者。 在某些情况下,主控者可能在一段时间内无响应,在此期间事件可能无法执行。

最佳实践​

  • 如果你希望玩家能够更改对象上的变量,请务必先检查或请求所有权。
  • 确保与所有权相关的逻辑考虑到玩家断线和后来加入者。
  • 尽可能避免依赖实例主控者——使用正确的所有权处理方式。

下一步​

有关更多详细信息,请探索这些网络主题: