前提
首先看到这篇文章,我希望你能够先暂时忘记这个令人极其拗口的标题以及Actor的所有权这个词!!!暂时叫它Actor的真正拥有者
必备小知识
- 服务器是权威,只能它同步给客户端,不能反着来
- PlayerController与网络以及输入密切相关
以上必须有一点点的了解
MyPlayerController类
为了很直观的去了解到Actor的真正拥有者,我们要新建一个C++类,叫MyPlayerController,继承于PlayerController这个类,并且在构建函数这里将隐藏取消
bHidden = false;
#if WITH_EDITORONLY_DATA
bHiddenEd = false;
#endif // WITH_EDITORONLY_DATA
这样一来我们就可以在游戏中看到我们的PlayerController了!
添加静态网格正方体
我在游戏中创建一个蓝图类,继承与上面刚刚创建的MyPlayerController,并且给蓝图添加一个静态网格正方形,如图。
接着我们进行三人游戏
看到PlayerController!
服务器端视角
你可以在服务器端口中看到三个PlayerController,白色正方体就是代表着PlayerController
客户端视角
而你在两个客户端中只能看到自身的PlayerController
思考这是为什么?
因为上面说了服务器端才同步,而同步是什么?简单点说就复制东西给客户端,因此服务器端才可以同时看见三个PlayerController。因为客户端的东西基本都是服务器端复制过去的,并且每人对应一份,所以客户端只能看见自身的PlayerController,客户端的PlayerController都是副本,都是服务器端复制过来的。说了这么多,现在就要进入主题了!
Actor的真正拥有者
Actor的真正拥有者其实是服务器端,客户端上的都是Actor的拥有者,注意字眼!
那么Actor的真正拥有者是谁?
就是服务器端上的PlayerController,那么对应的Actor的拥有者就是客户端上自身的PlayerController了。那么我们已经完美的理解到了Actor的拥有者----即Actor及其所属连接或者说是Actor的所有权。既然理解了,那么得试试看有没有理解错误,然后行不行得通啊。
官方Actor所以权对照表
- Client-owned actor:客户端拥有的Actor 对应的也就是Actor的拥有者
- Server-owned actor:服务器端拥有的Actor 对应的也就是Actor的真正拥有者
- Unowned actor:没有拥有的Actor 对应的也就是Actor的拥有者
补充一点,本人认为拥有既可以控制,你都不能控制一个东西,你怎么能拥有它?
Client-owned actor这个就是指我们在客户端中控制的Actor(角色),以及它对应的是在客户端这边看到的景象,其余两个差不多。
- Owned by Invoking client:当前客户端拥有的Actor 对应的也就是Actor的拥有者
- Owned by different client:其他服务器端拥有的Actor 对应的也就是Actor的拥有者
- Server-owned actor:服务器端拥有的Actor 对应的也就是Actor的真正拥有者
- Unowned actor:没有拥有的Actor 对应的也就是Actor的拥有者
现在我们来试试看,我们有没有理解错
在角色蓝图中的蓝图脚本
以及我们必须将火焰这个蓝图的Replicate设置为false
测试服务器端调用的RPC
现在测试不复制的
结果和官方所有权表一样只有服务器端有火焰,其他都没有。
测试Multicast
蓝图脚本修改
结果
全部都显示,和官方所有权表一致,注意我们都是在服务器端执行RPC的!
其他同样都是行的通的,在这里就不一一测试了
结论
所以Actor的所有权可以简单的理解为拥有者,而拥有者就是PlayController,服务器端的得是服务器同步的过去的PlayController
服务器是权威
顺带证明服务器是权威,为什么说服务器是权威,同步和权威这个两个字眼什么关系都没有,怎么得出的,不着急下面会有个小实验证明。
小实验
这个是我发现的一个奇怪的现象,当服务器将Client1的人物抬起的时候,只有client2和服务器更新Client1的人物位置,而client1的窗口并未更新
client1的窗口并未更新本身人物的位置
当我们将角色放下,放在地面的时候,client1窗口的人物瞬间移动到在服务器端中放下的位置。
我想这是因为服务器具有权威性,所以强制将Client1窗口的人物位置强制同步到和服务器端窗口一样的位置了