最近在尝试用unet做一个局域网游戏,游戏的核心概念在于玩家之间的发现和隐蔽,有个类似于战争迷雾的机制。

实现该机制最关键的是实现可视性检查。首先是unet中默认的一个可视性检查,由组件NetworkProximityChecker实现。其具体原理在 https://docs.unity3d.com/Manual/UNetVisibility.html 中有详细叙述,简单地说就是:

所有的networkIdentity都有一个观察者observer列表
在运行后的inspector下可以看到
值得注意的是,observer列表里保存的是player的gameobject。

这个observer列表表示,该物体被哪些networkConnection可见,对于不可见的networkConnection,server不会去做类似同步syncVar、或者调用clientRPC之类的操作。

按照文档的说法,这个observer列表会在两种情况下更新:

第一种情况:
在一个client被设置成ready之后,要对所有的network gameobject检查client能否看到它。该gameobject下的所有的networkBehaviour里的OnCheckObserver(NetworkConnection)会被调用,返回false表示该NetworkConnection看不到该gameobject。

第二种情况:
1.一个network gameobject在server上被spawn,要对所有的networkConnection检查能否看到该gameobject。
2.该gameobject中的,NetworkIdentity的RebuildObservers()方法被调用。需要重建Observers,该函数会调用同gameobject中的networkbehaviour中的onRebuildObservers
3.该方法签名如下
public override bool OnRebuildObservers(HashSet observers, bool initial);
实现者通过填充observers来表示哪些networkConnection对该gameobject可见。

注意两种方式的根本区别:第一种方式是一个新NetworkConnection进入后(client ready后),所有的network gameobject进行一次检查。第二种是一个network gameobject被创建后,所有的NetworkConnection做一次检查。

NetworkProximityChecker override了OnCheckObserver和OnRebuildObservers两个方法,通过检查距离实现检查。为了可见性能够刷新,同时在Update里定期调用NetworkIdentity的RebuildObservers方法。

以上是observer列表构建的一些事项。

之后,server会根据每个物体observers表的变化来对新增或者删除的networkConnection发送消息。比较麻烦的是在host上和client上的行为是不同的。

在client上,当一个物体可见性改变时,会收到来自服务器的消息。要注意的是,这个消息和在服务器上直接删除、创建物体时发送给客户端的消息是一模一样的。

而在host上,因为host本身的scene就是server的scene,不能直接把物体删除(不然就真没了)。因此需要另外实现行为。networkBehaviour提供了一个虚函数OnSetLocalVisibility(bool),这个函数只有在host上,失去或获得一个物体的可见性时被调用。在NetworkProximityChecker中实现的是把Renderer全部禁用或者启用,就实现了看不见的效果。不过因为UI的Canvas继承自Monobehaviour,消失时是不会被禁用的,如果要禁用的话需要自己实现一个component并且override OnSetLocalVisisbility。

unet中可视性检查的一些笔记的更多相关文章

  1. MySQL中Procedure事务编写基础笔记

    原文:MySQL中Procedure事务编写基础笔记 目录: 一.PROCEDURE: 二.CREATE PROCEDURE基本语法: 三.PROCEDURE小进阶   3.1.基本的DECLARE语 ...

  2. RSYNC在zabbix中的检查

      RSYNC在zabbix中的检查 作者:高波 归档:学习笔记 2017/08/21 快捷键: Ctrl + 1    标题1 Ctrl + 2    标题2 Ctrl + 3    标题3 Ctr ...

  3. 浏览器中js执行机制学习笔记

    浏览器中js执行机制学习笔记 RiverSouthMan关注 0.0772019.05.15 20:56:37字数 872阅读 291 同步任务 当一个脚本第一次执行的时候,js引擎会解析这段代码,并 ...

  4. jquery中关于append()的用法笔记---append()节点移动与复制之说

    jquery中关于append()的用法笔记---append()节点移动与复制之说 今天看一本关于jquery的基础教程,看到其中一段代码关于append()的一行,总是百思不得其解.于是查了查官方 ...

  5. SQL中如何检查死锁

    SQL中如何检查死锁 编写人:CC阿爸 2014-6-15 在日常SQL数据库的操作中,SQL偶尔会出现表被死锁的问题.比如: 在执行事务时,突然中止事务.系统肯定会锁表. 大批量数据操作时,由于网络 ...

  6. JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

    前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...

  7. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  8. 安全运维中基线检查的自动化之ansible工具巧用

    i春秋作家:yanzm 原文来自:安全运维中基线检查的自动化之ansible工具巧用 前几周斗哥分享了基线检查获取数据的脚本,但是在面对上百台的服务器,每台服务器上都跑一遍脚本那工作量可想而知,而且都 ...

  9. 第63节:Java中的Spring MVC简介笔记

    前言 感谢! 承蒙关照~ Java中的Spring MVC简介笔记 MVC简介 Spring MVC 基本概念 Spring MVC 项目搭建 maven 使用Spring MVC进行开发 实现数据绑 ...

随机推荐

  1. 使用TFS需要注意的地方

    1. 用管理员添加了本地映射,然后用其他用户就添加不了映射,一定要先用管理员账户去把映射 删除掉: 2. 在正式使用TFS时,一定需要在VS工具的设置里面,设置一下,签出时自动获取最新的代码.(默认是 ...

  2. Github上的1000多本免费电子书重磅来袭!

    Github上的1000多本免费电子书重磅来袭!   以前 StackOverFlow 也给出了一个免费电子书列表,现在在Github上可以看到时刻保持更新的列表了. 瞥一眼下面的书籍分类目录,你就能 ...

  3. Objective-C反射机制

    oc反射机制有三个用途: 1.获得Class Class LoginViewController = NSClassFromString(@"LoginViewController" ...

  4. (原)编写JAVA工具之json自动封装成pojo

    代码在最后 我个人是不太喜欢http和json,可能是游戏做的多了的原因的,对通信协议和通信方式特敏感,因此即使是做应用我也会选择rpc而非http,但是有时候因为各种原因,还是不的不处理标准的htt ...

  5. 『AngularJS』ngValue

    原文 描述 绑定给定的表达式到input[select]或input[radio]的值,以便当这个元素被选中的时候,设置这个元素的ngModel到绑定的值.当需要使用ng-repeat来动态生成rad ...

  6. spring多个定时任务quartz配置

    spring多个定时任务quartz配置 <?xml version=”1.0″ encoding=”UTF-8″?> <beans xmlns=”http://www.spring ...

  7. java正则表达式2 -- 匹配、切割、查找

    import java.util.Arrays; /* 正则表达式的作用: 1 匹配 2 切割 3 替换 * */ public class Demo1 { public static void ma ...

  8. javascript实现自动切换焦点功能学习

    当用户在表单中填写完当前字段后,能否自动将焦点跳转到下一个字段以方便用户输入? 为了增强易用性,加快数据输入的速度,可以在前一个文本框中的字符达到一定的设置的字符长度后(比如电话号码,身份证号等),用 ...

  9. 解决Mysql错误Too many connections的方法

    MySQL数据库 Too many connections出现这种错误明显就是 mysql_connect 之后忘记 mysql_close:当大量的connect之后,就会出现Too many co ...

  10. Python执行Linux系统命令的4种方法

    http://www.jb51.net/article/56490.htm (1) os.system 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 复制代码代码如下: system( ...