itch.io is community of indie game creators and players

Devlogs

Planet Rider --- Gravity implementation

Planet rider
A browser game made in HTML5

In this devlog I will explain how I implemented the gravity for my game.

I made a script based on something I found on this forum. It uses 

foreach (Collider collider in Physics.OverlapSphere(transform.position, pullRadius))

I had to adapt this line to 

foreach (Collider2D collider in Physics2D.OverlapCircleAll(transform.position, pullRadius))

because my game is in 2D and not in 3D.


First of all, I disabled normal gravity for my player by setting gravity scale in the rigidbody to 0.


This script is used for the planets, the black holes and the start platform. This is why I added an ObjectShape class, to use it with rectangles and circles.

I use a layermask to be sure not to try to attract planets or black holes but only the player (and meteorits but finally I didn't add them).

Then, in the FixedUpdate I check if my object is a circle or a rectangle.  If it's a circle, I calculate the direction vector and the distance between the player and the the centre of the planet (or black hole) to know in which direction I will have to add a force and how strong. I also add a force for the rotation, otherwise the player will be attracted to the centre of the planet but won't rotate with it.

After that, the OnTriggerEnter2D is only used with blackholes (that is why I make the collider trigger in the Start if it is a blackhole). It detects if the player enters in it and calls a function in my GameManager that will restart the level.

The OnDrawGizmos function is very useful to visualize the zones in which the planets will attract things.

I made GetRotationForce to know how the rotation force should be.


using UnityEngine;
[System.Serializable] public enum ObjectShape
{
    Square,
    Circle,
}
public class ObjectPuller : MonoBehaviour
{
    public float pullRadius = 2;
    public float pullForce = 1;
    public bool blackHole = false;
    [Space]
    public ObjectShape shape;
    [Tooltip("This will only be used with the square !")] public Vector2 squareSize;
    
    LayerMask layerMask;
    RigidBody2D rb;
    private void Start()
    {
        layerMask = ~LayerMask.GetMask("Planets");
        rb = GetComponent<RigidBody2D>();
        if (GetComponent<Collider2D>() && blackHole)
        {
            GetComponent<Collider2D>().isTrigger = true;
        }
    }
    public void FixedUpdate()
    {
        if (shape == ObjectShape.Circle)
        {
            foreach (Collider2D collider in Physics2D.OverlapCircleAll(transform.position, pullRadius, layerMask))
            {
                if (collider.attachedRigidbody)
                { // calculate direction from other object to this object
                    Vector3 forceDirection = transform.position - collider.transform.position;
                    float distance = forceDirection.magnitude;
                    // apply force on other object towards this object
                    collider.attachedRigidbody.AddForce(forceDirection.normalized * pullForce * pullRadius / distance * Time.fixedDeltaTime);
                    // apply force on other object regarding to the rotation
                    collider.attachedRigidbody.AddForce(GetRotationForce(forceDirection.normalized) * (pullForce / 3) * (pullRadius / distance) * Time.fixedDeltaTime);
                }
            }
        }
        else if (shape == ObjectShape.Square)
        {
            foreach (Collider2D collider in Physics2D.OverlapBoxAll(transform.position, squareSize, 0, layerMask))
            {
                if (collider.attachedRigidbody)
                { // calculate direction from other object to this object
                    Vector3 forceDirection = transform.position - collider.transform.position;
                    float distance = forceDirection.magnitude;
                    Bounds bounds = new Bounds(transform.position, squareSize);
                    float multiplier = Vector2.Distance(transform.position, bounds.ClosestPoint(collider.transform.position)) / distance;
                    // apply force on other object towards this object
                    collider.attachedRigidbody.AddForce(forceDirection.normalized * pullForce * multiplier * Time.fixedDeltaTime);
                }
            }
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (!blackHole)
            return;
        if (collision.CompareTag("Player"))
        {
            GameManager.instance.EndGame(false);
        }
        else
            Destroy(collision.gameObject);
    }
    private void OnDrawGizmos()
    {
        if (shape == ObjectShape.Circle)
            Gizmos.DrawWireSphere(transform.position, pullRadius);
        else if (shape == ObjectShape.Square)
            Gizmos.DrawWireCube(transform.position, squareSize);
    }
    Vector3 GetRotationForce(Vector3 currentForce)
    {
        int sign = 1;
        if (rb.rotation < 0)
            sign = -1;
        return Quaternion.Euler(0, 0, 45 * sign) * currentForce * Mathf.Abs(rb.rotation);
    }
}

Files

  • WebBuild.zip 13 MB
    Mar 20, 2022
  • WindowsBuild.zip 30 MB
    Mar 20, 2022
  • MacBuild.app.zip 39 MB
    Mar 20, 2022
Download Planet rider
Read comments (4)