Skip to main content

Contacts(联系人)

Contacts 是一个允许化身和世界检测与其他联系人碰撞的系统。你可以使用碰撞来驱动化身和世界的行为,以执行各种自定义交互。

这些与标准的 Unity 碰撞体是分开的。联系人分为发送器和接收器。发送器仅用于被检测。接收器检测发送器,然后相应地更新参数或触发事件。

在化身上使用联系人时,使用的联系人数量将影响其性能等级。

VRCContactSender​

Contact Sender 组件定义一个空间体积,在与 Contact Receiver 接触时发送联系人信号。

  • Root Transform - 此联系人放置的变换。如果为空,则使用此游戏对象的变换。

形状​

此部分包含定义 ContactSender 形状的设置。

  • Shape Type(形状类型) - 此联系人使用的碰撞形状类型。你可以在 Sphere、Capsule 和 Box 之间选择。
  • Radius(半径) - 从原点延伸的碰撞体大小。仅在形状类型设置为 Sphere 或 Capsule 时使用。
  • Height(高度) - 胶囊沿 Y 轴的高度,包括两端的一半球体。仅在形状类型设置为 Capsule 时使用。
  • Size(大小) - 盒状碰撞体沿每个轴的大小。仅在形状类型设置为 Box 时使用。
  • Position(位置) - 从根变换的位置偏移。
  • Rotation(旋转) - 从根变换的旋转偏移。

联系人形状限制为最大半径 3 米,最大宽度/高度/深度 6 米。如果联系人附加到已缩放的游戏对象上,这些限制将在缩放后应用。

过滤​

此部分包含允许你调整和定义此 ContactSender 如何与 ContactReceivers 交互的设置。

  • Local Only(仅本地) - 仅适用于化身上的 Contact Senders。将此联系人限制为仅在本地客户端上工作。如果启用,该联系人不会降低你的化身的性能等级。
  • Content Types(内容类型) - 仅适用于世界中的 Contact Senders。允许你设置此 Contact Sender 是否触发世界、化身和/或物品中的 Contact Receivers。
  • Collision Tags(碰撞标签) - 指定它可以影响/被什么影响的字符串列表。要成功发生碰撞,发送器和接收器需要至少一对匹配的字符串。碰撞标签区分大小写。一个联系人最多可以有 16 个标签。

例如,下面的标签将使 Sender 在与默认的 Head ContactReceiver 或任何带有 Face 标签的自定义 ContactReceiver 接触时发送联系人信号——注意大写字母 F!

你可以使用任何你想要的文本作为标签,但 SDK 也提供了一系列建议标签,你可以使用这些标签来更轻松地创建与不是你制作的化身和世界兼容的联系人系统。更多信息请参见内置联系人标签。

如果你决定使用自定义碰撞标签,建议使用帕斯卡命名法(PascalCase)编写,以匹配内置标签的格式。

标准碰撞体​

在化身上,一组"标准碰撞体"在 Avatar Descriptor 的"Colliders"部分中定义。此部分允许你定义在每个化身上存在的一些标准碰撞体。如果你不进行修改,它们将自动设置,但也可以进行调整以精确适配你的化身。这些碰撞体不影响性能等级。

  • 头部(Head)
  • 躯干(Torso)
  • 手部 L/R(Hands L/R)
  • 脚部 L/R(Feet L/R)
  • 手指 L/R(Fingers L/R)
    • 食指(Index)
    • 中指(Middle)
    • 无名指(Ring)
    • 小指(Little)

这些碰撞体主要作为 Contact Senders 使用内置身体部位标签,其他人可以使用他们的化身进行检测。但是,手指和手部碰撞体也用于创建全局 PhysBone 碰撞体,可用于影响他人的 PhysBones 以及世界中的 PhysBones。

VRCContactReceiver​

Contact Receiver 组件定义一个空间体积,在与 Contact Sender 接触时将接收联系人信号。

  • Root Transform - 此联系人放置的变换。如果为空,则使用此游戏对象的变换。

