Replicate(网络复制),ActorRole(角色),Ownership(所有权)以及RPC(远程调用)等等
I. Replication
Replication指的是 从服务端向客户端 传递数据和信息的行为。注意是单向的,不会从客户端传递信息和数据到服务端。
假设一个Actor被设置为Replicates, 当且仅当它被服务端生成 ,那么它会被所有客户端生成,并被Replicated。言外之意,即使是Replicates的Actor,如果在某个客户端生成,它也只会在本客户端生成,是 不会在其他客户端或者服务端生成 的,自然也谈不上Replication。
还有一种情况容易让人糊涂:假设在Pawn类中的Authority端生成一个Actor,并且把它存为变量,那么这个变量的Replicates属性和这个Actor本身的Replicates属性是什么关系?实际上,这里变量只是指向这个Actor的一个引用/指针,掌握住这点就好理解了。如果这个Actor没有Replicates,而让这个指针Replicates,那么它在客户端上就会指向一个NULL,这个并不会让引擎崩溃,但是没有任何意义。如果Actor Replicates,但是指针不是Replicated,那么在客户端这个Actor是存在的,但是指针没办法指向正确的对象。所以这种情况下需要Actor和变量都是Replicates(ed)才能达到正确的效果
另外,GameMode是不会Replicates的,它只存在于服务端,所以对它存储的变量设置Replicated没有任何意义。
那么再考虑一下,如果这个Actor在编辑阶段就被置于场景中呢,它在多人联网的情形下是什么状况?
我做了以下几个实验来逐步分析:
(以下实验如无特殊说明,均采用默认的第三人称场景,Play选项Number of Players选择2,New Editor Window(PIE))
实验1:Actor不勾选Replicates,直接放置于场景中,初始一个随机速度运动
结果:客户端和服务端都各自以各自的速度运动,证明这两个物体在不同的instance上是独立的,互无关联的。
实验2:Actor勾选Replicates,但不勾选Replicate Movement,直接放置于场景中,初始一个随机速度运动
结果:和实验1一样。那么大家可能就会怀疑,这种情况下是不是和实验1是完全一样的?实际上和实验1有很大的区别,这个Actor有了Replication,也就可以进行属性的Replicates和RPC调用,而实验1里的Actor就不可能进行这些操作。
实验3:Actor勾选Replicates,勾选Replicate Movement,直接放置于场景中,初始一个随机速度运动
结果:虽然初始化了不同的速度(print出来了),但是服务端和客户端运动基本上是同步的,只是客户端的运动会有些许“抖动”。出现这种情况的原因是客户端“想”以自己的速度去运动,但是由于更新了Replicate Movement,服务端会以固定的频率去把自身的位置同步给客户端,因此客户端会在更新的瞬间跳跃到服务器指定的位置,从而产生了抖动。
放置于场景中的Actor的情况我们搞清楚了,再来考虑一下更麻烦的——动态生成:
实验4:我们先在LevelBlueprint的BeginPlay中直接生成Actor,这个Actor是实验2的,也就是Actor勾选了Replicate,但并不同步移动。
结果:服务端有一个Actor,客户端有2个Actor,并且3个Actor均以不同的速度在运动。不难理解,因为在LevelBP中生成,所以服务端生成了一个,但是这个Actor是Replicates的,所以被复制到客户端,同时客户端本身的LevelBP中也生成了一个,所以客户端有两个。
所以如果要在LevelBlueprint中生成Replicates的Actor,一定要在前面加上Switch has authority,并在Authority后面生成。
上述几个实验的工程源码存放在这里
II. Ownership
所谓“Own”(拥有)的主语其实是一个“连接”的实例或者PlayerController。
每个“连接”的实例肯定会Own(拥有)一个PlayerController
那么决定一个Actor是否被拥有,就是向上查找他的Ownership结构树,找到最上层的拥有者,如果是个PlayerController,它就被这个PlayerController以及它的“连接”所拥有。
最典型的的例子,一个Pawn被PlayerController Possess的时候它就被Owned。如果它被Unposses了,Ownership也就丢失了。
那么一个普通的Actor能不能被“拥有”呢?答案是可以的,使用Set Owner方法就可以让他被某个PlayerController拥有。
为什么要强调Ownership呢?
- 后面我们将描述这个问题:RPC需要决定在哪个客户端执行 Run on Client的 RPC
- Actor网络复制和连接的Rlevancy(相关性)
- 牵扯到Owner时候的property Replication条件
III. Actor Role 和 Remote Role
Actor Role在我的 这篇文章里已经很详细的描述过了,这里做一下补充:
Actor Role 和 Remote Role是一组相对的概念,Actor Role指的是在本地的角色,Remote Role指的是远程端的角色。这里的“远程端”有点tricky,容易误解,我也是糊涂了很久才明白。
设想有一个服务端加两个或两个以上的客户端,那么所谓的“远程端”到底指的是在哪个“端”?实际上我们只需要分两个“端”,一个服务端,一个客户端,把所有的客户端都看成一端,这个问题的答案就很显而易见了。
另外 官方文档专门说明了, “目前,仅服务端可以负责同步信息到客户端,因此仅服务端可以看到Role=Authority,并且RemoteRole=Simulated_Proxy或者Autonomous_Proxy”,这个“目前”说的是目前的网络构架。
总之,只有服务端才可能有Authority,所有Replicates的Actor在服务端的Role都是Authority,要牢记这点。(非Replciates的有没有Authority?有待验证)
实际上,Simulated_Proxy和Autonomous_Proxy讲的是两种同步模式(Mode of Replication),因为服务器不可能每一帧都去把信息同步给所有客户端,而是以一定的频率去下发信息,那么两次下发之间的空白怎么填补呢?虚幻设计了两种同步的模式:
Simulated_Proxy是标准模式,用最后的速度和位置去移动物体.(使用最后的速度只是一种算法,你也可以实施自己的算法)
Autonomous_Proxy基本上只会用于被PlayerController 所Possess的对象(那就是被Possess的Pawn啦),那么在空白期间就直接用用户的操作来填补。
看到这里,我们需要明确两点:
- Autonomous_Proxy就是Pawn(当然说的是被Possess的)在本客户端的Role——目前我能想到仅有这一种情况。它的RemoteRole——也就是在服务端的Role是Authority,它在其他客户端的Role是Simulated_Proxy。
- 而任何非Pawn的Actor,在服务端的Role都是Authority,他们的RemoteRole都是SimulatedProxy。
在C++中可以使用Role==XXX来判断一个Pawn的Role,但是在蓝图中我们可能需要分两步来进行:首先判断是否has authority,如果是,则是服务端,如果否,还要继续判断pawn是否isLocallyControlled,如果是,则是Autonomous_Proxy,如果否则是Simulated_Proxy。
IV. Actor Role和Ownership的关系
很重要的一点, Actor Role 和 Ownership没有任何关系 ,是不同的概念。
只是很巧合,Autonomous_Proxy肯定会被Own,但不能说被Own了就一定是Autonomous_Proxy,例如我们可以对一个非Pawn的Actor 设置所有者(Set Owner),但是它的Actor Role没有改变。
V. RPC
- RPC本质是用来调用在 另外一个游戏实例上的函数的 。
- RPC无法获取返回值 ,这就是为为什么没办法把蓝图中的Function设置为RPC的原因,因为Function是可以带返回值的。而CustomEvent是没法设置返回值的,所以RPC只能标记在CustomEvent上。
- RPC分三种,Run on Server,Run on owning Client,NetMulticast
- RPC必须在Actor或者其子类上调用
- Actor必须是Replicated的(否则不存在RPC一说)
1. Run on Server
表示在Actor的服务端实例上执行。
如果RPC是从客户端调用,让其在服务端执行,客户端必须 Own(拥有) 这个Actor。
2. Run on owning Client
表示在Actor的Owner上执行。
如果RPC是从服务端调用,让其在客户端执行,只有 Own(拥有) 这个Actor的客户端才会执行。
注意Run on Server和 Run on owning Client的条件:客户端必须Own这个Actor,也就是 这个Actor必须有Ownership 。
3. NetMulticast
表示在Actor的所有实例上执行。
如前所述,前两种RPC模式都要求Actor必须有Ownership。 Multicast是个例外,它不需要OwnerShip 。
如果从服务端调用,服务端会本地执行,所有目前连接的客户端也都会执行。
如果从客户端端执行,则只会本地执行,服务端不会执行,其他客户端也不会执行。

