UE4联网开发翻译(四)

Examples and Usage

在多人游戏中,我们主要使用Pawn的复制来展现角色和分享信息给其他玩家。一个简单的例子就是角色的‘生命值’。

但我们不仅仅复制‘健康值’去使其他人可见,还需要复制这个属性,使服务器有对它的权限而且使客户端不能够作弊。

Blueprint

除了一些默认的标准Pawn类函数供你重写外,还有两个事件供你调用:possessing和un-possessing。如果是un-possessing的话,可以用来隐藏Pawn。

NOTE:由于拥有权,这发生在服务器上,这些事件只会在当Pawn需要用多播RPC函数改变其可见性时,才会在服务器上被调用,就如上述截图所示。

 

第二个例子将会引入‘健康值’来说明。下面这个图片将会告诉你怎么用‘EventAnyDamage’事件和复制的‘健康值’变量来降低玩家的血量。这只会发生在服务器上而不会发生在客户端上!

由于Pawn被复制,所以如果服务器上调用‘DestroyActor’,那么客户端上的Actor也同样会被销毁。在客户端上,我们可以用复制的‘健康值’变量来改变 我们的HUD或者 在玩家头上的HealthBar血量条。

你可以通过创建带有Progressbar和Pawn的引用的Widget来轻松做到这一点。

由于这是网络开发介绍文档,我希望你了解widgets,至少在其他地方看到过,要介绍这些内容那就偏离这个文档范围了。

 

假设在‘TestPawn’类上有‘Health’和‘MaxHealth’变量,且都设为replicate。

现在,在创建含有‘TestPawn’引用变量和ProgressBar的Widget后,我们可以将Bar的百分比绑定到下面这个函数。

现在,在设置WidgetComp(这个类用来做实验)后,我们在BeginPlay中用‘Wdiget Class to use’来设置你的HealthBar。

 

‘BeginPlay’是每个Pawn实例都会在游戏开始时运行的,意思是在服务器和客户端上都有。

所以每个Pawn引用实例都会在自身头顶创建出Widget部件。

由于Pawn和Health变量是复制的,所以我们就有了Pawn上正确的血量百分比。

即使你现在还不懂Replication过程,也没关系,继续读下去你会知道它是如何简单运作的。

 

在C++例子中,我不想创建像蓝图中的widget部件,因为特别麻烦。我们关注PossessEvent和DamageEvent。

在C++中,两个PossessEvents被调用:

‘Unpossessed’事件不会传递旧PlayerController。

 

我们同样需要多播RPC函数。你将会在后续章节了解RPC:

 

 

我打算用C++重新创建Health例子。就如前面所说,你现在不懂Replication步骤也不用担心,接下来的章节会给你解释。

如果觉得这个例子的Replication太复杂,那先跳过。

‘TakeDamage’函数等同于刚刚蓝图示例中的‘EventAnyDamage’节点。

想要造成伤害,那么你需要在你想处理这个伤害的Actor上调用‘TakeDamage’函数,如果这个Actor有TakeDamage的函数实现,则他会响应这个伤害,就如代码中所示。

 

 

 

Player Controller

PlayerController类应该是我们遇到过最有趣和最复杂的类了。这是客户端真正拥有的第一个类。

PlayerController类可以被理解成Player的输入。这是玩家和服务器之间的沟通渠道。意味着,每一个客户端都有一个PlayerController。

一个客户端上的PlayerController只存在于这个客户端自身和服务器上,其他客户端不知道有这个PlayerController。

每个客户端只知道自己的PlayerController!

所以结果是,服务器有所有客户端PlayerController的引用!

‘输入’一词不意味着所有实际的输入(按键、鼠标移动、控制轴等)都需要放置在PlayerController中。

将特定的输入放入Character或者Pawn类里面(例如车和人的工作方式不一样),而将通用的角色输入放入PlayerController类里面(甚至角色对象无效的时候),这将会是一个好的实践方法!

 

 

重点注意:

输入总是先传递给PlayerController类。如果PlayerController不响应这输入,那么将会传给其他有权限的类处理。当然也可以手动设置停止处理。

还有一件重要的事情:

我如何获得正确的PlayerController呢?

比较常用的节点‘GetPlayerController(0)’或者代码‘UGameplayStatics::GetPlayerController(GetWorld(),0)’在服务器和客户端上有不同的工作方式,但是并不难理解使用。

1.在监听服务器上调用会返回服务器的PlayerController

2.在客户端上调用会返回客户端的PlayerController

3.在专用服务器上调用会返回的第一个客户端的PlayerController

不是0的其他数字也不会返回其他客户端的PlayerController。这个0用于本地多玩家(分屏),在此不再详述。

 

猜你喜欢

转载自blog.csdn.net/qq_16468937/article/details/94624565