Top Down Movement with AddForce()

I’m making a top down shooter. To make the enemies (and player) move I use the MovePosition function.

When a bullet hits an enemy it pushes the enemy using AddForce. The problem is: this force is overwitten by MovePosition right after being added.


I thought about using AddForce instead of MovePosition and somehow cap the max speed of the enemy, but I think that it will also cap the force that the bullet adds to the enemy.

What’s the best way to do this?


Here’s my movement script:

public class EnemyMovement : MonoBehaviour
{
    public Rigidbody2D body;
    public Rigidbody2D player;
    public float speed = 3f;

    public int stopTime;

    void Start()
    {
        player = null;
        stopTime = 0;

        GameObject temp = GameObject.Find("Player");
        if (temp) player = (Rigidbody2D) temp.GetComponent("Rigidbody2D");
    }

    void FixedUpdate()
    {
        if (stopTime > 0) stopTime--;

        if (stopTime == 0 && player != null)
        {
            Vector2 direction = (player.position - body.position).normalized;
            body.MovePosition(body.position + direction * speed * Time.fixedDeltaTime);
        }
    }
}

The way I am dealing with this at the moment is to not let the enemy move for a few frames when a external force is applied (thats what the variable stopTime is for), but I was hoping to find a better way to deal with this problem.

Definitely not an expert on physics movement controllers, but maybe you could use AddForce with a high friction value (or, even better, implement your own friction) that way you will have a terminal velocity for movement but you can still add higher impact forces if you want. The friction could be as simple as multiplying your velocity by like 0.8 or something each frame.
**
It also seems like using a force model will make your movement less snappy… have you thought about not using physics at all? You could use MovePosition to move the character, then keep track of impact physics yourself as a Vector3 that is added to the movement commands every frame and is scaled down every frame as well, something like

Vector3 externalForces; //Add a value here on bullet impact
float friction = 0.8f;

void Update(){
    rigidbody.MovePosition(movement + externalForces);
    externalForces *= friction;
}