0
\$\begingroup\$

I'm currently working on a small simulation of Newton's Law of Gravitation in Unity3d, and it seems to be working pretty well, except, it's doing the opposite of what I expected. Instead of attracting as it should, this script is repelling objects instead:

using UnityEngine;

/// <summary>
/// Gravity component.
/// </summary>
public class GravityComponent : MonoBehaviour 
{
    public float gravityConstant;
    public Vector3 startingForce;
    public GameObject twinObject;

    /// <summary>
    /// Applies attraction to the object.
    /// </summary>
    public void ApplyAttraction()
    {
        Vector3 currentForce = this.transform.position - this.twinObject.transform.position;
        float attraction = 
              ((this.gravityConstant * this.rigidbody.mass * this.twinObject.rigidbody.mass)
            / (Mathf.Pow(currentForce.magnitude, 2)));
        this.rigidbody.AddForce(currentForce * attraction);
    }

    public void Start()
    { this.rigidbody.AddForce(this.startingForce); }

    public void FixedUpdate()
    { this.ApplyAttraction(); }
}

While it is possible to "fix" this by making the result of the attraction calculation negative as seen below, this solution feels "dirty", as it's not truly following Newton's Law of Gravitation.

float attraction = 
      -((this.gravityConstant * this.rigidbody.mass * this.twinObject.rigidbody.mass)
    / (Mathf.Pow(currentForce.magnitude, 2)));

What's the issue here? Is there a way to solve this issue without the above "dirty" fix?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Firstly, while your variable may be named currentForce, it actually only contains the vector pointing from this to this.twinObject. Furthermore, with your addition, the subtraction actually points toward the first object. Think of vector a in this image to be your this.transform.position and vector b as your this.twinObject.transform.position.

Vector Substraction

So, since the vector is pointing from b to a, the vector is pointing in the opposite direction of the direction you actually want a to go in. You want to be going toward b.

To fix this just subtract b - a instead of a - b:

Vector3 currentForce = this.twinObject.transform.position - this.transform.position;
\$\endgroup\$
1
\$\begingroup\$

This line:

Vector3 currentForce = this.transform.position - this.twinObject.transform.position;

This gets you a vector pointing from twinObject toward yourself. By applying a force in that direction, you end up pushing yourself away from twinObject.

Think of it using one-dimensional numbers:

int difference = 5 - 2;
//difference is now 3
//difference points from 2 toward 5

Your solution multiplies currentForce by negative one, which flips the direction back to match your desired result. It's a minor kludge, but it works in a pinch. When I find myself doing that, I usually figure I've flipped the direction of a vector accidentally.

You can also fix this by flipping the operands for the subtraction:

Vector3 currentForce = this.twinObject.transform.position - this.transform.position;
\$\endgroup\$

You must log in to answer this question.

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