Game Object deletes itself without having Destroy() in the script - unity3d

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);
}
}

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

Unity: how to force rotation after rotating towards a direction?

After asking here for a solution, which worked, my sphere "walks" to each point of a list. Now, I'm trying to "force" a rotation around the x axis, to fake the ball is "rolling". I came up with the following code, but it doesn't work (it makes a progressive acceleration of the rotation on the x-axis, which I both dont want and... dont understand).
Create a new project, add a sphere and add this small script. Then add 2 points in the points list. This script does nothing but moving the object (the sphere) each points of the list, and make a simple rotation around the x-axis.
Simple rotation around the x-axis is not realistic (it's working as long as the sphere doesn't change its direction, but in this case, it should rotate on x + on z, but I dont know how to do this too...) so if you have a more realistic idea its even more welcome.
using UnityEngine;
public class MoveAlongPath : MonoBehaviour
{
public Vector3[] points;
public float speed = 1.0f;
public float rotateSpeed = 200.0f;
public float minDistance = Vector3.kEpsilon;
private SphereCollider _c;
[SerializeField] private Vector3 _posStart;
[SerializeField] private Vector3 _posEnd;
[SerializeField] private int _currentIndex;
[SerializeField] private Rigidbody _rigidbody;
[SerializeField] private Vector3 _direction;
[SerializeField] private Vector3 _directionNormalized;
[SerializeField] private float _xRotation;
private void NextPoint()
{
_posStart = points[_currentIndex];
transform.position = _posStart;
_currentIndex = ++_currentIndex % points.Length;
_posEnd = points[_currentIndex];
_direction = _posEnd - _posStart;
_directionNormalized = _direction.normalized;
}
private void Start()
{
_rigidbody = GetComponent<Rigidbody>();
NextPoint();
}
private void FixedUpdate()
{
_xRotation = (_xRotation + -10 * Time.fixedDeltaTime) % 360;
Quaternion q = Quaternion.LookRotation(
_directionNormalized, Vector3.up
);
transform.rotation = Quaternion.RotateTowards(
transform.rotation, q, rotateSpeed * Time.fixedDeltaTime
) * Quaternion.AngleAxis(_xRotation, Vector3.left);
Vector3 step = speed * Time.fixedDeltaTime * _directionNormalized;
if (step.magnitude > _direction.magnitude) {
step = _direction; // don't overshoot
}
Vector3 newPos = transform.position + step;
_rigidbody.MovePosition(newPos);
if (Vector3.Distance(_posEnd, transform.position) < minDistance) {
/* close enough -> next point: */
NextPoint();
}
}
}

Unity 3D jump and movement conflict

I wanted to make an endless runner game where the player can jump and he moves forward automatically, so, for the forward movement i wanted to use the rigidbody velocity function in order to make the movement smoother and for the jump i made a custom function. My problem is, when i use in my update method the velocity function alone, it works, when i use it with my jump function it stops working. What can i do?. I tried changing the material of the floor and of the player's box collider to a really slippery one but nothing
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovePrima : MonoBehaviour
{
[SerializeField]
private float _moveSpeed = 0f;
[SerializeField]
private float _gravity = 9.81f;
[SerializeField]
private float _jumpspeed = 3.5f;
public float speedAccel = 0.01f;
private CharacterController _controller;
private float _directionY;
public float startSpeed;
public float Yspeed = 10f;
private int i = 0;
public float touchSensibility = 50f;
public int accelTime = 600;
[SerializeField]
Rigidbody rb;
// Start is called before the first frame update
void Start()
{
startSpeed = _moveSpeed;
_controller = GetComponent<CharacterController>();
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
rb.velocity = new Vector3(0f, 0f, 1f) * _moveSpeed;
touchControls();
}
public void touchControls()
{
if (SwipeManager.swipeUp && _controller.isGrounded)
{
_directionY = _jumpspeed;
print("Entrato");
}
_directionY -= _gravity * Time.fixedDeltaTime;
_controller.Move((new Vector3(0, _directionY, 0)) * Time.fixedDeltaTime * Yspeed);
i += 1;
if (i % accelTime == 0)
{
_moveSpeed += startSpeed * speedAccel;
i = 0;
}
}
private void OnControllerColliderHit(ControllerColliderHit hit) //Checks if it collided with obstacles
{
if(hit.transform.tag == "Obstacle")
{
GameOverManager.gameOver = true;
}
}
}
You should either use the CharacterController or the Rigidbody. With the CharacterController you tell Unity where to place the character and you have to check yourself if it is a valid position. With the Rigidbody you push it in the directions you want, but the physics around the character is also interfering.
You can use Rigidbody.AddForce to y when jumping instead of _controller.Move.

How to identify multiple objects in a sphere cast?

