Tutorial 3: Authoritative servers 之前的服务器设置,被称之为“非权威性”服务器;服务器对所有的网络信息没有任何控制权,客户端会和服务器共享物体的位置信息,并且所有的终端都接受并且执行 这些信息。在你的FPS游戏里,你肯定不想有玩家能瞬间移动,水上飞什么的。所以一般来说服务器都是“权威性”服务器。设置一个权威性服务器也不需要什么特别难的 代码,不过它的确需要你设计代码框架的时候,稍微做些调整。你需要在服务器端完成所有的工作并且检查所有的通讯。 我们回头看一下上个教程B2,怎么才能把它修改成权威性服务器呢。首先,服务器需要生产玩家,玩家不能决定他们被生成的时间和地点。其次, 服务器要告诉所有的客户端所有物体的位置,客户端之间无法发送和接受信息。因为只有服务器能够移动物体的位置,客户端的玩家想要移动的话, 必须向服务器发送他的所需要的移动信息,然后接收服务器指令才能移动。 我们要发送所有客户端的移动输入命令到服务器端,服务器会处理这些数据,然后送回结果数据(新的位置)到客户端。看一下Tutorial3场景。功能还是和以前一样, 但是内部处理机制已经不一样了。移动起来可能比以前感觉更卡一点,但是现在这个暂时不重要。 这个例子里没有新脚本,只有Playerscript脚本和spawnscript脚本的内容有改变。我们先看下Tutorial_3_Spawnscript.js。客户端在这个脚本里没有任何操作, 每当客户端连接的时候服务器端才开始生成物体。服务器端还会保存一个已连接客户端的列表,列表中还包括了Playerscripts的信息,这样在一个客户端下线的时候, 服务器就可以删除正确的玩家物体。这个Spawnscript脚本是一个纯粹的服务器端脚本,和客户端的“OnDisconnectedFromServer”函数没有任何关系。 现在我们再看一下Tutorial_3_Playerscript.js脚本,这个脚本现在不只被Networkview所有。因为现在由服务器端来生成所有的物体,所以全部的Networkview都被服务器所有。所以现在我们使用每个终端自己的“所有者”参数来控制,哪一个网络上的玩家会控制哪一个物体。playerscript脚本的所有者会发送移动信息到服务器。 服务器执行这个移动信息并且负责移动玩家物体。这样一来,我们就有了一个“权威性”的服务器! 关于卡的问题:在之前的例子里,玩家物体会在按下按键后立即移动,但是当我们使用权威性服务器,我们需要发送移动信息给服务器,然后服务器会处理它, 然后再发回一个移动指令,然后我们才能移动物体。我们当然是想让服务器端有所有的控制权,但是我们不想让客户端等太长时间。其实这个问题也很简单, 只要让客户端也同时计算移动信息,然后再让服务器端的信息覆盖客户端的计算结果,这样服务器端总是有控制权。很简单吧。Tutorial_3_Playerscript.js这个脚本 在客户端调用了“SendMevementInput(HIput,Vinput)”函数。这里你可以发送一个移动信息RPC到服务器(第56行代码)。随后这个SendMovementInput RPC 会 调用客户端移动脚本里的Update()函数的最后一部分代码,来更新物体的移动。同时在本地调用这一段代码:“|| Network.player == owner)” (第64行代码)。 这样就可以确保客户端的移动立刻就能执行,而且让服务器端的计算结果为最终结果。 虽然我们设置了让客户端可以“预测”物体的移动,但是还是有些卡,在代码的第100行这里有一段代码,它合并了当前的物体位置和服务器发送来的位置, 并且以服务器的位置为主。你还可以把服务器发送来的位置保存为一个参数,然后用Vector3.Lerp这个命令来进行插值。这样你就可以在Update函数里进行平滑的插值, 而不是只能在OnSerializeNetworkView函数里进行一次插值。 注意一下,其实你不用总是在你的多人游戏里用“权威性”服务器。比如我们公司的Crashdriver 3D游戏,就用了非权威性服务器。玩家可以恶意修改他的赛车位置; 但是谁在乎呢~这种修改最多也就能让玩家得到很高的分数。之后我们再检查那些高的离谱的得分要容易得多。总而言之:想明白你究竟为什么要用权威性服务器。 另外也要知道,如果你直接修改权威性服务器,也能作弊哦。 |