Why is my Character not moving on client in Top Down Template Network game?

Hello,
Creating a new top down blueprint project, setting the number of clients to 2 and running a network game allows the server side character to move and responds to mouse clicks while the client side character is not movable.
Tried to enable replication on the controller blueprint but no luck.

Marcel

Did a bit more digging in to this, started with a c++ version of the top down template and it looks like NavSys in the template character controller code is returning NULL when running on the client.

void ANetTestPlayerController::SetNewMoveDestination(const FVector DestLocation)
{
...
...
UNavigationSystem* const NavSys = GetWorld()->GetNavigationSystem();
..
..
}

So it looks like the navigation system is not replicating to the client. Hence why the character is not moving on the client.

The ANavigationData constructor is setting the bNetLoadOnClient to false.
What is the workflow here? Do I need to create a UNavigationSystem for each remote client?
Or perhaps a client to server function call to query the Nav system for each click?

Marcel

Got the same problem and would love to see how to fix this.

Same problem here. Any luck?

Here’s what I did

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
in .h
UFUNCTION(reliable, server, WithValidation)
void SetDestination(const FVector aDestination);

in .cpp
void AWPlayerController::SetDestination_Implementation(const FVector DestLocation)
{
	APawn* const Pawn = GetPawn();
	if (Pawn)
	{
		UNavigationSystem* const NavSys = UNavigationSystem::GetCurrent(this);
		float const Distance = FVector::Dist(DestLocation, Pawn->GetActorLocation());
		if (NavSys && (Distance > 120.0f))
		{
			NavSys->SimpleMoveToLocation(this, DestLocation);
		}
	}
}

bool AWPlayerController::SetDestination_Validate(const FVector DestLocation)
{
	return true;
}

Then just let the client interpolate normally with the movement component. You might need to replicate the rotation on the client, otherwise he will only face one direction as he’s moving.

Hello,
Great spot on the UNavigationSystem::GetCurrent(this) did not see this at all.
As you say rotation on the client needs to be replicated not sure how to do that yet.

I did it via Blueprint, want me to post a pic?

please do, i was trying to figure it out today

is there a way i can do what Omberone provided with blueprint?

Same question as Cheesecake,
Is it possible to Replicate the “Simple Move to Location” function in blueprint as well?
I also tried to implement the rotation blueprint replication, but it didn’t seem to work, probably because I can’t do the first part unless I change my project to C++.

Omberone, I changed my project to C++ but still can’t get the code to work. I edited the playercontroller.h and playercontroller.cpp.
Was your code above for location modifying existing code or did you add those blocks to the end? I tried both, but my client character still won’t move, must be doing something wrong.

Here is variant with “AddMovementInput”.

in PlayerController.h

...
void MoveToMouseCursor();
void UpdatePawnMove();
private:
bool m_isMoveToMouseCursor;
FVector m_DestLocation;
...

in PlayerController.cpp

void APlayerController::PlayerTick(float DeltaTime)
{
    Super::PlayerTick(DeltaTime);

    // keep updating the destination every tick while desired
    MoveToMouseCursor();
}

void APlayerController::SetupInputComponent()
{
    // set up gameplay key bindings
    Super::SetupInputComponent();

    InputComponent->BindAction("SetDestination", IE_Pressed, this, &APlayerController::OnSetDestinationPressed);
    InputComponent->BindAction("SetDestination", IE_Released, this, &APlayerController::OnSetDestinationReleased);
}

void APlayerController::MoveToMouseCursor()
{
    // Trace to see what is under the mouse cursor
    FHitResult Hit;
    GetHitResultUnderCursor(ECC_Visibility, false, Hit);

    if (m_isMoveToMouseCursor && Hit.bBlockingHit)
    {
        m_DestLocation = Hit.ImpactPoint;
    } 

    // We hit something, move there
    if (m_DestLocation != FVector::ZeroVector)
        UpdatePawnMove();
}

void APlayerController::UpdatePawnMove()
{
    APawn* const Pawn = GetPawn();
    if (Pawn)
    {      
        float const Distance = FVector::Dist(m_DestLocation, Pawn->GetActorLocation());
        FVector const Direction = (m_DestLocation - Pawn->GetActorLocation()).Rotation().Vector();
        Pawn->AddMovementInput(Direction, Distance);
        if (Distance < 120.0f)
        {
            m_DestLocation = FVector::ZeroVector;
        }
    }
}

void APlayerController::OnSetDestinationPressed()
{
    // set flag to keep updating destination until released
    m_isMoveToMouseCursor = true;
    m_DestLocation = FVector::ZeroVector;
}

void APlayerController::OnSetDestinationReleased()
{
    // clear flag to indicate we should stop updating the destination
    m_isMoveToMouseCursor = false;
}

“AddMovementInput” parametr “scale” don’t do anything. That’s why this function in Tick and use variable.
But this example without verifcation on server. You can add it additional before “AddMovementInput”

Hi Guys,

I had a similar problem with Network Clients not moving in the Top Down Template.
Have made a Blueprint only solution by modifying the character controller slightly:

I now have multiple clients able to move around properly!
Hope this helps.

Hiya, I have a partial solution Via blueprints which I’ve put below:

So when I click the pawn that is possessed does now move to the loaction clicked. The only trouble now is that the walk animation doesn’t play on the client, it sort of slides across the screen, but it does play on the server. Any ideas/solutions/flashes of inspiration would be greatly appreciated?

The reason for the stuttering/sliding is explained in this answer. Basically, simple move to location is not meant to be used in multiplayer. There is not (yet) an built in solution to this. You can use an AI-Controlled Pawn on the server and replicate it’s movement to your client side pawn(s) in their Tick Event. There is also a blueprint solution to this in the link above.

Awesome, this is exactly what I was looking for. Thanks so much. In case it isn’t clear, looks like this won’t work for people that want the controller to pathfind, tho. It only moves them in the direction you click/touch. Thanks again!

Hello,

please note I am still very new (2 months) to game development so if my solution is wrong or you have sugestions in improving it please do not hesitate to tell me :).

I saw many answers using your pawn along side an AI controller, and many of my functionality gets limited when I do this, so I found my own little way.
Resolving my Network movement on the client side:

  1. Enable Client side replication of the Nav-Mesh. (Project settings → Navigation System → Allow Client side navigation)
  2. Get the path you wish to follow by using “Find path to location synchronously” Node
  3. take the result and get an array of points
  4. create you own little movement component that calculates the next point in the array when it reached its destination.
  5. enjoy client side Navigation :slight_smile:

This is just after experimenting and finding a solution, so mind the mess :slight_smile:

1 Like