Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Trying to emulate Gravity around objects, need a little help fine tuning

Discussion in 'Scripting' started by UpcomingChris, Jul 4, 2022.

  1. UpcomingChris

    UpcomingChris

    Joined:
    Feb 11, 2011
    Posts:
    201
    Hey guys, messing around in unity, making a little orbit game, you fire a projectile and it'll orbit the 'earth' using AddForce (I know there's other, better ways to do this, but I'm trying to figure it out this way, simply because I like to try and do as much as I can from my head, without following guides and such, it's a little personal challenge, of sorts. I have 2 planets, and when I get closer to one, that will become the main target you will orbit around, works well, only thing is, I'd like to try to somehow have it so, the closer you get to the object, the more force is pushing you towards that object.

    Here's my script that works.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Attractor : MonoBehaviour
    6. {
    7.  
    8.     public GameObject earth;
    9.     public GameObject moon;
    10.     float G = 0.6f;
    11.     public Rigidbody2D rb;
    12.  
    13.     void FixedUpdate()
    14.     {
    15.         rb = GetComponent<Rigidbody2D>();
    16.         Vector3 directionToEarth = rb.transform.position - earth.transform.position; //works
    17.         Vector3 directionToMoon = rb.transform.position - moon.transform.position;
    18.         float distanceToEarth = directionToEarth.magnitude; //works
    19.         float distanceToMoon = directionToMoon.magnitude;
    20.  
    21.         if(distanceToEarth <= distanceToMoon)
    22.         {
    23.          rb.AddForce(earth.transform.position - transform.position);  //need to figure out how to make the force more, when closer, smoothly.
    24.         } else if (distanceToMoon <= distanceToEarth)
    25.         {
    26.             rb.AddForce(moon.transform.position - transform.position);
    27.         }
    28.      
    29.      
    30.     }
    31.  
    32.  
    33. }
    34.  
    What I want to do I think might be quite simple, I'm just not sure how to go about it, the closer you get to whatever you're orbiting, the more force is added, so you can 'slighshot' so to speak, around objects better.

    Any help is appreciated :)
     
  2. FlashMuller

    FlashMuller

    Joined:
    Sep 25, 2013
    Posts:
    449
    You are already using the distance in your code. Inversing that based on a maxDistance and using it as a factor should do the trick.
    Somewhat like this:
    Code (CSharp):
    1.  
    2. float maxDistance = 10f;
    3. factor = 1f + (Mathf.Clamp(10f - distanceToEarth, 0f, 10f) / maxDistance); //will give you a factor between 1 and 2
    4. rb.AddForce((earth.transfrorm.position - transform.position) * factor);
    5.  
     
  3. karliss_coldwild

    karliss_coldwild

    Joined:
    Oct 1, 2020
    Posts:
    530
    Awesome! That's a great attitude. Although if you want to challenge yourself and learning for me the priority of information resources would be:
    • your head
    • general information resources like API documentation, physics textbook, ...
    • tutorials/guides for specific situation
    • ask someone in a forum (preferably a specific question not how do I do this)
    So I'll try to help without too much spoilers. My recommendations are:
    • Take a look at physics textbook how the gravity force is calculated. https://en.wikipedia.org/wiki/Newton's_law_of_universal_gravitation is also good enough. You can ignore the units just tweak the constants until things look pleasing for the game.
    • In case of multiple planets attracting a things just add the forces together. If everything is correct it should just work. An apple falling to earth doesn't magically know that earth is closer than moon. This also helps with smoothness. Any kind of ifs in motion equations are potential source of discontinuity and sudden jerks.
    • Get familiar with https://docs.unity3d.com/ScriptReference/Vector3.html and what each function there does
     
  4. UpcomingChris

    UpcomingChris

    Joined:
    Feb 11, 2011
    Posts:
    201
    I'll have a read though, thank you!
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    Just a little note, using "rb.transform.position" isn't where the Rigidbody2D is. Using ".transform" on any component just gets the Transform on the same GameObject. The Transform on a GameObject that has a Rigidbody2D isn't necessarily the same if you're using interpolation/extrapolation. This is why you should use Rigidbody2D.position which is the real position of the physics body.
     
  6. UpcomingChris

    UpcomingChris

    Joined:
    Feb 11, 2011
    Posts:
    201
    Oh interesting, ok, Thanks for the input
     
    MelvMay likes this.
  7. UpcomingChris

    UpcomingChris

    Joined:
    Feb 11, 2011
    Posts:
    201
    Would you be able to explain a little what this is doing exactly?, I've looked at it and fiddled with it for a while, I can't seem to fully understand what is happening in that bit of code, I'd like to try to understand it better!

    changing the numbers and messing around seems to not really have much, if any impact (Granted, I'm probably doing it wrong due to not understanding what it actually happening here)
    It would be really appreciated!
     
  8. FlashMuller

    FlashMuller

    Joined:
    Sep 25, 2013
    Posts:
    449
    I have changed and commented the code. Hope it helps.
    Code (CSharp):
    1.  
    2. float maxDistance = 10f; //This is the distance to the Object, at which an effect will start to take place.
    3. //If you want gravity to increase at a Distance of 100f, insert 100f.
    4. float multiplyer = 5f; //Just a variable to easily adjust the effect
    5. factor = 1f + (Mathf.Clamp(maxDistance - distanceToEarth, 0f, maxDistance) / maxDistance);
    6. //This is where the magic happens: maxDistance - distanceToEarth will increase the closer you get.
    7. //It is clamped to stay positive and smaller then maxDistance.
    8. //By dividing it with maxDistance it becomes a number between 0 and 1.
    9. //This is added to one so that our factor will always increase (> 1f) the force
    10. factor *= multiplyer; //Use the multiplyer to your interest
    11. rb.AddForce((earth.transfrorm.position - transform.position) * factor);//Apply factorized force