Hi guys, seems like there is very little information on how to make Mover plugin work. I had to spent some time figuring things out by myself and I want to share my experience.
The source of knowledge is MoverExamplesContent. Maps there get you nice overview of Mover capabilities, while MoverExampleCharacter cpp shows the code that make things work. Obviously you can take a look yourself, also copy code from there. Don’t forget to check MoverExamples in Plugins.
The least effort way to get things working is just to copy MoverExamplesCharacter, also AnimatedMannyPawn/Extended. Then add NavMovement if necessary.
PathFollowingMannyPawn kinda shows how NavMovement works, but honestly it has code that is mostly example-specific and you do not want to extend/copy it.
But what if we want our own Mover Pawn?
Obviously you will need the things that will be moved. Collision component (I used Capsule) + mesh will do.
One might think: just add (Character)MoverComponent, set MovementModes, add NavMover for AI and it will just work… It’s almost there, but not quite.
The inconspicuous requirement for Mover (and NavMover/AI) to work is IMoverInputProducerInterface and ProduceInput_Implementation (in CPP).
I have no idea how to implement ProduceInput in BP since OutInputCmd is purely output parameter… But we do seem to need it as input aswell.
At this point you just copy ProduceInput implementation from MoverExamplesCharacter, if you want delete “SpringComp = FindComponentByClass…”. Flying and Jump are up to you.
Add variables ProduceInput depends upon into your own class.
Also consider copying code of GetNavAgentLocation().
When we’re done with setting our class either easy or hard way:
AI Movement (AIMoveTo, MoveToLocation etc) should work already. You are not required to use NavWalking mode.
Usual (player) input requires you modifiying CachedMoveInputIntent. SImply exposing it to BP and then setting it straight from InputAction works. Or RequestMoveByIntent.
Some more advanced knowledge:
Mover variable access works in an unusual way, it uses some sort of dynamic composition. So you cannot just Object.Variable. You’ll have to dynamically find types that actually hold those variables, like SyncState or SharedSettings. CharacterInputs in ProduceInput is one of the examples.
Or how to access SyncState variables:
MoverComponent->GetSyncState().SyncStateCollection.
FindDataByType<“FMoverDefaultSyncState>”();
Troubleshooting AI:
Use VisualLogger, draw debug arrow etc,
Make sure your components are valid. Even if they seem to be valid in BP, it might not be the case in CPP. Navigation code might not tell this is the case. It will just fail and very deep inside the engine code you may find out that Navigation just can’t get starting location.
Also also: AI-controlled Mover pawns are prone to twitcing uncontrollably (changing movement direction to opposite and back). It is mitigated by setting AcceptanceRadius but not entirely. You may try to fix it for good yourself by modifying ProduceInput… But it’s not a trivial task. I tried and I’d rather wait for Epic now. Tho it’s no wonder for Experimental plugins.