I’ve been working on making a simple follower for my player character in a 2D platformer I’m making with paper sprites. I created the follower as a child of the Paper Character Class, gave it a CharacterMovement component, and set a timeline and vector lerp to get it to move from its current location to the location of my player character. Now I’ve moved on to trying to animate the follower, and I’ve noticed something strange happening with the CharacterMovement functions. They don’t seem to update.
I use a function to change the flipbook that the follower uses depending on the value of a boolean called IsMoving. That boolean is determined by the function IsWalking from the CharacterMovement component. So if IsMoving is true, the follower should use its walking flipbook, and if it’s false, it should use its sitting flipbook. However, when I test it, the follower doesn’t stop walking, even when it’s not moving anymore.
In the debug window, I’ve found that IsWalking actually stays true all the time - it doesn’t update to false when the follower stops moving. The same thing happens when I use IsMovingOnGround. I’ve also tried using a separate method for seeing if the follower is moving - I use GetVelocity to see if it’s moving, but that doesn’t work either. Again, when debugging, that value is always at 0, regardless of whether or not the follower is moving. You can see the different attempts I’ve made in my blueprint below.
So how can I get around this? Is there something about using a timeline to move a character that messes with the CharacterMovement component/GetVelocity? Any help would be greatly appreciated.
I don’t know if this is still relevant to you but I think I see the problem, mind you this is just after a cursory glance and after a few drinks. I notice that you aren’t moving your component with “Add Movement Input” function. That function in particular you’re going to want to use for all pawns that have a designated controller (which most should by default barring any “complex” or extra programming on your part to the contrary).
Add Movement Input takes a direction (specifically a vector type, which for all intents and purposes should be normalized, or not have a length greater than 1. There are prepackaged functions that should be able to accomplish that for you if you drag off from a vector and type “normalize”), a scalar value (basically how fast do you want this to move in the direction provided), and a boolean, “Force” (which forces the input even if it should be ignored). Optionally you can specify a target at the top of the node stack if you are affecting an “alien” pawn, or a pawn other than the one you are currently putting this node in.
If you need an example, this is a bit more complicated, but I have an excerpt from a somewhat basic following enemy. The only thing you’ll notice that is not a part of your available functions is my macro DistanceBetweenTwoPoints which is a basic algebraic formula that, as you guessed it, calculates distance between two given 3D points (also works in 2D because math). One last caveat is that I changed my locked plane to a different axis. I think the default is “Y” so you’ll need to leave that as a 0 so you don’t go plane hopping.
to comment on: “Add Movement Input takes a direction (specifically a vector type, which for all intents and purposes should be normalized, or not have a length greater than 1”
The UPawnMovementComponent::AddInputVector c++ documentation does say the vector is “usually normalized.” But it doesn’t need to be. If the input vector(or rather the sum of input vectors) had to be normalized, then handling two simultaneous inputs (say up and right) at the same time would be difficult. At least, it would be difficult ensuring the summed added input is 1.
By that, I mean when moving in a diagonal direction, the accumulated input vector would have a length greater than 1. (adding the vertical vec3(1,0,0) and horizontal vec3(0,1,0) gives vec3(1, 1, 0) – which may make the character run faster in the diagonal direction. In that case, both input vectors are normalized, but the accumulation isn’t.
However, this concern doesn’t appear to be a problem for Unreal. Looking through the code, this AddMovementInput function accumulates input into an “input vector”. This input vector drives the acceleration of the movement component. But before updating the acceleration, the accumulated input vector is normalized (see CharacterMovementComponent::TickComponent calling UCharacterMovementComponent::ScaleInputAcceleration).
So, from reading the code it looks like you can call “Add Movement” Input for up and right during the same frame – and the movement component will take care of normalizing your input direction. So, code checking whether two buttons are pressed shouldn’t be necessary.