1
\$\begingroup\$

I have set of pipes(edge colliders) in my scene, through which I pass the ball.

     ____|  |  <---Edge colliders
   o _______|

How do I move the ball in upward direction. For above this pipe I have to move along the positive x direction first, then positive y direction. How can I detect that.?

mRigidBody.AddForce (new Vector2 (moveSpeed,moveSpeed));

I tried this, but this can be used to move one direction at a time

\$\endgroup\$
3
  • \$\begingroup\$ @MrRobot ? You know that sarcasm doesn't come through the internet \$\endgroup\$
    – Bálint
    Commented May 19, 2017 at 10:49
  • \$\begingroup\$ How do you author these pipes? If they're built from segments or following a spline, that parent segment/spline can be consulted for this kind of structural info. If you're just placing edge colliders manually then we need a more complicated solution that can infer your intent from the arrangement, without it being explicit in the authored data. \$\endgroup\$
    – DMGregory
    Commented May 19, 2017 at 11:42
  • \$\begingroup\$ @DMGregory I have added them manually \$\endgroup\$
    – Aaa
    Commented May 19, 2017 at 11:59

2 Answers 2

1
\$\begingroup\$

What you can do is have your ball fire out whisker rays around it to detect nearby colliders, using 2D raycast methods:

RaycastHit2D hit = Physics2D.Raycast(ballPosition, rayDirection, maxDistance);

(You can add other parameters to limit the ray to only the pipes' physics layer, or specific z-values)

Then for each ray that hits a pipe wall, you can get its normal - a unit vector sticking perpendicularly outward from the edge.

We can do a bit of math on our current velocity to divide it into two parts: one that runs parallel to the wall and one that runs perpendicular to the wall.

float awayDistance = Vector2.dot(hit.normal, rayDirection * hit.distance);
float awaySpeed = Vector2.Dot(hit.normal, body.velocity);

Vector2 perpendicularVelocity = hit.normal * awaySpeed;
Vector2 parallelVelocity = body.velocity - perpendicularVelocity;

To keep the ball in roughly the middle of the pipe, you can apply a repulsive spring force based on the distance the ball is from each wall (awayDistance), and add some damping to the perpendicular velocity. This will help nudge the ball around 90-degree corners like the one in the diagram: it gets repulsed from the floor and the ceiling drops away, so there's no counter-force holding it down. (Just be careful not to double-count walls that get hit by more than one whisker ray)

Then you can apply another force/impulse to keep the length of the parallel component of the velocity close to your target speed, so the ball moves along at a roughly steady rate.

\$\endgroup\$
0
1
\$\begingroup\$

An alternative solution would be to use the physics engine to detect collisions and use effectors to force your ball to move along your pipe. I would typically add an area effector to every section of your pipes to recreate a feeling of flow. This means that your balls will most likely hit and bounce off the walls of your pipes. Here is an example of GameObject with effector to align with one section of your pipe:

inspector shot

A few things to watch:

  1. select collider mask in the Area Effector component to match the layer of your balls
  2. decide if you want gravity to apply or not, this will affect the result that you get
  3. You will most likely need/want to tweak the force magnitude and force variation parameters to get something realistic (or not)

I think that an advantage to rely on the physics engine will be that you can create scenes that are closer from reality. The main disadvantage might be that you have less control during gameplay as things might not always react as anticipated/as they would with scripting.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .