0
\$\begingroup\$

I'm working on some special pick ups on an arkanoid-like game. Currently, I have one that should spawn several balls all in a row, right after the original ball hits the paddle. All the additional balls should spawn just above the paddle and then they are passed the vector from the original ball, in which case they should follow that vector, essentially causing a line of balls all traveling in the same direction. The problem I am having is the ball's spawn just above the paddle, but they are spawning in place. Gravity pulls them down, and when they hit the paddle, that seems to be when the vector becomes active and the ball takes off like it should have when it spawned. I'm not sure what I am doing wrong here to keep it from just taking off like that as soon as it spawns. Can anyone see anything here that could be causing this behavior?

This is the code for spawning a ball and setting the vector.

  Instantiate(newBall, new Vector3(paddle.transform.position.x, (paddle.transform.position.y + 1), 0), Quaternion.identity);
    newBall.GetComponent<Ball>().hasStarted = true;
    GameManager.pickUpManager.allBalls.Add(newBall.GetComponent<Ball>());
    newBall.GetComponent<Rigidbody2D>().AddForce(mainBallVector, ForceMode2D.Impulse);      //use the original ball's vector3 to follow it directly

Here is where mainBallVector gets set, it is a vector3:

  mainBallVector = mainBall.GetComponent<Rigidbody2D>().velocity;
\$\endgroup\$
  • \$\begingroup\$ Can you show us how you calculate mainBallVector? What units is it in? \$\endgroup\$ – DMGregory Aug 4 '18 at 4:20
  • \$\begingroup\$ added that info in the edit, sorry about that. \$\endgroup\$ – ethan codes Aug 4 '18 at 4:34
1
\$\begingroup\$

Don't forget to capture the instance of the ball you've just spawned (returned by the Instantiate method) - otherwise your subsequent lines accessing newBall are acting on the prefab you spawned it from, not the new instance.

eg.

// At the top of your script:
public Ball ballPrefab;

// ... in your spawning method:

var ball = Instantiate<Ball>(
            ballPrefab, 
            (Vector2)paddle.transform.position + Vector2.up, 
            Quaternion.identity);

 ball.hasStarted = true;
 GameManager.pickUpManager.allBalls.Add(ball);

 ball.GetComponent<Rigidbody2D>().velocity = mainBallVelocity;     

You'll note I changed the last line, because your code had a mismatch between the way you read the vector from the main ball (as velocity), and the way you applied it to the new ball (as an impulse).

If we call 1.0 worldspace units a meter, then velocity has units of meters per second, and impulse has units of Newton seconds (or kg m/s)

So for objects with a mass other than one, these two numbers won't agree. If you just want to overwrite the new ball's velocity to exactly match the main ball's, assigning it directly is probably the simplest & clearest way.

Or if you want to continue using AddForce, don't forget to scale up your velocity by the ball's mass to convert it to a desired change in momentum for use as an impulse.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.