Replicate(网络复制),ActorRole(角色),Ownership(所有权)以及RPC(远程调用)等等的更多相关文章
- 8.9.网络编程_Socket 远程调用机制
1.网络编程 1.1.网络编程概述: 通过通信线路(有线或无线)可以把不同地理位置且相互独立的计算机连同其外部设备连接起来,组成计算机网络.在操作系统.网络管理软件及网络 通信协议的管理和协调下,可以 ...
- 廖雪峰Java13网络编程-3其他-2RMI远程调用
1.RMI远程调用: Remote Method Invocation 目的:把一个接口方法暴露给远程 示例: 定义一个接口Clock,它有一个方法能够获取当前的时间,并编写一个实现类,来实现这个接口 ...
- 网上常用免费webservice_查询(网络复制)
MP3在线搜索服务 地址:http://www.wopos.com/webservice/song.asmx 介绍: 使用: getMusicList()方法搜索MP3/WMA等音乐文件 多功能条形码 ...
- 小程序 js中获取时间new date()的用法(网络复制过来自用)
js中获取时间new date()的用法 获取时间: 1 var myDate = new Date();//获取系统当前时间 获取特定格式的时间: 1 myDate.getYear(); //获 ...
- sql高级主题资料(网络复制)
SQL Server 常用高级语法笔记 自从用了EF后很少写sql和存储过程了,今天需要写个比较复杂的报告,翻出了之前的笔记做参考,感觉这个笔记还是很有用的,因此发出来和大家分享. 1.case. ...
- [Socket网络编程]一个封锁操作被对 WSACancelBlockingCall 的调用中断。
原文地址:http://www.cnblogs.com/xiwang/archive/2012/10/25/2740114.html记录在此,方便查阅. C#中在使用UDPClient循环监听端口,在 ...
- Unity自带网络功能——NetworkView组件、Serialize、RPC
Unity拥有大量的第三方插件,专门提供了对网络功能的支持.可是,大部分开发人员第一次接触到的还是Unity自带的网络功能,也就是大家常常说到的Unity Networking API.这些API是借 ...
- 远程调用shell脚本文件和远程复制文件
1.安装sshpass yum install sshpass 2.本地调用远程服务器的shell脚本文件: sshpass -p sa ssh root@192.168.56.105 -C &quo ...
- [网络]_[0基础]_[使用putty备份远程数据]
场景: 1. putty是windows上訪问linux服务的免费client之中的一个.用它来ssh到远程server备份数据是常见的做法(在没做好自己主动备份机制前), 通过putty界面尽管也不 ...
随机推荐
- sqlserver迁移mysql语法修改
1.top 100 选取表中前100条改为 limit #{limit},limit 为变量2.获取当前日期getdate()改为now()3.id=#{id,jdbcType=BIGINT}改为i ...
- HNUSTOJ-1674 水果消除(搜索或并查集)
1674: 水果消除 时间限制: 2 Sec 内存限制: 128 MB提交: 335 解决: 164[提交][状态][讨论版] 题目描述 “水果消除”是一款手机游戏,相信大家都玩过或玩过类似的游戏 ...
- Nginx + Tomcat动静分离 (转)
什么是动静分离 为了提高网站的响应速度,减轻程序服务器(Tomcat,Jboss等)的负载,对于静态资源比如图片,js,css等文件,我们可以在反向代理服务器中进行缓存,这样浏览器在请求一个静态资源时 ...
- Codeforces 1220D. Alex and Julian
传送门 首先考虑怎样的集合一定是合法的 发现全部是奇数的集合一定合法,因为每次都是奇数连偶数,偶数连奇数 然后考虑如果集合同时有奇数和偶数是否一定不合法,结论是一定不合法,证明如下: 设某个奇数为 $ ...
- elasticsearch系列一elasticsearch(ES简介、安装&配置、集成Ikanalyzer)
一.ES简介 1. ES是什么? Elasticsearch 是一个开源的搜索引擎,建立在全文搜索引擎库 Apache Lucene 基础之上 用 Java 编写的,它的内部使用 Lucene 做索引 ...
- Bootstrap中DropDown插件显示下拉列表,点击下拉列表区域,不会再自动关闭。
目标: Bootstrap中DropDown插件显示下拉列表,点击下拉列表区域,不会再自动关闭. 参考:http://v3.bootcss.com/javascript/#dropdowns / ...
- SQL语句优化 学习笔记
sql语句时间花在哪了? 1 等待时间 2 执行时间 这两个时间并非孤立的,单条语句执行的快 其他语句等待的时间就少 执行时间花在哪了? 1 查找 沿着索引查找 慢者可能全表扫描 2 取出 查到行后, ...
- PL/SQL中判断字段为空
功能写完发现数据库里好多关键字段是空的,可以直接删掉,可直接: DELETE FROM 表名 WHERE 字段 IS NULL OR TRIM(字段) = ''
- GDAL支持中文路径和Shp文件中文属性写入
在使用GDAL的过程中,为了支持中文,比需手动进行中文路径的设置,同时特别是在对Shp的属性进行中文输入的时候,都必须进行必要的设定. 为了支持中文路径,在注册了驱动之后,加上第三句就可以了.必须设置 ...
- C#文件路径操作总结
一.获取当前文件的路径 1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName 获取模块的完整路径,包括 ...