当 Contact Receiver 从 Contact Sender 接收到信号时发生的情况取决于 Contact Receiver 所属的对象:

  • 如果 Contact Receiver 是化身的一部分,它会按照化身作者定义的方式设置动画参数。
  • 如果 Contact Receiver 是世界的一部分,它会在所有附加到与 Receiver 相同游戏对象的 Udon 行为上触发以下事件之一:
    • OnContactEnter(ContactEnterInfo contactInfo) - 当 Contact Sender 开始接触 Contact Receiver 时引发的事件。
    • OnContactExit(ContactExitInfo info) - 当 Contact Sender 停止接触 Contact Receiver 时引发的事件。

形状​

此部分包含定义 ContactReceiver 形状的设置。

  • Shape Type(形状类型) - 此联系人使用的碰撞形状类型。你可以在 Sphere、Capsule 和 Box 之间选择。
  • Radius(半径) - 从原点延伸的碰撞体大小。仅在形状类型设置为 Sphere 或 Capsule 时使用。
  • Height(高度) - 胶囊沿 Y 轴的高度,包括两端的一半球体。仅在形状类型设置为 Capsule 时使用。
  • Size(大小) - 盒状碰撞体沿每个轴的大小。仅在形状类型设置为 Box 时使用。
  • Position(位置) - 从根变换的位置偏移。
  • Rotation(旋转) - 从根变换的旋转偏移。

联系人形状限制为最大半径 3 米,最大宽度/高度/深度 6 米。如果联系人附加到已缩放的游戏对象上,这些限制将在缩放后应用。

过滤​

此部分包含允许你调整和定义此 ContactReceiver 如何与 ContactSenders 交互的设置。

  • Allow Self(允许自身) - 仅适用于化身上的 Contact Receivers。允许此联系人受自身影响。
  • Allow Others(允许他人) - 仅适用于化身上的 Contact Receivers。允许此联系人受他人影响。
  • Local Only(仅本地) - 仅适用于化身上的 Contact Receivers。将此联系人限制为仅在本地客户端上工作。如果启用,该联系人不会降低你的化身的性能等级。
    • 启用此选项后,你可以在单个化身上使用多达 256 个联系人组件。如果超过此限制,你将无法上传化身。
  • Content Types(内容类型) - 仅适用于世界中的 Contact Receivers。允许你设置此 Contact Receiver 是否触发世界、化身和/或物品中的 Contact Receivers。
  • Collision Tags(碰撞标签) - 指定它可以影响/被什么影响的字符串列表。要成功发生碰撞,发送器和接收器需要至少一对匹配的字符串。碰撞标签区分大小写。一个联系人最多可以有 16 个标签。

接收器​

此部分包含定义 Receiver 在接收到信号时执行的操作的设置。

化身中的接收器​

在化身上使用时,Contact Receiver 将通过设置化身动画控制器中的动画参数来响应联系人信号。

Receiver Type(接收器类型)定义了接收到信号时参数设置的行为。

  • Constant(常量) - 在任何联系人存在时通知你。未检测到联系人时重置。理想情况下,在此使用布尔参数。对于 Float 设置为 1.0,对于 Bool 设置为 True,对于 Int 设置为 1。
  • OnEnter(进入时) - 在检测到联系人的帧通知你。下一帧立即重置。理想情况下,在此使用布尔参数。对于 Float 设置为 1.0,对于 Bool 设置为 True,对于 Int 设置为 1。可以选择定义 Min Velocity(最小速度)。
  • Proximity(接近度) - 根据联系人距离触发器的远近,给你一个 0.0-1.0 的 Float 值。必须使用 Float 类型。如果检测到多个联系人,它将给出最近的那个。
  • Parameter(参数) - 在动画控制器上更新的参数。此参数不需要在同步的化身参数列表中定义。根据使用的接收器类型,参数可以是 Float、Bool 或 Int。
  • Value(值) - 检测到碰撞时参数更新到的值。没有碰撞时参数将重置为零。
  • Min Velocity(最小速度) - 传入碰撞体影响此触发器所需的最小速度,仅在 OnEnter 类型中激活。

接近度值告诉你联系人距离触发器中心有多近。计算方式为发送器到接收器的最近点。

对于盒状 Contact Receivers,你可以启用 Use Face Proximity(使用面接近度)选项。此选项更改接近度计算,告诉你联系人距离盒子的正 Z 面有多近。

世界中的接收器​

世界中的 Contact Receiver 组件除了配置盒状 Contact Receivers 的接近度计算方式(见上文)外,没有其他配置选项。

