UE5学习笔记——RPC——属性同步结合UserWidget

注意:以下举例的网络同步函数实现都是不正确的(正确实现应该是在.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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值