一、名词说明:
客户端
概念1:一台设备通过加入游戏房间连入游戏后就被视为客户端,包括显示设备、输入设备、输出设备。
概念2:在进入游戏后看到的任何可视化的游戏内容都是客户端的一部分。
概念3:有多少玩家就有多少客户端。
服务器
概念1:游戏创作者将编辑完的一个游戏发布后,此时游戏就开始运行在一个虚拟服务器上。形成一个游戏服务器。
概念2:服务器是不能可视化的,一般存在远程的设备上,用户通过客户端访问。
概念3:服务器存储和处理数据,完成计算,并将处理后的数据同步给客户端进行可视化。
概念4:数据化的游戏世界即为服务器。对于《Reworld》的多人游戏来说,服务器首要保证游戏世界在所有客户端的表现是实时、一致的。
服务器脚本与客户端脚本
一般情况下,客户端脚本功能主要是提交数据,获取录入数据后提交给服务器,服务器代码功能主要是分析处理这些数据,然后把处理结果返回给客户端。
服务端脚本在服务器上执行,客户端代码在客户端执行。不能用客户端代码去控制服务器,只能通过客户端代码将数据发送到服务器,由服务器代码执行。
服务器脚本用来处理所有人都能受到影响的逻辑,比如在服务器创建一个零件,所有玩家都能看到,也可以进行触碰。而在客户端创建一个零件,则只有创建这个零件的客户端才能看到,此时零件的触碰等事件也只能在客户端检测。
同步机制中,人物同步是由各客户端向服务器同步的,因此操作角色(Avatar)的逻辑需要通过客户端脚本执行。
游戏世界
指加载完成后生成的游戏场景,包括地图内容、游戏对象等。
二、脚本执行流程
在Reworld中,脚本按照一定顺序执行,并不是一瞬间全部加载完毕的,下面是一个简略的执行流程,可以看到客户端最先加载下的脚本是先于其他所有脚本执行区执行的,因此如果此处的脚本在游戏开始时就尝试去获取玩家、界面或者工作区对象等,其结果很有可能发生错误。
三、API访问限制
大多数API目前均允许服务器/客户端脚本访问,但一些服务类API例外:
- 玩家列表服务(Players):服务器脚本可以访问Players:GetLocalPlayer()以外的接口;而客户端脚本只能访问Players:GetLocalPlayer()
- 玩家信息存储(PlayerStoreData):这个服务的接口只能通过服务器脚本调用,并且为了将测试数据与正式数据分离,该服务暂时不能在编辑器环境下执行。
- 自定义事件(MessageEvent)与事件对象(EventObject):客户端可以使用FireServer、ClientEventCallBack;服务器可以使用FireClient、FireAllClient、ServerEventCallBack
- 鼠标(Mouse):鼠标相关的接口只可以在客户端脚本使用。
- 摄像机(Camera):摄像机参数只可以通过客户端脚本调用和修改。
- 界面UI:界面相关的对象一般通过客户端脚本调用,根据需求也可以用服务器脚本修改,服务器脚本修改UI会同步给所有玩家。
- GameUI: 只可以在客户端脚本中使用。
四、管理器对象访问限制
目前所有对象均会由服务器同步至客户端,但会限制客户端对于一些管理器对象的访问。
- 客户端不能通过API接口查询其他Players对象,但可以通过父子级结构访问。
- 客户端不能访问服务器存储(两种方式均不可)。
五、事件通信模型
有些时候,创作者需要根据自己的游戏设计,在客户端——服务器之间传输一些自己定义的数据。
举例来说:当玩家想要购买一件商品,也许需要这个玩家点击商品 “购买”按钮,在此之后,客户端需要向服务器发送一段自定义的信息,它可能会包括商品的ID,商品的售价,购买数量等数据。服务器收到这条信息后,根据收到事件的参数对玩家数据进行处理,并且将结果同步给客户端。
此时可以使用事件对象(EventObject)或者自定义事件(MessageEvent)完成服务器——客户端的通信。
两者之间的区别在于:事件对象是唯一的,例如在游戏场景中,可能存在多个克隆(RWObject:Clone)出来的对象,如果此时使用自定义事件进行通信,就会造成所有对象同时进行事件通信的结果,这是因为克隆出的脚本传递的事件名称和参数都是完全相同的,如果想要避免这种情况,就可以使用事件对象进行通信,在使用事件通信时,根据自己需求,灵活选择。
有任何相关问题欢迎大家在下方讨论~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。