相反,Receivers 始终通过调用附加到与 Receiver 相同游戏对象的任何 Udon 脚本中的事件来响应联系人信号。有关使用 Udon 与联系人交互的更多信息,请参见下方部分。

世界中的 Udon 访问​

  • 你可以使用类型 VRCContactSender 和 VRCContactReceiver 分别创建引用世界中 Contact Sender 和 Contact Receiver 的字段和变量。这两个类都在命名空间 VRC.SDK3.Dynamics.Contact.Components 中。ContactEnterInfo 和 ContactExitInfo 参数类型在命名空间 VRC.Dynamics 中。
  • 要检测 Contact Sender 和 Contact Receiver 何时接触,你可以将 UdonGraph 或 UdonSharp 行为附加到与 Contact Receiver 组件相同的游戏对象上,并使用以下事件:
    • OnContactEnter(ContactEnterInfo contactInfo) - 当 Contact Sender 开始接触 Contact Receiver 时调用。参数是一个包含以下联系人信息的数据结构:
      • ContactSenderProxy contactSender - 对此碰撞中涉及的 Contact Sender 组件的引用。
      • ContactReceiverProxy contactReceiver - 对此碰撞中涉及的 Contact Receiver 组件的引用。
      • Vector3 enterVelocity - Contact Sender 相对于 Contact Receiver 在接触点的相对速度。
      • Vector3 contactPoint - Contact Receiver 表面上估计的接触点,在世界空间中。
      • string[] matchingTags - Contact Sender 和 Contact Receiver 共有的标签数组。
    • OnContactExit(ContactExitInfo contactInfo) - 当 Contact Sender 停止接触 Contact Receiver 时调用。与进入事件一样,参数是一个包含碰撞信息的数据结构:
      • ContactSenderProxy contactSender - 对此碰撞中涉及的 Contact Sender 组件的引用。
      • ContactReceiverProxy contactReceiver - 对此碰撞中涉及的 Contact Receiver 组件的引用。
      • string[] matchingTags - Contact Sender 和 Contact Receiver 共有的标签数组。
  • 在上述每个事件中,contactSender 和 contactReceiver 是引用碰撞中涉及的 Contact Sender 和 Contact Receiver 的代理对象。你可以通过使用 == 或 != 比较两个对象来检查它们是否与世界中的 VRCContactSender 或 VRCContactReceiver 匹配。代理对象本身包含以下属性:
    • bool isValid - 如果此代理对象引用有效的联系人组件,则为 true,否则为 false。在访问任何其他属性之前,应检查此值是否为 true。
    • VRCPlayerApi player - 对拥有联系人组件的玩家的引用(如果适用)。对于世界中的联系人组件,此值为 null。
    • DynamicsUsage usage - 描述联系人组件所属的内容类型。对于属于世界一部分的任何联系人,这将为 World;对于属于化身一部分的任何联系人,这将为 Avatar。
    • Vector3 position - 联系人组件根变换的世界空间位置。
    • Quaternion rotation - 联系人组件根变换的世界空间旋转。
    • Vector3 scale - 联系人组件根变换的损失缩放。
  • 你可以通过获取和设置字段来读取和设置 Contact Sender 或 Contact Receiver 的 radius、height、size、position 和 rotation 属性。
    • 如果你更改了这些属性,必须在完成所有更改后在 Contact 上调用 ApplyConfigurationChanges(),否则更改将不会实际应用到 Contact。
    • Contact 的配置更改可能会很昂贵! 如果过度使用,可能会导致性能问题,使你的世界让玩家感到不适——避免过于频繁地更改这些属性,并尽量在应用之前将尽可能多的更改批量处理。
  • 在任何时候,你都可以使用 Receiver 上的 CalculateProximity() 方法计算 Receiver 和 Sender 之间的接近度。这将返回一个 0.0-1.0 的 Float 值,表示 Sender 距离 Receiver 中心(如果 Receiver 是启用了 Use Face Proximity 的盒状,则距离 Receiver 的正 Z 面)有多近。
  • 你可以使用 UpdateContentTypes(DynamicsUsageFlags newContentTypes) 和 UpdateCollisionTags(string[] newCollisionTags) 方法更改 Contact 允许的内容类型和碰撞标签集。
    • 请记住,Contact 有 16 个标签的硬性限制。如果你尝试设置超过 16 个标签,只有前 16 个会生效。