#1 关于Unreal的网络个人使用心得
#2 HasAuthority() 、GetWorld()->IsServer() 、GetLocalRole()区别
#3 Unreal网络功能解析
#4 Unreal中的攻击有效判定及网游动画通知
#1 关于Unreal的网络个人使用心得
#2 HasAuthority() 、GetWorld()->IsServer() 、GetLocalRole()区别
Unreal的网络是基于C/S共体的设计模式,客户端承载了Gameplay的网络;加上Unreal的大框架,Unreal非常的封闭;加上国内资料少,资料来源都是国外和官方资料;
因为这种特殊的设计,在制作客户的时候,需要考虑到服务器,客户端融合了服务器的功能;由于采用了RPC设计,使用服务器的这部分的功能非常容易的嵌入到客户端,也就是服务器的分发功能;
HasAuthority()
HasAuthority()
的源码,判定当前是否运行在Authority(授权)服务器上FORCEINLINE_DEBUGGABLE bool AActor::HasAuthority() const
{
return (GetLocalRole() == ROLE_Authority);
}
如果true
说明当前是服务器的代码片段,false
则是代理客户端;
这个方法可以大致判定区分客户端和服务器,推荐可以使用IsLocallyControlled()
GetWorld()->IsServer()
GetLocalRole()
角色类型枚举UENUM()
enum ENetRole
{
/** No role at all. */
ROLE_None,
/** Locally simulated proxy of this actor. */
ROLE_SimulatedProxy,
/** Locally autonomous proxy of this actor. */
ROLE_AutonomousProxy,
/** Authoritative control over the actor. */
ROLE_Authority,
ROLE_MAX,
};
ROLE_None
:单机游戏
ROLE_SimulatedProxy
:网络游戏的模拟客户端
ROLE_AutonomousProxy
:网络游戏的自主客户端
ROLE_Authority
:服务器
ROLE_MAX
:MAX标记
#3 Unreal网络功能解析
资料取自Unreal3的官方文档
https://docs.unrealengine.com/udk/Three/ReplicationRoles.html
Roles
In addition to their varying priorities and properties mentioned earlier, actors also have different ‘ways’ of replicating data. A rocket or grenade needs only the initial position and velocity, and the client is able to simulate the rest of it’s behavior on it’s own. A player in the game needs both location and velocity information replicated to all other clients so that they can simulate the motion of the player for the brief period of time between updates. These different networking behaviors correspond to different roles.
If an actor exists on both the server and client, its Role value will generally be ROLE_Authority on the server, and be ROLE_SimulatedProxy or ROLE_AutonomousProxy on the client, corresponding to three fundamental different roles that an actor can play in net play. The Role of the actor on the client is normally specified in RemoteRole’s value in the defaultproperties of the actor, but one is free to change the value dynamically in-game without any problems. The value of the Role is set in the current Role field, with RemoteRole indicating what Role is set on the other side of the connection. This allows code on the server, where Role is ROLE_Authority, to check what kind of simulation is being provided on the client. In general, the Role is ROLE_Authority for whatever machine spawned the actor. If an actor is spawned on the client, the client will have a Role of ROLE_Authority, but the actor will not be replicated to the server, due to the ease with which one could cheat and create weapons for themselves, on the client.
Now that you understand how Roles and RemoteRoles work, let’s go through an overview of each of the various roles individually.
ROLE_Authority
This role is different from the others in that it is always the Role on the server. On the server, all Roles will be ROLE_Authority, and the RemoteRole will be one of the following values. On the client, the reverse will be true. This role doesn’t have any real significance, beyond its use in replication statements, which are described later.
ROLE_None
This role is probably the simplest. It simply tells the server not to make this actor relevant to the client. No information will be sent about it, and it will exist only on the machine on which it was created. If a given actor was created independently on both the client and the server (via a simulated function, described later), and given a RemoteRole of ROLE_None, then there would be two separate, non-connected instances of the actor on the server and the client. This is used rather often for special effects for which replication is not needed, and can instead be spawned on both machines independently.
ROLE_SimulatedProxy
This is used for anything that should be simulated over the network, via prediction. Take a rocket, for example. It always travels in a straight line, and is an ideal candidate for Simulated Proxy. By the same token, the game can predict the falling physics clientside, and so grenades, and falling people are also good candidates for this role. Anything that can be predicted clientside because of Physics or clientside physics should use this Role. All Controllers use this role as well, since when a player is running, he’s more than likely to continue to run, and so they can take advantage of the simulation as well. It’s the best prediction method that can be used, for unpredictable players. The only exception to this guideline for players is the pawn you yourself are playing as, since you don’t want to simulate your own behavior.
In practice, there are two types of Simulated Proxy actors. Simulated Pawns and Simulated Non-Pawns both have different but similar behavior. The differences are delineated below.
Non-Pawn ROLE_SimulatedProxy
It expects full client-side prediction of the actor, given initial values. It’s like extrapolating out a curve given some data, where the current Physics is the curve fit, and you have initial data available to extrapolate from. ROLE_SimulatedProxy gives you an initial Location, Rotation and Physics. It then keeps you updated with the Velocities, should they change. These variables should enable the client to perform full client-side prediction on this object, assuming it continues along the physics prediction. In the case of PHYS_Falling and PHYS_Projectile, this is the case. There can be no aberration from these behaviors, (unless you play around with the Physics variables bBounce and such, which are very useful in prediction.) Finally, for this role, you also get animation updates, assuming the client is not the owner and it’s not set for client-side animation. In summary, this Role is for actors that smoothly predict their data on the client.
Pawn ROLE_SimulatedProxy
When ROLE_SimulatedProxy is combined with Pawns, a different sort of simulated proxy is created, that act differently in net play. Pawns are one of the most complex actors in terms of replication, because of their need for client side prediction, yet inherent unpredictability in their movement. There is no way to duplicate this behavior except by subclassing Pawn, so don’t expect to achieve it in your Projectile subclass. It gets velocity updates for the client side prediction, while at the same time getting location updates from the server to ‘readjust’ the player’s locations. You might then wonder why the pawn does not jump when a new location update comes in. Again, there is native code that causes the actor to smoothly head towards the location given by the server if the location position is too far off from the player’s real position. This again ensures seamless movement of player’s while keeping them accurate to the server’s version. All non-players will get by with velocity-only client-side prediction. No physics will be taken into account for these pawns. This is because some non-players can be PHYS_Spider, or a variety of other physics that don’t work with the following always-walking/falling prediction. Only player pawns get the special client-side prediction to have falling/walking physics. This physics is an assumed physics, which is accomplished by applying the zone’s gravity if the player is not on the ground. This logic will be bypassed if the Pawn’s bCanFly variable is set, which frees it of the client side physics, but must be accounted for in your code, since there is no physics replication in pawns. This logic is also bypassed if the pawn is in a water zone, which also differs from the default walking/falling physics. In water zones, actors are predicted using velocity alone, which is sufficient with the low amount of gravity that exists in those zones. The actor’s get their locations ‘adjusted’ anyway, so it doesn’t make any real difference in the long run. Finally, pawns get rotation updates. Since rotation (which is directly based off the ViewRotation, or the direction the player is looking) can change quite radically, no prediction is done with it. Instead, the player’s rotation is adjusted as new player rotation information comes in from the client. Animation is handled the same as any other non-pawn simulated proxy.
ROLE_AutonomousProxy
This is used for you. When you play online, you yourself should be treated differently from all other PlayerControllers. You don’t want your own self being predicted based upon the server’s expectations. Rather, you want to control yourself and tell the server where you are moving. That is the purpose of this role. This is used for things that the client directly control. In most cases, this will only be used by the PlayerControllers. When Unreal sees an Autonomous Proxy actor, it finds the top owner of the actor (Owner.Owner.Owner…), which should be a PlayerController. If this Top Owner is not the player we are currently replicating to, we change the RemoteRole to ROLE_SimulatedProxy temporarily. This allows Autonomous Proxy actors to be treated as Simulated Proxy actors to everyone else, and treated as Autonomous Proxy actors to ourselves. When the actor’s RemoteRole is set to ROLE_AutonomousProxy, it appears to be a Simulated Proxy for everyone but the owner of the actor.
Note that this technique is also used with the guided redeemer, to ensure that it works the same way and lets the controlling player have a different proxy setting from the other clients that are just simulating it. Having the server tell you where your guided redeemer is flying would not be appropriate. Rather, you want to tell the server where your guided redeemer is. While Autonomous Proxy doesn’t make this just ‘work’ for you, it does differentiate you from the other people viewing your redeemer, which is what is needed to have it act differently for you, as compared to everyone else.
Roles
ROLE_Authority is used for the server or the machine which is controlling the actor.
RemoteRoles
ROLE_None is used to indicate the actor should not be relevant at all.
ROLE_SimulatedProxy is used for any actor that needs client side simulation based upon initial rotation, location, and velocity settings. Simulated pawns get those three variables over time in addition to everything Simulated Proxies get.
ROLE_AutonomousProxy is used for client-controlled actors which need to be treated separately for their owner, which will provide client server movement information, versus other players in the game, which will use Simulated Proxy to simulated the actor on their client.
The actual code that defines these various Roles will be shown later in the actor’s variable replication statements. It is this code which makes a role do what it does (in addition to some internal native code, of course.)
#4 Unreal中的攻击有效判定及网游动画通知
多人游戏效果演示,第一次打空气弹出动画通知,第二次攻击目标,中间LOG目标信息
UFUNCTION(BlueprintCallable, Category="Abilities")
void ValidMeleeStateNotify(bool Valid);
void ANewMMOCharacter::ValidMeleeStateNotify(bool Valid)
{
UE_LOG(LogTemp, Error, TEXT("%s ValidStateNotify:%d, Role:%d"), *UCommonUtils::GetPIENetModeNamePrefix(GetWorld()), Valid, GetLocalRole());
WeaponCapsuleComponent->SetGenerateOverlapEvents(Valid);
}
// Weapon Trigger
WeaponCapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(FName("WeaponCapsuleTrigger"));
WeaponCapsuleComponent->SetRelativeLocation(FVector(0.0f, -38.0f, 0.0f));
WeaponCapsuleComponent->SetRelativeRotation(FRotator(0.0f, 0.0f, 90.0f));
WeaponCapsuleComponent->SetCapsuleRadius(5.0f);
WeaponCapsuleComponent->SetCapsuleHalfHeight(34.0f);
WeaponCapsuleComponent->SetCollisionProfileName(FName("NewMMO"));
WeaponCapsuleComponent->SetupAttachment(GetMesh(), "weapon_r");
WeaponCapsuleComponent->SetGenerateOverlapEvents(false);
动画通知在默认情况对模拟客户和控制客户端都进行分发,如果真正在专用服务器上,则不会出现。