InputBindings on UObjects issue with delegates

Hey dear community,

i have an InputSystem using Proxy-Pattern for Inputbindings.

So instead of asking whether to bind InputBindings in Controller/Pawn and co. I have ProxyClasses implementing the bindings for specific tasks. F.e. PawnInputProxy binds every action/axis for Pawnrelated Functions.
This gives me the convinience of ignoring the case which pawn is currently controlled. The Proxy will always call GetPawn from the controller to get the correct object.

Though this works very well im experiencing an issue (probably through the garbage collection):
Note: The Proxy is a UPawnInputProxy (UObject as Base)

  • OnBeginPlay: I instantiate a PawnInputHandler (owner is PlayerController) -> Call SetupInputBindungs with the Controller`s Inputcomponent

  • PawnInputHandler creates a constant PawnProxy and then binds the desired functions like: (“BindAxis(“MoveForward”, ProxyObject, UPawnInputProxy::Move_Forward)”)

  • When Moveforward was pressed it will call the Proxy Function and inside we would: (“Controller->GetPawn()->MoveForward(value)”).

  • This works well for some time in game. But at some point all delegates are unbound and no Input is handled anymore.

  • It feels like some important mechanism is returning false and so it unbounds the delegates. Considering the almost randomness of this event, i assume something gets garbage collected but shouldnt.

  • The system works of course if i SetupInput in Pawn or Controller.

A question would be if UObject might be the case for this, so its not intended to bind mappings to an UObject instance. Ive checked if the inputhandler and proxy became invalid, but they are still valid after break…

Any suggestions?

kinf regards

Just an idea of mine:

  • I noticed i havnt called object->AddToRoot(), after i created my UObject. Could this be the issue? What exactly does this function do?

Seems to work now with AddToRoot. Thanks for your hint @anonymous_user_3a8723ae ;D

It prevents your object from being garbage collected (at least until the engine shuts down or you’re calling RemoveFromRoot() again). Internally it does nothing but set/unset a flag on your object that’s used by the garbage collector to check whether it may destroy your object.
Instead of using AddToRoot, you could have also created a UPROPERTY for your object. As long as the object that has this UPROPERTY is not destroyed (e.g. the Pawn or Controller), any raw UObject pointer UPROPERTY members will also not be garbage collected.

@UnrealEverything

Thanks for your input :wink: