UInputComponent::AddActionBinding crashes on server

Hey everyone,

I’m running Unreal Engine 4.16.1 and I’m experiencing a crash on server-side immediately after a client successfully connects. The crash is happening in engine code, the top of the stack trace looks like this:


[2017.06.24-19.28.29:103][879]LogWindows:Error: UE4Editor-Engine.dll!UInputComponent::AddActionBinding() [c:\dev\unrealengine\engine\source\runtime\engine\private\components\inputcomponent.cpp:108]
[2017.06.24-19.28.29:103][879]LogWindows:Error: UE4Editor-RTSPlugin.dll!UInputComponent::BindAction<ARTSPlayerController>() [c:\dev\unrealengine\engine\source\runtime\engine\classes\components\inputcomponent.h:692]
[2017.06.24-19.28.29:103][879]LogWindows:Error: UE4Editor-RTSPlugin.dll!ARTSPlayerController::BeginPlay() [c:\dev\ue4-rts\source\rts\plugins\rtsplugin\source\rtsplugin\private\rtsplayercontroller.cpp:26]

The relevant game class ARTSPlayerController is publicly available on GitHub at https://github.com/npruehs/ue4-rts/blob/develop/Source/RTS/Plugins/RTSPlugin/Source/RTSPlugin/Private/RTSPlayerController.cpp

To me, it seems like calling BindAction on an InputComponent is not allowed for connecting clients on server-side. Is that correct?

If that’s the case, how do I avoid this?

I’ve attached the full client and server log for reference.

Thanks for your help!
Nick

Fixed by moving the BindAction calls from BeginPlay to SetupInputComponent.

This in turn is called in APlayerController::InitInputSystem(), which is called in APlayerController::SetPlayer for local players only.

I still think the engine shouldn’t crash in that case, but log an error instead. Will open a pull request :slight_smile:

It’s probably crashing because it doesn’t have an InputComponent at that point and you weren’t checking for a nullptr. All input should be setup in SetupPlayerInputComponent. Clients run things in different orders to the server a lot of the time and you can never guarantee that code that runs on a server will also run reliably on a client.

Also from a design standpoint, I wouldn’t recommend storing an actor iterator to calculate bounds for a camera, but instead create a custom volume that a level designer places in the world and get the min/max bounds from that, or even setting it in World Settings. Since the world size probably never changes, it’s safer and cheaper.

Also, you’re storing an old version of the actor iterator as soon as you spawn a new actor.

Hey TheJamsh!

Thanks for the answer :slight_smile: Yes, I got up a night, suddenly having an idea what could be causing trouble here, remembering the good old Unreal 3 times. My own answer just had to be approved by a moderator first.

Actually, the camera bounds actor is placed by the level designer. I felt a little helpless accessing that one in code, is there any safer and cheaper way of doing that in C++?