I am implementing a space simulator where fireballs are colliding with planets. I want the fireballs to be effected by gravity of planets but don't want them to collide every time.
My Current code in the Update function is:
var fgX = 0;
var fgZ = 0;
var distanceX = fireball.transform.position.x - planet.position.x;
var distanceZ = fireball.transform.position.z - planet.position.z;
var theta = Mathf.Atan2(distanceZ,distanceX);
var rsq = distanceZ*distanceZ+distanceX*distanceX;
if (rsq < 400)
{
fireball.transform.position.x = fireball.transform.position.x-(Mathf.Cos(theta));
fireball.transform.position.z = fireball.transform.position.z-(Mathf.Sin(theta));
var fg = 0.5*planet.rigidbody.mass*fireball.rigidbody.mass/(rsq);
fgX += fg*Mathf.Cos(theta);
fgZ += fg*Mathf.Sin(theta);
fireball.rigidbody.velocity.x += (fgX/fireball.rigidbody.mass);
fireball.rigidbody.velocity.z += (fgZ/fireball.rigidbody.mass);
}
At the moment the fireball is just flying into the planet every time as soon as it hits the 400 rsq distance. I want it to be dependent on how far away the fireball is when it enters this area.
Any help would be much appreciated even if you can't see where my code is going wrong another way to go about the gravity would be great.
Thanks
Sorry, just thought of something else. You need to calculate the escape velocity of the planet. If the meteor is traveling faster than that speed, and it's not aimed at the planet...it will always miss (kenetic eneragy > potential energy). Personally, I say fake the effect. If the meteor is X close, change its direction by Y degrees.
Thanks everyone for your comments, I have found another way to implement this
`function FixedUpdate()
{
var cols : Collider = Physics.OverlapSphere(transform.position, gravityRange);
var rbs : Array = new Array();
for (c=0;c<cols.length;c++) {
if (cols
.attachedRigidbody && cols[c].attachedRigidbody != rigidbody) {
var breaking :boolean = false;
for (r=0;r<rbs.length;r++) {
if (cols[c].attachedRigidbody == rbs[r]) {
breaking=true;
break;
}
}
if (breaking) continue;
rbs.Add(cols[c].attachedRigidbody);
var offset : Vector3 = (transform.position - cols[c].transform.position);
var mag: float = offset.magnitude;
cols[c].attachedRigidbody.AddForce(offset/mag/mag * rigidbody.mass);
}
}
}
`
<p>This was on the unity wiki and works perfectly. </p>
**Edit Smorpheus: The full source code (C# & JS) can be found here: http://www.unifycommunity.com/wiki/index.php?title=Gravity
If this solved the problem, please mark it as the accepted answer.
I disagree with the issue mentioned in the comments about your gravitational constant, that is relative to the mass. If you're following the javascript example and using small masses, it should be fine.
To find the problem you first need to figure out if the problem is in your code or in your assumptions about the behavior of the system. How your fireballs behave is going to depend very much upon their initial location and size relative to the planet as well as their velocity.
If you notice in the JS simulation, there are several trajectories you can start a ball on that will always crash it into the planet. In fact, it's a lot harder to not crash the ball than it is to crash it.
I'm assuming that you have the rest of the function in your code somewhere that actually moves the fireballs. If so, you'll need to experiment with different starting positions and velocities and print out some debug information to see why the system isn't behaving as you expect.
Sorry, just thought of something else. You need to calculate the escape velocity of the planet. If the meteor is traveling faster than that speed, and it's not aimed at the planet...it will always miss (kenetic eneragy > potential energy). Personally, I say fake the effect. If the meteor is X close, change its direction by Y degrees.
ā anon33906366