1
\$\begingroup\$

I found a game on the Internet called Sagittarius. This game is very fun, and I have a question: how can I make the arrow move like it does in this game? I know each sphere has a different gravity, but when I try to use this formula, it's not working as I expect=. Can any one help me resolve this problem? Thanks.

  public List<PlanetABC> p = new List<PlanetABC>() { 
    new PlanetABC(){
        x = 0.91f,
        y = -1.28f,
        gravity = 5,
        r = 5
    },
    new PlanetABC(){
        x = 8.12f,
        y = -1.3f,
        gravity = 3,
        r = 10
    }
};
void Start () {

}
void Update () {
    float gravityOnX = 0;
    float gravityOnY = 0;
    foreach (var planet in p)
    {
        if (Vector2.Distance(g.transform.position, new Vector2(planet.x, planet.y)) > planet.r)
            continue;
        if (planet.x > g.transform.position.x)
            gravityOnX += planet.gravity;
        else gravityOnX -= planet.gravity;

        if (planet.y > g.transform.position.y)
            gravityOnY += planet.gravity;
        else gravityOnY -= planet.gravity;
    }

    if (currentGravityX > gravityOnX)
        currentGravityX -= Time.deltaTime;
    else currentGravityX += Time.deltaTime;

    if (currentGravityY > gravityOnY)
        currentGravityY -= Time.deltaTime;
    else currentGravityY += Time.deltaTime;

    Debug.Log(currentGravityX + "/" + currentGravityY);
    var DEG2RAD = Mathf.PI/180;
    float vx1 = Mathf.Cos(angle * DEG2RAD) * power ;
    float vy1 = Mathf.Sin(angle * DEG2RAD) * power;
    float y = (0.5f * currentGravityY * time + vy1) * time;
    float x = (0.5f * currentGravityX * time + vx1) * time;
    Vector3 pos = g.transform.position;
    pos.x = x;
    pos.y = y;
    g.transform.position = Vector3.Lerp(g.transform.position, pos, Time.deltaTime);
    time += Time.deltaTime;
}

Here is the game: https://gprosser.itch.io/sagittarius

\$\endgroup\$
1
  • 2
    \$\begingroup\$ What's happening when you use your existing code? What is it doing that you don't want or expect? \$\endgroup\$ Commented Sep 20, 2016 at 17:37

1 Answer 1

2
\$\begingroup\$

Your method of calculating gravity is unusual. Is there a particular reason you've structured it this way?

A conventional gravity with inverse square falloff would look something like this...

// We're applying physics forces, 
// so for consistency we should do this at a fixed timestep:
void FixedUpdate() 
{
    // Initialize our acceleration to a zero vector:
    Vector2 totalAcceleration = Vector2.zero;

    foreach (var planet in p)
    {
        // Construct an arrow from the projectile to the planet center.
        Vector2 offset = planet.position - this.transform.position;
        Vector2 direction = offset.normalized;

        // Get the distance between the projectile and the planet.
        float distance = Vector2.dot(direction, offset);

        // Accumulate acceleration in the direction toward the planet,
        // with strength proportionate to the inverse square of the distance.
        totalAcceleration += direction * planet.gravity / (distance * distance);
    }

    // Apply the acceleration.
    // (f = ma, so we multiply by mass to convert to a force)
    rigidbody2D.AddForce(totalAcceleration * rigidbody2D.mass, ForceMode.Force);
}

You can integrate these forces yourself if you like, or course. But the built-in physics systems are already made for doing just this sort of work efficiently and stably, so it's not a bad idea to leverage that existing tech.

The major differences from your version are:

  • gravity falls off using an inverse square law, as it does in real-world physics
  • planets have no outer radius (though you could enforce one if you wanted - just beware of introducing discontinuous changes in the force field, which can look strange as the projectile shifts suddenly from one regime to another)
  • accelerations are computed as a vector considering both x and y components, rather than treating the two separately
  • integration and framerate independence is delegated to the physics system
\$\endgroup\$

You must log in to answer this question.

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