ue4-Network相关-Client和Server的区分

时间:2022-04-07 04:11:13

判断当前是在Client or Server执行方法,敏感信息应放在服务端计算,而客户端只做展示


区分当前运行的是客户端还是服务器

  • 蓝图中,有个 SwitchHasAuthority 宏:
    ue4-Network相关-Client和Server的区分

    FORCEINLINE_DEBUGGABLE bool AActor::HasAuthority() const
    {
    return (Role == ROLE_Authority);
    }
    • 只有 Role == ROLE_Authority 情况才是表示是 这个actor是在服务器上,其他两种情况都表示在客户端上
      • Authority:如果是服务器,会走这个支线
      • Remote:如果是客户端,会走这个支线
  • c++中:

    • AActor 中都有个 ENetRole Role 变量是用来识别角色的 Actor 的身份的。ENetRole 的几个值:

      • ROLE_None
      • ROLE_SimulatedProxy:这个actor是其他客户端在本机客户端的一个模拟代理
      • ROLE_AutonomousProxy:这个actor是本机客户端的自己控制的角色
      • ROLE_Authority:这个actor是服务器上的actor
    • 示例代码

      void AMyNetCharacter::BeginPlay()
      {
      Super::BeginPlay();
      switch (Role)
      {
      case ROLE_Authority: Flag = "ROLE_Authority"; break;
      case ROLE_SimulatedProxy: Flag = "ROLE_SimulatedProxy"; break;
      case ROLE_AutonomousProxy: Flag = "ROLE_AutonomousProxy"; break;
      default: Flag = "ROLE_None";
      }
      }

      从左至右的三个角色分别是 Server、Client1、Client2 对应控制的角色

      • Server 显示
        ue4-Network相关-Client和Server的区分
      • Client1 显示
        ue4-Network相关-Client和Server的区分
      • Client2 显示
        ue4-Network相关-Client和Server的区分

Actor 的 生成销毁

  1. 如果想 生成销毁 一个 Actor,这个 Actor 必须为 Replicates
    ue4-Network相关-Client和Server的区分
  2. 而且必须在服务器上调用,而不是客户端调用,否则只会在该客户端生产,其他客户端不会生成
    ue4-Network相关-Client和Server的区分
    ue4-Network相关-Client和Server的区分
    • 销毁 的类似。

区分自己控制的和别人的

  • 方式一:经过服务,先rpc服务器方法,再调用拥有该actor控制权的客户端的方法
    ue4-Network相关-Client和Server的区分

    • CallServerChangeSkin 事件是 Run On Server 类型
    • ChangeOwnSkin 事件是 Run On Owning Client 类型
  • 方式二:直接成 Actor 中 的 Role 中判断,但不知为啥引擎不提供接口, Role 变量也没有暴露给蓝图,那么就自己提供个接口

    UFUNCTION(BlueprintCallable, Category = AMyNetCharacter)
    virtual ENetRole GetRole() { return Role; }

    ue4-Network相关-Client和Server的区分

  • 结果:只有自己控制的 Actor 变色
    ue4-Network相关-Client和Server的区分


服务端计算、客户端展示

一般来说,对于敏感数值的计算及校验都是在服务端上做,客户端则用来做展示效果,示例如下:

  1. 空格键 触发一个 Skill1 事件, Skill1 是个 Run On Server,只在服务器上调用的事件
    ue4-Network相关-Client和Server的区分
    ue4-Network相关-Client和Server的区分

    • 该事件是选取范围内的 Pawn 赋予伤害触发 Apply Damage 事件
  2. Apply Damage 是个只会在服务器上跑的事件 修改 Health 变量,该变量是个 RepNotify 类型,会对应生产一个 值改变时触发的函数 OnRep_Health(客户端服务器都会调用),
    ue4-Network相关-Client和Server的区分
    ue4-Network相关-Client和Server的区分
    ue4-Network相关-Client和Server的区分

    • OnRep_Health 判断只有在客户端中才调 ChangeHealthText(TextRender的展示内容)
    • 这里如果 Health 减到小于0时则 DestroyActor 销毁,否则触发 ShowEffect 事件
  3. ShowEffect 事件是个 Multicast 类型,客户端服务器都会调用
    ue4-Network相关-Client和Server的区分
    ue4-Network相关-Client和Server的区分

    • 这里只需要客户端展示,所以进一步 SwitchHasAuthority 判断,只在客户端(Remote)Spawn粒子特效
  4. 所以结果是:Health 的 TextRender展示 和 粒子特效 都只会在客户端展示,服务端只负责存储及计算值。
    ue4-Network相关-Client和Server的区分