I am trying to get a line of spheres to move around but all i get is the first sphere to move and get the rest to follow as one instead of building a sort of a train of spheres. Any idea how to alter the code to get it right? In the code bellow i get the first pbject in listBalls to move nicely along the Bezier curve but the rest move as one and overlap with the first sphere too.

    void Update()

    t += Time.deltaTime * 0.2f;
    ballPosition = Mathf.Pow(1 - t, 3) * p0 + 3 * Mathf.Pow(1 - t, 2) * t * p1 + 3 * (1 - t) * Mathf.Pow(t, 2) * p2 + Mathf.Pow(t, 3) * p3;
    listBalls[0].transform.position = positions[j];
    for (i = 1; i < listBalls.Count; i++)
        Transform ball = listBalls[i].transform;
        Transform nextBall = listBalls[i - 1].transform;
        if ((ball.position - nextBall.position).magnitude > 1f)
            ball.position = positions[j];

Feels like it should be something easy, setting the N-1 balls to same position as the first ball must be wrong. I tried setting them at positions[j-2] but it didn't work either.

Edit: the Spheres should start rolling left to right one after the other eventually all 10 should be on the screen and when they reach P3 they should restarting the rolling.

  • listBalls is the List with 10 spheres
  • positions is the List with 50 Vector3 positions along the curve.

enter image description here

[![enter code here][2]][2]
  • \$\begingroup\$ It's not clear to me what kind of movement you want here. Can you edit your question to include a diagram to walk us through how the game should start, how it should look next frame, and a few frames after that? \$\endgroup\$ – DMGregory Aug 2 at 15:34

It looks like you want something like this:

t += Time.deltaTime * 0.2f;

ballPosition =     Mathf.Pow(1 - t, 3)                   * p0 
             + 3 * Mathf.Pow(1 - t, 2) * t               * p1
             + 3 * (1 - t)             * Mathf.Pow(t, 2) * p2
             +                           Mathf.Pow(t, 3) * p3;

// Put first ball at the last position in the list. It's our first "leader"
int positionIndex = positions.Count - 1;
Vector3 leaderPosition = positions[positionIndex];
listBalls[0].transform.position = leaderPosition;

for (i = 1; i < listBalls.Count; i++)
    // Back up through the positions list until you find one that's 1.0 units
    // or further behind our current "leader" ball.
    do {
    } while ( (positionIndex >= 0 )
         && ( (positions[positionIndex] - leaderPosition).sqrMagnitude < 1f*1f )

    // If we exhausted our available positions, abort
    // and leave the rest of the balls where they are.
    if(positionIndex < 0) break;

    // This position becomes our new leader for the next ball to follow.
    leaderPosition = positions[positionIndex];

    // Position our current ball at this leader position.
    listBalls[i].transform.position = leaderPosition;

// Once the whole train of balls has moved past the start of the list,
// we can remove old positions to keep the list from growing without bound.
if(positionIndex > 0);
positions.RemoveRange(0, positionIndex);

// For efficiency, note that using a circular buffer here will save you the
// copying cost of shifting all the list entries down each time.
| improve this answer | |
  • \$\begingroup\$ why isn't (positions[positionIndex] - leaderPosition) always 0? They are both based on positionIndex and it seems to me that the While condition should always be satisfied (until positionIndex < 0). \$\endgroup\$ – mavish Aug 14 at 23:49
  • 1
    \$\begingroup\$ Try stepping through the code. positionIndex changes between the setting of leaderPosition and the condition you asked about. \$\endgroup\$ – DMGregory Aug 14 at 23:54

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.