I am trying to implement a RADAR sensor in unity. I am currently using sphere cast to identify the object and measure its velocity and distance. At the moment even though there are several objects in within the radius of the sphere cast ,It only identifies the nearest one. How can i make it recognize all the objects within the sphere cast.?
Any help would be appreciated..
This is what i have done now which just identifies identify the closest object.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spherecast : MonoBehaviour
{
Rigidbody rb;
public GameObject curobject;
public float radius;
public float maxdist;
public LayerMask layermask;
public float velocity;
public Time deltatime;
public Vector3 previous;
private Vector3 origin;
private Vector3 direction;
private float hitdist;
// Use this for initialization
void Start()
{
previous = curobject.transform.position;
}
// Update is called once per frame
void Update()
{
velocity = hitdist/Time.deltaTime;
origin = transform.position;
direction = transform.forward;
RaycastHit hit;
if (Physics.SphereCast(origin, radius, direction, out hit, maxdist, layermask, QueryTriggerInteraction.UseGlobal))
{
curobject = hit.transform.gameObject;
hitdist = hit.distance;
Debug.Log("Distance" + hitdist);
velocity = ((curobject.transform.position - previous).magnitude) / Time.deltaTime;
previous = curobject.transform.position;
Debug.Log("Velocity" + velocity);
// Debug.Log("Velocity = " + velocity);
}
else
{
hitdist = maxdist;
curobject = null;
}
}
private void ondrawgizmosselected()
{
Gizmos.color = Color.red;
Debug.DrawLine(origin, origin + direction * hitdist);
Gizmos.DrawWireSphere(origin + direction * hitdist, radius);
}
}
How can i make it recognize all the objects within the sphere cast.?
I believe you need to use SphereCastAll instead of SphereCast for that.
https://docs.unity3d.com/ScriptReference/Physics.SphereCastAll.html
Answer:
"Like Physics.SphereCast, but this function will return all hits the sphere sweep intersects."
It returns a RaycastHit[].

Can not print out gameobject's position's value correctly

When trying to print out (debug) my objects value, it gives me the position's value of where it's original position is (the startposition in world space). So my object is placed in -3.51 in y in world space before starting the game, therefore it only prints out -3,51 on every update despite the fact that in the inspector you can see the y position (in transform) changing when the object moves.
This is the code that does it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Icke procedurell
public class createLevels : MonoBehaviour {
public GameObject doodle;
public Transform doodleTransform;
public GameObject greenPlatform;
public float distMultiplier = 1f;
public float valueY;
public int ammountPlatforms = 10;
public float levelWidth = 3f;
public float minY = 0.2f;
public float maxY = 1.5f;
public Vector3 spawnPosition = new Vector3();
void Start()
{
for (int i = 0;i < ammountPlatforms; i++) // Instansierar en startsumma platformar.
{
spawnPosition.y += Random.Range(minY, maxY); // Ökning i y
spawnPosition.x = Random.Range(-levelWidth, levelWidth); // Ingen ökning i x..
Instantiate(greenPlatform, spawnPosition, Quaternion.identity);
}
}
void Update()
{
Debug.Log(doodle.GetComponent<Transform>().position.y);
/*
if (doodleTransform.position.y >= 10)
{
Debug.Log("I am over a certain distance.");
distMultiplier++;
Instantiate(greenPlatform, spawnPosition, Quaternion.identity);
}
*/
}
}
Also note that this is a script on another gameobject referencing my "wanted" gameobject's position.
To summarize the question, if you look in the update function, observe the "Debug.Log". It only prints out my startvalue, and i am trying to print out the objects position in y in realtime, being dynamic.

Use Accelerometer for Roll-a-ball Movement

I'm working on maze game for Android in Unity 5.1.1f1 and I have troubles with controlling my ball with accelerometer. At start I tried:
public class PlayerController : MonoBehaviour {
public GameObject sphere;
public Camera camera;
public float speed=200;
private Rigidbody myRigidBody;
void Start()
{
myRigidBody = gameObject.GetComponent<Rigidbody> ();
}
void FixedUpdate()
{
float moveH = Input.acceleration.x;
float moveV = -Input.acceleration.z;
Vector3 move = new Vector3 (moveH, 0.0f, moveV);
myRigidBody.AddForce (move * speed*Time.deltaTime);
}
}
But the ball is not moving as it should. Then I tried another solution. But my ball still doesn't move right. It seems like it's sometimes hard to move left/right/forward/backward, also it's possible my ball will rotate in the opposite direction.
public class PlayerController : MonoBehaviour {
public float speedAc = 10;
//accelerometer
private Vector3 zeroAc;
private Vector3 curAc;
private float sensH = 10;
private float sensV = 10;
private float smooth = 0.5f;
private float GetAxisH = 0;
private float GetAxisV = 0;
// Use this for initialization
void Start () {
ResetAxes();
}
//accelerometer
void ResetAxes(){
zeroAc = Input.acceleration;
curAc = Vector3.zero;
}
void FixedUpdate () {
curAc = Vector3.Lerp(curAc, Input.acceleration-zeroAc, Time.deltaTime/smooth);
GetAxisH = Mathf.Clamp(curAc.x * sensH, -1, 1);
GetAxisV = Mathf.Clamp(-curAc.z * sensV, -1, 1);
Vector3 movement = new Vector3 (GetAxisH, 0.0f, GetAxisV);
GetComponent<Rigidbody>().AddForce(movement * speedAc);
}
}
Can someone help me, please?
I have answered this one in another SO question: Unity 3D realistic accelerometer control - you've got two variants of control there, just copy the one you find fit.
If you're having more problems, ask.