Home > other >  Game Object deletes itself without having Destroy() in the script
Game Object deletes itself without having Destroy() in the script

Time:11-12

I am creating a Space simultation in Unity using Newtons Law of gravitation and Centripetal force calculations to re-create the motion of the planets. Recently i have tried to implement realistic masses such as 3.285e 23 and i have converted them to managable numbers using a massScale 1e-24f. but since implementing these new masses and converting them, the smaller planet of the three has started deleting itself shortly after runtime without any error being thrown. I will also add that i dont have any sort of Destroy Line in my code either.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlanetVelocity : MonoBehaviour
{
    private Gravity _gravity;
    public float v;
    public bool debugBool;
    public GameObject Sun;
    private Rigidbody rb;
    private Vector3 dif;

    public static List<GameObject> AllPlanets;
    private const float distScale = 1e-7f;
    private const float massScale = 1e-24f;
    private const float gravity = 6.674e-11f;

    public float mass = 5.972e24f;

    private Vector3 motion;

    [Header("Orbital Data")]
    public float velocity = 29.8f;
    public float distance = 148900000f;

//TODO: Convert weight units to KG and use realistic weights for planetary bodies
/*Calculate velocity using v = sqrt[(G M )/r]*/
/*Get the Planet to look at the sun*/
/*Apply V to the transform.right of the planet to have perpendicular motion*/

void Start()
{
    _gravity = FindObjectOfType<Gravity>();
    rb = GetComponent<Rigidbody>();
    rb.mass = mass * massScale;
}

void DebugClass()
{
    if(debugBool)
    {
        Debug.Log($"Mass Scale {rb.mass}");
        //Debug.DrawRay(gameObject.transform.position, motion, Color.red);
       // Debug.Log($"Calculated Velocity = {v} Difference {dif} Motion {motion}");
    }
}
void ObjectLook()
{
    transform.LookAt(Sun.transform);
}


// Update is called once per frame
void Update()
{
    DebugClass();
    ObjectLook();
    Vector3 sunPos = new Vector3(Sun.transform.position.x, Sun.transform.position.y, Sun.transform.position.z);
    Vector3 planetPos = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y,
        gameObject.transform.position.z);

    Vector3 dif = sunPos - planetPos;
    float r = dif.sqrMagnitude;

    v = Mathf.Sqrt(_gravity.f * rb.mass) / r;
    //v = Mathf.Sqrt(_gravity.G * rb.mass / r ) ;

    Vector3 motion = transform.up * v;
    if (gameObject.transform.position.x > 0 && gameObject.transform.position.y > 0)
    {
        motion.x = Math.Abs(motion.x);
        motion.y = -Math.Abs(motion.y);
    }

    if (gameObject.transform.position.x > 0 && gameObject.transform.position.y < 0)
    {
        motion.x = -Math.Abs(motion.x);
        motion.y = -Math.Abs(motion.y);
    }

    rb.velocity = motion;
    
}

}

and here is my script controlling gravitational pull towards the sun, based off of what game objects are withing the sphere collider range of the sun.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gravity : MonoBehaviour
{

    public float f; //force

    private const float massScale = 1e-24f;
 

    public float mass = 1.989e 30f;

    public float G = 6.674e-11f; //Gravitational Constant

    private Rigidbody m1;//Mass 1 The Sun ( this Game Object)
    private Rigidbody m2;//Mass 2 Planet
    private Vector3 r1;

    public Vector3 FORCE;

    public bool debugBool;

void Start()
{
    Time.timeScale = 50f;
}

private void Awake()
{
    m1 = GetComponent<Rigidbody>();
    m1.mass = mass * massScale;
}

private void DebugClass()
{
    if (debugBool)
    {
        Debug.Log(m2.velocity); 
        Debug.Log("TRIGGERED");
        Debug.Log($"r1 {r1.normalized} FORCE {FORCE}");
    }
}

private void Update()
{
    DebugClass();
}

private void OnTriggerStay(Collider other)
{
    //declares rigidbody locally
    Rigidbody m2;
    //assigns other objects rigidbody to m2
    m2 = other.gameObject.GetComponent<Rigidbody>();
    
    // get sun position
    Vector3 Sun = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, gameObject.transform.position.z);
    // planet
    Vector3 otherPlanet = new Vector3(other.gameObject.transform.position.x, other.gameObject.transform.position.y, other.gameObject.transform.position.z);
  
   
    //Difference between each object
    Vector3 r1 = Sun - otherPlanet;
 
    //Difference between each object squared
    float r2 = r1.sqrMagnitude;
    float distance = r1.magnitude;
    
    ///<summary>
    /// Calculates Force by Mutliplying Gravitational
    /// constant by the mass of each object divided 
    /// by the distance between each object squared
    /// <summary>
    f = G * m1.mass * m2.mass / r2;
    
    
    //Assigns the value r1 normalized between 0 and 1
    //multiplied by F independent of frames per second
    Vector3 FORCE = r1.normalized * f * Time.deltaTime;
    
    // Adds force to the other game objects rigidbody using the FORCE vector
    // Using the Force force mode
    m2.AddForce(FORCE);

}

}

CodePudding user response:

I had issues with extremely small float numbers on my Rigidbody transform and thus unity was deactivating the game object before it overflowed, my solution was to multiply the physic calculations i used by a 'PhysicsMultiplier' and this solved my issues completely

  • Related