注意:以下举例的网络同步函数实现都是不正确的(正确实现应该是在.h声明,在.cpp文件实现,函数名_Implementation())
前提条件:一个Character,一个UMG_Character(用于可视化手部物品)
UCLASS()
class ACharacter
{
//左手物品
UFUNCTION(Replicated)
AActor*LHandActor;
//添加到左手
UFUNCTION(Server)
void Server_AddToLHand(AActor*AddToActor)
{
LHandActor=AddToActor;
}
//更新手部UI
void UpdateHandUI()
{
//手部UI更新逻辑
UMG_Character->UpdateHandUI();
}
//属性同步重写
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACharacter, LHandActor);
}
}
需求:在手部物品被重新设置的时候更新UI
实现想法:手部物品在服务端设置(手动实现)→网络同步(通过Replicated自动同步)→调用手部UI更新函数(手动调用)
错误使用:
1.直接在AddToLHand添加UpdateHandUI()方法
错误原因:Server_AddToLHand被标识为Server只会在服务端调用不会在本地客户端调用
UCLASS()
class ACharacter
{
//左手物品
UFUNCTION(Replicated)
AActor*LHandActor;
//添加到左手
UFUNCTION(Server)
void Server_AddToLHand(AActor*AddToActor)
{
LHandActor=AddToActor
//修改后直接调用更新UI方法
UpdateHandUI();
}
//更新手部UI
void UpdateHandUI()
{
//手部UI更新逻辑
UMG_Character->UpdateHandUI();
}
//属性同步重写
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACharacter, LHandActor);
}
}
那么有睿智的人说了这么睿智的错误还不简单,不就是单独加一个Multicast_UpdateHandUI函数不就行了吗
对我就是这个睿智o(* ̄︶ ̄*)o
2.新增Multicast_UpdateHandUI函数,在Server_AddToLHand调用后调用
*错误原因:在调用Server_AddToLHand后还并未触发网络同步,客户端的LeftHand依然未同步改变,所以紧接着调用Multicast_UpdateHandUI多播到客户端没有任何意义
UCLASS()
class ACharacter
{
//左手物品
UFUNCTION(Replicated)
AActor*LHandActor;
//添加到左手
UFUNCTION(Server)
void Server_AddToLHand(AActor*AddToActor)
{
LHandActor=AddToActor
//修改后调用多播UI更新方法
Multicast_UpdateHandUI();
}
/*********多播到客户端更新UI************/
UFUNCTION(NetMulticast)
void Multicast_UpdateHandUI()
{
UpdateHandUI();
}
//更新手部UI
void UpdateHandUI()
{
//手部UI更新逻辑
UMG_Character->UpdateHandUI();
}
//属性同步重写
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACharacter, LHandActor);
}
}
正确使用
1.在属性宏中添加选项ReplicatedUsing=UpdateHandUI
UCLASS()
class ACharacter
{
//左手物品
UFUNCTION(Replicated,,ReplicatedUsing=UpdateHandUI)
AActor*LHandActor;
//添加到左手
UFUNCTION(Server)
void Server_AddToLHand(AActor*AddToActor)
{
LHandActor=AddToActor
//修改后调用多播UI更新方法
Multicast_UpdateHandUI();
}
//更新手部UI
void UpdateHandUI()
{
//手部UI更新逻辑
UMG_Character->UpdateHandUI();
}
//属性同步重写
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACharacter, LHandActor);
}
}
2.将设置LeftActor的逻辑和UI更新逻辑放在同一个Multicast函数中
(开销比较大,但可以实时同步UI,这样种方法属性的Replicated也失去了意义)
UCLASS()
class ACharacter
{
//左手物品
UFUNCTION(Replicated)
AActor*LHandActor;
//添加到左手
UFUNCTION(Server)
void Server_AddToLHand(AActor*AddToActor)
{
Multicast_AddToLHand(AddToActor);
}
//添加到左手
UFUNCTION(NetMulticast)
void Multicast_AddToLHand(AActor*AddToActor)
{
LHandActor=AddToActor
UpdateHandUI();
}
//更新手部UI
void UpdateHandUI()
{
//手部UI更新逻辑
UMG_Character->UpdateHandUI();
}
//属性同步重写
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACharacter, LHandActor);
}
}

1827

被折叠的 条评论
为什么被折叠?



