Spawned objects won't stop moving after instantiating. 2D Top-Down

	void SpawnCoins()
	{
		for (int i = 0; i < coinDrops; ++i) //Spawns an amount of coins
		{

			GameObject coin = Instantiate(coinPrefab, transform.position, Quaternion.identity) as GameObject;


			Vector3 targetPosition = new Vector3(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f), 0);
			Rigidbody2D rb = coin.GetComponent<Rigidbody2D>();

			rb.AddForce(targetPosition * speed);

			Debug.Log("Adding force");
			if (Vector2.Distance(coin.transform.position, targetPosition < 1f) //this part isn't working
			{
				rb.velocity = Vector2.zero;
				Debug.Log("It's going through.");
			}

		}
	}

Also, tried:

			if (coin.transform.position == targetPosition) 
			{
				rb.velocity = Vector2.zero;
				Debug.Log("It's going through.");
			}

So, I’m spawning coins after an enemy dies. After the coins instantiate, I want them to burst out in random directions and move a small distance away, and then stop. I can get a set amount of coins to spawn and they do move in random directions…but they won’t stop moving. I would like help to figure out how to stop the coins.

I’ve used a debug.log to check if the “if” statement was going through, and it wasn’t.

I’ve also tried moveTowards, but the coins just teleport to the target position. I’m guessing this is because it’s not being called in the Update function. But I’m not sure how to reference the instantiated coin gameobject outside of it’s own function. When I made it public, I got errors.

Any help/suggestions would be very much appreciated!

I see 2 issues:

THE CHECK MUST RUN OVER TIME

This is happening because you call the method once and not over time.

Basically this is what happening:

  • Spawn
  • Addforce to rigidbody
  • Check the distance just in the same frame
  • End

This means the rigidbody had not the time to move away.

To solve this in the same script you can use a coroutine (otherwise you can add a monobehaviour to the spawned object and use its update loop).

THE CHECK MUST BE DONE AGAINST A POSITION

This:

Vector3 targetPosition = new Vector3(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f), 0);

Gives you a direction between (-1f,-1f) and (1f,1f). While I think you should check against a position that should be something like:

PositionToCheck = targetPosition  + coin.transform.position.

SOLUTION

You may implement the coin as monobehaviour like this:

1 - Create the monobehaviour for the coin

[RequireComponent(typeof(Rigidbody2D))]
public class CoinStopper : MonoBehaviour
{
    // --------------- DATA TO CHECK THE SPEED --------------- //
    //the position we want the coin to reach
    private Vector2 _positionToReach;
    //the rigidbody
    private Rigidbody2D _rb;

    public void SpawnCoin(Vector2 direction, float speed)
    {
        //first thing we calculate the position to reach
        _positionToReach = (Vector2) transform.position + direction;
        //caching the rigibopdy
        _rb = GetComponent<Rigidbody2D>();
        //add the force
       _rb.AddForce(direction * speed);
    }
    
    
    //we use fixed update because this is related to a physics logic
    private void FixedUpdate()
    {
        //we keep checking in the fixed update
        if(Vector2.Distance(transform.position, _positionToReach) > 1f)
            _rb.velocity = Vector2.zero;
    }
}

2 - Add this monobehaviour to your Coin prefab.

3 - Update the spawner code with this

void SpawnCoins()
    {
        for (int i = 0; i < coinDrops; ++i) //Spawns an amount of coins
        {
            //instantiate the coin
            GameObject coin = Instantiate(coinPrefab, transform.position, Quaternion.identity) as GameObject;

            //calculate the position
            Vector3     targetPosition = new Vector3(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f), 0);

            //send the logic directly to the coin
            var coinStopper = coin.GetComponent<CoinStopper>();
            coinStopper.SpawnCoin(targetPosition, speed);                
        }
    }

------EDIT
Changed from coroutine to update in a specific monobehaviour.