Rigidbody2D.AddForce on randomly spawned object causing force to fluctuate

I’m working on a super basic 2D arcade style game. I have enemies spawning at a random position in the playing space facing toward the player, then moving in a straight line toward the direction they face. I’ve created a variable posDelta to calculate the rotation the enemy should spawn with (in order for them to be looking at the player).

However, when I try to use AddForce() the only way I can get the enemy to travel in the direction they are facing is to use the same posDelta variable as the Vector2 when calling AddForce. This works, but when I multiply that vector by the movement speed variable it causes the speed of the object to be influenced by its random spawn position, as each instantiated enemy will have a unique posDelta.

I’m fairly new to both Unity and scripting, and after hours looking for and trying every solution I can find, I’m stuck. Is there a way to use posDelta as the direction of force while modifying speed in a different place? Am I just missing something obvious?

Thanks in advance :slight_smile:

  public Rigidbody2D enemyRb;
    public float moveSpeed = 5;
    private GameObject player;
    private Vector3 posDelta;
    private Quaternion lookRotation;

    void Awake()
    {
        enemyRb = GetComponent<Rigidbody2D>();
        player = GameObject.Find("Player");
    }
    // Start is called before the first frame update
    void Start()
    {
        //Find delta between player and enemy
        posDelta = (player.transform.position - transform.position);

        SetRotation();

    }

    // Update is called once per frame
    void Update()
    {

    }

    void FixedUpdate()
    {
        MoveEnemy();
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            Debug.Log("Player Hit");         
        }
    }

    void MoveEnemy()
    {
        //Add Force in the direction of movement * movemenet speed
       enemyRb.AddForce(posDelta * moveSpeed * Time.deltaTime, ForceMode2D.Impulse);
    }

    void SetRotation()
    {
        //Find relative position
       var relativePos = player.transform.position - transform.position;

       //Calculate rotation needed to face target
       var zAngle = Mathf.Atan2(relativePos.y, relativePos.x) * Mathf.Rad2Deg;
     
       //Rotate enemy by zAngle
       enemyRb.transform.Rotate(0, 0, zAngle);

    }

You need to scale the posDelta vector so that it’s length is 1. It can be done by dividing it by length. posDelta / posDelta.magnitude . This process is also called normalization. But since it’s a common operation there is builtin method which does it posDelta.normalized

You should never change the Transform directly on a GameObject when using 2D physics. Always go through the Rigidbody2D API. The above call isn’t a transform of the Rigidbody2D, just a way to get the Transform on the GameObject.

Also, when referring to the actual position or rotation, read the Rigidbody2D as it is in control of writing to the Transform and is the authority. For instance, if you’re using interpolation then the Transform (for visuals) is always “behind” where the body is because obviously interpolation is moving from the previous body positon to the current one.

What does this scaling do as it relates to achieving consistent speeds? When I updated my code to normalize the posDelta it still causes speeds to vary based on the object’s (random) instantiation position. Am I missing something?

I’m not sure I understand the difference between going through the Rigidbody2D API and what I did. If calling on the Rigidbody2D component just goes to the transform of the GameObject, should I be calling something else?