Curious extra movement when stopping an ability

DankP3

Active member
Apologies for the vagueness. I have just a draft of a custom movement type (essentially like point and click with the point and click removed!). I am using my own pathfinding grid and pathfinding solution and navigating that grid with an ability that follows the waypoints. I am driving the movement by calculating an inputvector and rotating the character in UpdateRotation and tweaking the movement in ApplyPosition. I see my issue without any rotation code. Here is ApplyPosition:

Code:
public override void ApplyPosition() {
            Vector3 moveDirection = m_CharacterLocomotion.MoveDirection;
            if (m_ArrivedAtDestination) {
                moveDirection = m_PathList[m_TargetIndex].transform.position - m_Transform.position;
                moveDirection.y = 0;
                if (moveDirection.magnitude < 0.01f) {
                    Scheduler.ScheduleFixed(1f, Stop);
                }
            }
            else if (m_TargetIndex == 0) {
                if (moveDirection.magnitude > m_DesiredDirection.magnitude) {
                    moveDirection = m_DesiredDirection;
                }
            }
            m_CharacterLocomotion.MoveDirection = moveDirection;
        }

In short, when m_ArrivedAtDestination is true (the last waypoint is reached), the code tampers with the MoveDirection to perfectly align the character to the tile and then it stops the ability. However, you will note, I am stopping the ability with the scheduler. This is fine with my use case, but I am not sure why this is necessary? If I stop the ability directly as soon as the criteria are met some extra movement comes from somewhere and the character always overshoots. This still happens with a very short schedule time, but doesnt when the schedule time is increased, eg. maybe above 0.3-0.4 seconds.

Hopefully this clarifies what should happen, correct movement: https://drive.google.com/file/d/1zb5_93eNRvNDh_2wR3isuWCWTICulh5b/view?usp=sharing

you'll see that the movement ends with the character correctly in the tile's centre (character moving down the picture with the grid marking the tiles):
Delayed.PNG

Without a delay it overshoots:
noDelay.PNG

The odd thing is that the debug says the character is in the correct position and hence the MoveDirection is calculated correctly as Vector3.zero, but as soon as the ability stops it drifts that bit forward and the position reports incorrect. (Inputvector is being set as Vector2.zero at this point - when m_ArrivedAtDestination = true).

So the question: Given that I am overriding position and inputvector, what time sensitive thing am i overlooking that is moving the character forward as the ability is stopped? presumably something is running down that i need to zero out manually?

(I appreciate the code can be optimised, but i wanted to understand the working before moving to that)

Thanks
 
I assume you're not using root motion on the character's animator? You may also need to ensure that the character's input vector is [0,0] - you said you're using a custom movement type, so you could do this in GetInputVector (would be useful to see your custom movement type either way).
 
Yes, i am not using rootmotion and I am artifically setting the inputvector to Vector2.zero, maybe i will go debug the animator values...
 
Sorry, missed your other question, my movement type is basically 'empty':

Code:
public override float GetDeltaYawRotation(float characterHorizontalMovement, float characterForwardMovement, float cameraHorizontalMovement, float cameraVerticalMovement)
        {
            return 0;
        }
        public override Vector2 GetInputVector(Vector2 inputVector)
        {
            return Vector2.zero;
        }

and in the ability I am setting the InputVector just like MoveTowards via:
Code:
m_CharacterLocomotion.InputVector = GetInputVector(m_Transform.InverseTransformDirection(m_DesiredDirection));

Certainly the Animator values had dampening. but removing that doesnt effect the overshoot.
 
When the ability stops are you setting the AbilityMotor back to Vector3.zero? This value is not cleared automatically so I am thinking that the extra movement comes from that value still being set.
 
Yep, that doesn't stop it. The only thing i have found that works is to schedule the StopAbility, which makes me think something is residual somewhere, but failing a solution, the schduler is robust and this is more about precision than speed in my use case.
 
Hmm, if it's not the AbilityMotor then it must be something else. The movement is applied within CharacterLocomotion.UpdatePosition. What variable is not zero when it is being added to m_MoveDirection?
 
m_MoveDirection, m_ExternalForce and m_MotorThrottle all at Vector3.zero (1 decimal place) before and after stop being called. I didnt check the gravity, but i have gravity at world down.
I asume there should be no minor collision events? i am on flat ground
 
If m_MoveDirection is 0 then the character shouldn't be moving. All of the collision detect has been performed at that point. Are you managing the movement at all outside of the character loop?
 
Top