Replicating AIController

So, I’m trying to have each player control a character that supports MoveToLocation (see my previous thread: MoveToLocation with PlayerController - C++ - Unreal Engine Forums)

To accomplish this, I did something similar to what was suggested in my previous thread. I created an AIController as proxy. So my PlayerController has an AIController instance variable that possesses the character.

The problem I’m encountering is getting this AIController or Character information to the client. The server creates the character and the AIController and links them up, but on the client the PlayerController doesn’t have a reference to either the AIController or the Character.

My first approach was to replicate the AIController, but whatever I did, the AIController variable kept being null on the client, and now I’m not sure what to do.

Any ideas?

Got a code snippet you can share with us, to clarify the issue a little better. I have tried Droneah’s and it worked fine, just kind of ugly and seemed taxing. Additionally I would have to pass in every single movement input over the server. How are you instantiating the controller?

AIControllers do not exist on clients by design. If you associate AIController with your PlayerController it will work on the server, and all you have to do on the client is to implement and call replicated functions so that they get executed on the server and do whatever you need with the AI controller.

Cheers,

–mieszko

I was thinking it would be something like that. I’ll have a look at my code and see how to work around it best.

As you say, it just seems very annoying with a set up that has two characters per character. I’d rather try to minimize annoying convoluted ways of doing things, rather than get stuck with it forever.

I’m MieszkoZ’s answer is correct. If AIControllers don’t exist on clients, I have to rethink my design.

let us know what you come up with, I’m very interested in this.

For my use-case, the only reason to have an AIController is to use MoveToLocation to take advantage of the navmesh pathfinding. This was easily accomplished with a RPC to the server.

The thing that caused issues for me is that I was using the AIController instance variable as an indirect reference to the controlled character (by doing something like MyControl->GetPawn()). Since I wasn’t sure what was causing the replication to not work, I didn’t experiment with replicating other things.

In the end, I changed it to replicate the character instead, which works fine.

For the final structure of it: I’m having a PlayerController with a server-only reference to an AIController that possesses my character. My playercontroller has a replicated reference to the character. Moving the character is done by calling a RPC in the PlayerController which tells the AIController to move the character. It’s not as messy as it sounds, trust me :stuck_out_tongue:

I just let the AIController always possess the character so you don’t have to do it every time you right click. This means I possessed it in BeginPlay. I changed it though to sync better with networking and instead put it in BeginPlayingState, but YMMV.

Do you want the camera to follow? I’m not great at this, so this might not be the best way to do it. If there isn’t a built-in function for it, you could probably do it in the camera.

Assuming you’re doing the cast in the playercontroller, it will definitely be null everytime since you can’t cast PlayerController to AIController.

My code is currently a mess, but it’s open source and available at CCUE/CCPlayerController.cpp at master · Siretu/CCUE · GitHub

Where are you possessing and unpossessing the pawn? I have a player reference that is replicated, and when I click to move it gets the hit location and calls a server function that does:

  playerCharacter = ReferencePossessedPawn();
  pAIController->Possess(playerCharacter);
  pAIController->MoveToLocation(DestLocation);

The problem for me is that the camera does not follow the character while the character moves (basically the original playercontroller unpossesses the character).

Edit: I also tried casting my controller but its always NULL:

Cast<AAIController>(this)->MoveToLocation(DestLocation);

ty in advance,

As Mieszko suggests, you need to replicate from the client to the server using a player controller. The player controller that holds a reference to the AI controller should have a replicated event that is set to server only lets call it requestMoveTo. then in there you would call pAIController->MoveToLocation(DestLocation); Since you are on the server at that point, the pAIController should be valid and the resulting pawn movement should replicate down to the clients.

I made a new class based on APawn which has a camera component. I set it as my default pawn so it’s created automatically and then I do PlayerCameraManager->SetViewTarget(GetPawn());