Grabbing item does not replicate from Client to Server

Hi I am currently engaged in a problem with the replication of an action from Client to Server.

We have a character capable of grabbing and actor class AItemActor (inheriting from AStaticMeshActor) from the floor with ‘Q’ and ‘E’ keys (left and right hand respectively) through the methods:

void APlayerCharacter::TakeItemLeft() { some magic things }

void APlayerCharacter::DropItemLeft() { some magic things }

The same applies to the right hand. With these functions we can grab a AItemActor object (knife or spoon or whatever) on the floor which has corresponding components for the right and left hand grabbing.

Replication of the AStaticMeshActor component bStaticMeshActorMovementReplication is set to “True”.

The actual problem is when inside the Play scene with two players (one as listen server and one as client / or both as clients and a dedicated server); as a Client it does not seem to replicate the behavior of grabbing the component and showing it to the other player on the camera (when a player is also server, the server player shows the object on the hand, to the player on the client).

Any ideas what the problem may be?

P.D.: I have tried changing authority on the the AItemActor class, tried to use UFUNCTION(NetMulticast,…), etc, etc…

HERE IS A VIEW OF THE PROBLEM:

Thanks in advance for the help.

If I understand correctly, you are running “TakeItemLeft” on the client and try to replicate afterwards. But generally, the server should be the authority for these kind of actions. The best way would be to run TakeItemLeft on the server and then replicate to all clients. You should not run NetMulticast from a client, see for example

Can you post the code you have?

It sounds like when the client wants to do something, it isn’t telling the server to replicate it.

I post you the code we have until now. These should be the functions currently to be asked to the server to replicate on clients, as I am understanding.

PlayerCharacter.cpp

/*** TAKING DROPING ***/
void APlayerCharacter::TakeItemLeft() {
    ItemData data = FindComponentUtil(UItemTakeLeft::StaticClass());
    UItemTakeLeft* takeComp = data.comp ? Cast<UItemTakeLeft>(data.comp) : nullptr;

    if (takeComp) {
        _itemLeft = data.actor;
        UStaticMeshComponent* mesh = _itemLeft->GetStaticMeshComponent();
        if (mesh) {
            mesh->SetSimulatePhysics(false);

            mesh->AttachToComponent(GetMesh(),
                                    FAttachmentTransformRules::KeepRelativeTransform,
                                    TEXT("itemHand_l"));

            mesh->RelativeLocation = takeComp->_locationAttach;
            mesh->RelativeRotation = takeComp->_rotationAttach;
        }
        _itemLeft->SetActorEnableCollision(false);
        _activeScenaryItems.Remove(data.actor);
		_itemLeft->Destroy();
    }
}

void APlayerCharacter::DropItemLeft() {
    UStaticMeshComponent* mesh = _itemLeft->GetStaticMeshComponent();
    if (mesh) {
        mesh->DetachFromParent();
        mesh->SetSimulatePhysics(true);
    }
    _itemLeft->SetActorEnableCollision(true);
    _itemLeft = nullptr;
}

Thanks I am going through the information you passed right know, I’ll let you know if i come accross with the solution.

How is TakeItemLeft( ) and DropItemLeft( ) being called?

I ask because if what is calling them is not the server, the function isn’t going to replicate. If you wanted these to be server functions, you’ll have to make them so. Such as:

[h]

UFUNCTION( Server, Reliable, WithValidation )
void TakeItemLeft( );

[cpp]

bool MyPlayerController::TakeItemLeft_Validate( )
{
    return true;
}

void MyPlayerController::TakeItemLeft_Implementation( )
{
    // Take Item attachment code.....
}

You should not run NetMulticast from a client, see for example How do I make a function replicate from client to server? - C++ - Epic Developer Community Forums

This helped very much and I finally came across with the answer.

Vawx

[h]
`[h]

UFUNCTION( Server, Reliable, WithValidation )
void TakeItemLeft( );

[cpp]

bool MyPlayerController::TakeItemLeft_Validate( )
{
return true;
}

void MyPlayerController::TakeItemLeft_Implementation( )
{
// Take Item attachment code…
}

`

Yeah, the solution I came by is exactly as this is. Yesterday I went through the code and created a server function for each of the methods that should be replicated just as you do.

Though I am having a problem now with physics turning true where they shouldnt, the problem is very much SOLVED.

Still figuring out how this works with bool flags and stuff for On_Rep calls. But I think this is the answer I finally came across yesterday.

There should be a more elegant and abstract method to call server functions from any class. As it says in this wiki page: Command from client to server