在PlayerController中只执行一次服务器事件
在PlayerController中,若只想在游戏开始时,只执行一次服务器事件,那么事件就得写在服务器的本地PlayerController中的。如图
权威版和非权威版--个人这么认为的
假如进行一个二人游戏,那么服务器上就有两个PlayerController,客户端只有一个PlayerController
- 权威版就是服务器上的PlayerController,一个PlayerController是服务器的权威版,同时该PlayerController也是服务器的本地PlayerController,另外一个PlayerController是客户端的权威版PlayerController。
- 非权威版就是客户端上的PlayerController,该PlayerController是客户端本地的PlayerController,该PlayerController是服务器端的权威版PlayerController 复制/同步 过来的。
GameInstance
单独存在每个链接中/或者说是窗口中,服务器上修改的变量不会同步到所有的客户端
所以得依靠GameState去同步给客户端
由于我们在服务器调用SetRoomName,其实是可以不用设置为在服务器上执行自定义事件的,但是这样可以防止客户端(非权威)执行该事件
设置房间
在多人游戏会话中,以创建房间,设置房间名字为例子
在GameInstance中设置RoomName不需要设置服务器上的GameInstance
原因有两点
- GameInstance单独存在每个Game中/每个窗口中/每个连接的客户端中
- 当创建完房间后,如果是客户端创建房间,那么本客户端将成为监听服务器
当然我们想要让所有人看到房间名字,所以我们就得在服务器上设置房间名,所以我们在GameState中设置了RoomName
Widget蓝图部分节点----设置RoomName节点
它将在PlayerController中被调用
PlayerController蓝图部分节点
之前在客户端创建房间的时候,一直认为得首先呼叫服务器事件,然后在这个事件里去获取服务器的GameInstance,然后设置RoomName,然而这样做不会有错误,也可以在服务器事件中获取到GameInstance,但是在逻辑上就说不通了。(然而这段标注为红色的也是错误的,在这段话中,说是要去获取服务器的GameInstance,然而获取的还是本地/客户端的GameInstance,因为如果是在客户端的Widget是没有对应权威版的Widget的。例如PlayerController,在客户端中,作为客户端,我们拥有两个PlayerController,一个权威版/服务器版,一个非权威版/本地版,那么我们去呼叫服务器事件的话,其实就是在权威版的PlayerController中去执行这个事件。所以在Widget中去呼叫服务器事件,其实也是呼叫了本地的Widget,因为Widget只存在于客户端中)
其实在会话/创建房间这种模式中并不需要在服务器上设置RoomName,因为创建完房间后,本身将会成为服务器(监听服务器),即客户端的GameInstance也自动变成服务器的,而原来服务器的自动成为客户端
证明OnServer----服务器事件是呼叫权威版的事件
在其所属的客户端上运行
会话
在查找会话完成后,记得先销毁上次的会话
这是由于当服务器退出游戏时候,不会自动销毁其他客户端的Session,所以得去销毁上次的会话,否则虽然可以找到会话,但是加入不了,因为会话已经存在了