[Unity Mirror] Custom Interest Management

81 篇文章 31 订阅

英文原文:

https://mirror-networking.gitbook.io/docs/interest-management/custom

自定义兴趣管理

Mirror 允许您实施自定义兴趣管理解决方案。例如:

  • 基于 Raycast,因此 DotA 玩家看不到墙后或灌木丛中的其他玩家
  • Counter-Strike 类游戏的预测性光线投射。 穿墙外挂显示玩家在墙后。您可以创建一个自定义兴趣管理系统,仅在敌人从墙后弹出前不久将其发送给玩家。在第一人称射击游戏中,玩家移动速度很快,所以你仍然需要在他们变得可见之前发送他们几毫秒。

以上所有自定义解决方案都可以在 Mirror 中实现。要了解如何实施兴趣管理,让我们一步一步来。

脚本模板

  Mirror 包括用于自定义兴趣管理的脚本模板。它完全注释了所有已经为您存根的虚拟方法覆盖。如果您之前使用过我们的旧版兴趣管理系统,那么这些应该看起来很熟悉。

  • OnCheckObserver 当有人生成时调用。如果 ‘newObserver’ 可以看到 ‘identity’,则返回 true
  • OnRebuildObservers 为给定的网络身份重建观察者。结果存储在 newObservers 中。
    • Mirror 会在内部自动将 newObservers 放入 identity.observers 中。我们不直接这样做,因为它比添加/删除要复杂一些。Mirror管理它。没什么可担心的 :)
  • RebuildAll 是一个帮助函数,用于重建每个生成的网络身份的观察者。
    • 实现可能希望在每个间隔都调用它。

距离示例

  距离兴趣管理是最简单、直接的实施。让我们通过它来了解如何从抽象的 InterestManagement 类继承。

public class DistanceInterestManagement : InterestManagement
{
    [Tooltip("对象可见的最大范围.")]
    public int visRange = 10;

    [Tooltip("每隔“rebuildInterval”秒重建所有.")]
    public float rebuildInterval = 1;
    double lastRebuildTime;

    public override bool OnCheckObserver(NetworkIdentity identity, NetworkConnection newObserver)
    {
        return Vector3.Distance(identity.transform.position, newObserver.identity.transform.position) <= visRange;
    }

    public override void OnRebuildObservers(NetworkIdentity identity, HashSet<NetworkConnection> newObservers, bool initialize)
    {
        Vector3 position = identity.transform.position;
        
        // 对于每个连接
        foreach (NetworkConnectionToClient conn in NetworkServer.connections.Values)
            // 如果通过身份验证并加入世界
            if (conn != null && conn.isAuthenticated && conn.identity != null)
                // 检查距离我们的“身份”
                if (Vector3.Distance(conn.identity.transform.position, position) < visRange)
                    // 添加到结果
                    newObservers.Add(conn);
    }

    [ServerCallback]
    void Update()
    {
        // 每隔一段时间重建所有生成的 NetworkIdentity 的观察者
        if (NetworkTime.time >= lastRebuildTime + rebuildInterval)
        {
            RebuildAll();
            lastRebuildTime = NetworkTime.time;
        }
    }
}

这不是太复杂,是吗?

  • OnCheckObserver 只是比较新生成的身份和连接之间的距离。一个连接有一个主玩家,这就是我们在这里用于距离检查的东西。

    • 请注意,您还可以检查连接拥有的每个对象。例如,如果 Bob 生成并且 Alice 离得不够近,Alice 的宠物可能离得足够近,因此 Alice 和 Bob 应该仍然可以看到对方,尽管有点超出正常范围。
  • OnRebuildObservers 的工作是返回可以看到我们网络身份的网络连接的 HashSet。很明显,我们只是迭代所有 NetworkServer.connections 并检查他们的主要玩家与我们的网络身份的距离。

    • 请注意,我们只检查那些经过身份验证并且在世界上有玩家的人。仍在登录或选择字符的连接不应该观察到任何东西。
  • Update 的工作是不时地实际调用 RebuildAll()。如果我们不调用 RebuildAll(),那么 Mirror 将永远不会重建观察者。

主机模式可见性

在主机模式下,有人一边运行服务器一边自己玩,所以你可能会想:

  • 我是服务器。服务器看到每个人。因此,我应该看到每个人。

  这在技术上是正确的,但如果你有幸参加过局域网聚会,那么你会有不同的记忆:

在这里插入图片描述
  例如,LAN 上的某个人主持 Counter-Strike 或 DotA 游戏。让我们考虑一下这个案例:

  • 主机运行服务器。服务器将整个世界状态保存在内存中,而主机玩家只能看到他周围的世界。

  这个想法是让主机玩家成为游戏中的常规玩家。如果您玩 DotA / Counter Strike 并且主持人总是看到其他人的位置,那么局域网聚会不会很有趣,对吗?

显然,Host可以作弊。如果你在局域网上作弊,那么你需要专业的帮助。

  Mirror 有一个虚拟方法 SetHostVisibility(NetworkIdentity, bool) 可以在主机模式下启用/禁用渲染器。换句话说,世界状态仍然存在——Host 玩家只是看不到它。您可以在自定义系统中覆盖它以满足您的需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值