Skip to content

Instantly share code, notes, and snippets.

@oliverholmberg
Last active February 21, 2023 10:26
Show Gist options
  • Save oliverholmberg/de738361a07246991b56 to your computer and use it in GitHub Desktop.
Save oliverholmberg/de738361a07246991b56 to your computer and use it in GitHub Desktop.
Orbital Gravity 2D - A demonstration of Orbital Gravity in a 2D Unity Game. Unity's standard physics engine implements gravity only in the vertical axis. Here's a demo of orbital gravity for space type games. It allows for one object (spaceship, satellite, etc.) to achieve a stable organic orbit around another object (planet, moon, star, etc.)
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
// Intended to be attached to a GameObject in order for that object to have its own gravity.
// Standard Unity Gravity is disabled on objects implementing this class
// This class is pared down from the original WorldBodyController used Oliver Holmberg's game Apogee to simply demonstrate orbital gravity.
public class OrbitalGravityObject : MonoBehaviour {
// Physics settings
// The relative mass of the object
public float mass;
// The radius of the "sphere of influence" This can be set to infinity (or a very large number) for more realistic gravity.
public int soiRadius;
// Used to alter (unatuarally) the coorelation between the proximity of the objects to the severity of the attraction. Tweak to make orbits easier to achieve or more intersting.
public int proximityModifier = 195;
// On init of obj
void Start() {
mass = mass * 100000; // Mass ^ 5 in order to allow the relative mass input to be more readable
}
// Creates a visual representation of the sphere of influence in the editor
public void OnDrawGizmos() {
// Show the Object's Sphere Of Influence
Gizmos.DrawWireSphere (transform.position, soiRadius);
}
void FixedUpdate () { // Runs continuously during gameplay
// Get all objects that will be affected by gravity (Game objects are tagged in order to be influenced by gravity)
GameObject[] objectsAffectedByGravity;objectsAffectedByGravity = GameObject.FindGameObjectsWithTag ("affectedByPlanetGravity");
foreach (GameObject gravBody in objectsAffectedByGravity) { // Iterate through objects affected by gravity
Rigidbody2D gravRigidBody = gravBody.GetComponent<Rigidbody2D> (); // Get the object's Rigid Body Component
float orbitalDistance = Vector3.Distance (transform.position, gravRigidBody.transform.position); // Get the object's distance from the World Body
if (orbitalDistance < soiRadius) { // If the object is in the sphere of influence (close enough to be affected by the gravity of this object)
// Get info about the object in the sphere of influence
Vector3 objectOffset = transform.position - gravRigidBody.transform.position; // Get the object's 2d offset relative to this World Body
objectOffset.z = 0;
Vector3 objectTrajectory = gravRigidBody.velocity; // Get object's trajectory vector
float angle = Vector3.Angle (objectOffset, objectTrajectory); // Calculate object's angle of attack ( Not used here, but potentially insteresting to have )
float magsqr = objectOffset.sqrMagnitude; // Square Magnitude of the object's offset
if ( magsqr > 0.0001f ) { // If object's force is significant
// Apply gravitational force to the object
Vector3 gravityVector = ( mass * objectOffset.normalized / magsqr ) * gravRigidBody.mass;
gravRigidBody.AddForce ( gravityVector * ( orbitalDistance/proximityModifier) );
}
}
}
}
}
@ovbm
Copy link

ovbm commented Jul 31, 2017

Hey, great work - I just found two little typos when trying it out:
line 13
public int soiRadius
should be:
public int soiRadius;

line 53
massToUse
should be:
mass

thx!

@davecdempsey
Copy link

Good work!

I would move the code inside in the FixedUpdate into a physics trigger collider. Doing FindGameObjectsWithTag every FixedUpdate is very performance intensive.

Depending upon 2D or 3D aspect of the game, OnTriggerEnter or OnTrigger2D you can check the tag of the object being triggered. That way you can also just use the trigger size as checking the distance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment