Hi I think I have a code that pretty much does the job but something is wrong. Characters are not moving at all and unexpected log output for Client’s path points. They never change. Server outputs seemingly good pathpoints. Also, distance between click location and pawn location is always about 85. Strange. The RPC calls get called many times for one click. Not sure why. Could just be repeated legitimate calls because mouse was held down. I haven’t check that yet.
It’s hard to explain, if you feel like analyzing just one 100 line cpp and offering help please do.
.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MobaScapeServerPlayerController.generated.h"
UCLASS()
class AMobaScapeServerPlayerController : public APlayerController
{
GENERATED_BODY()
public:
AMobaScapeServerPlayerController();
protected:
TArray<FNavPathPoint> PathPoints;
int32 PathPointsIndex;
bool bMoveToMouseCursor;
virtual void PlayerTick(float DeltaTime) override;
virtual void SetupInputComponent() override;
void LeftClickPressed();
void LeftClickReleased();
UFUNCTION(Reliable, Server, WithValidation)
void ClientToServerMoveTo(const FVector DestLocation);
UFUNCTION(Reliable, Client)
void ServerToClientMoveTo(const float Distance, const FVector Direction, const FVector DestLocation);
void MoveToCurrentPathPoint();
void MoveToMouseCursor();
};
.cpp
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "MobaScapeServerPlayerController.h"
#include "AI/Navigation/NavigationSystem.h"
#include "Runtime/Engine/Classes/Components/DecalComponent.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "MobaScapeServerCharacter.h"
#include "UnrealNetwork.h"
#include "AI/Navigation/NavigationPath.h"
//easily get my pawn
#define MyPawn GetPawn()
//easily get this controller's pawn location
#define MyLocation MyPawn->GetActorLocation()
//easily get the current path point
#define CurrentPathPoint PathPoints[PathPointsIndex].Location
//Gets the path to a destination in a TArray<FNavPathPoint>
#define GetPathPoints(DestLocation) GetWorld()->GetNavigationSystem()->FindPathToLocationSynchronously(GetWorld(), MyLocation, (DestLocation), MyPawn)->GetPath()->GetPathPoints()
//Moves this controller's pawn on the server to the destination location the client sent and then moves the client
#define MoveMe(DestLocation) float Distance = FVector::Dist(MyLocation, CurrentPathPoint); \
FVector Direction = CurrentPathPoint - MyLocation; \
MyPawn->AddMovementInput(Direction, Distance, false); \
ServerToClientMoveTo(Distance, Direction, (DestLocation))
//The Constructor
AMobaScapeServerPlayerController::AMobaScapeServerPlayerController()
{
bShowMouseCursor = true;
DefaultMouseCursor = EMouseCursor::Crosshairs;
bReplicates = true;
bMoveToMouseCursor = false;
PathPointsIndex = 0;
PathPoints = TArray<FNavPathPoint>();
}
void AMobaScapeServerPlayerController::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
//Player clicked or is holding left click
if (bMoveToMouseCursor)
{
MoveToMouseCursor();
}
//We aren't there yet
else if (PathPointsIndex < PathPoints.Num())
{
if (MyPawn)
{
//Wait did we just get there?
UE_LOG(LogTemp, Warning, TEXT("Distance: %f"), FVector::Dist(CurrentPathPoint, MyLocation));
if (FVector::Dist(CurrentPathPoint, MyLocation) < .03f)
{
MoveMe(CurrentPathPoint);
PathPointsIndex++;
}
}
}
}
void AMobaScapeServerPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
InputComponent->BindAction("SetDestination", IE_Pressed, this, &AMobaScapeServerPlayerController::LeftClickPressed);
InputComponent->BindAction("SetDestination", IE_Released, this, &AMobaScapeServerPlayerController::LeftClickReleased);
}
void AMobaScapeServerPlayerController::MoveToMouseCursor()
{
if (Role < ROLE_Authority)
{
FHitResult Hit;
GetHitResultUnderCursor(ECC_Visibility, false, Hit);
if (Hit.bBlockingHit)
{
ClientToServerMoveTo(Hit.ImpactPoint);
}
}
}
void AMobaScapeServerPlayerController::ClientToServerMoveTo_Implementation(const FVector DestLocation)
{
if (MyPawn)
{
PathPoints = GetPathPoints(DestLocation);
for (int i = 0; i < PathPoints.Num(); i++)
{
UE_LOG(LogTemp, Warning, TEXT("PathPoints on server #%d: %s"), i, PathPoints[i].Location.ToString());
}
PathPointsIndex = 0;
MoveMe(CurrentPathPoint);
}
}
bool AMobaScapeServerPlayerController::ClientToServerMoveTo_Validate(const FVector DestLocation)
{
return true;
}
void AMobaScapeServerPlayerController::ServerToClientMoveTo_Implementation(const float Distance, const FVector Direction, const FVector DestLocation)
{
if (MyPawn)
{
UE_LOG(LogTemp, Warning, TEXT("Checking NavSys on Client"));
if (GetWorld()->GetNavigationSystem())
{
UE_LOG(LogTemp, Warning, TEXT("Good NavSys"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Bad NavSys"));
}
PathPoints = GetPathPoints(DestLocation);
for (int i = 0; i < PathPoints.Num(); i++)
{
UE_LOG(LogTemp, Warning, TEXT("PathPoints on client #%d: %s"), i, PathPoints[i].Location.ToString());
}
PathPointsIndex = 0;
MyPawn->AddMovementInput(Direction, Distance, false);
}
}
void AMobaScapeServerPlayerController::LeftClickPressed()
{
bMoveToMouseCursor = true;
}
void AMobaScapeServerPlayerController::LeftClickReleased()
{
bMoveToMouseCursor = false;
}