- Home /
Asteroid Field Physics
I'm making a space 2.5d shooter similar to r-type delta or g-darius. Managed to snap all of the action into local space relative to the camera, so the camera can fly around the level and all the action (enemies, projectiles, players) follow the camera as if there was just a movie playing in the background.
What I want to do next though, is have an asteroid field where the player's ship can push asteroids out of the way (they're small). I will also have falling debris and things in the future that will need to bounce off the ship.
The problem I have currently, is that when I fly into an asteroid, the won't fly away or move away, they just kind of crawl away from my ship, and when my ship stops moving, the asteroids stop moving as well. My understanding is that if they both have colliders, with gravity turned off, and the ship is moving in transform.translate methods, that when I push the asteroids, when the ship stops moving, the asteroids should still have "momentum" and keep flying away.
I've frozen the z axis so the asteroids all have this effect on a x/y plane, so that it fits the 2d ness of the 2.5 game, but they still don't carry momentum after being hit by the ship. Any ideas?
Nothing is kinematic except the ship, gravity is off, and nothing is set to trigger. I notice that when I push one asteroid with my ship into another, the asteroid that is hit by an asteroid WILL float away like I want it to. I'm just getting confused x_X
Edit: Also forgot to mention, that when I move an asteroid into another asteroid using my mouse in the inspector panel, and just move them into each other like the ship's movement is done (with translate) they don't bounce anymore, and they just push off each without carrying through their momentum. Is this because if I don't do acceleration or actual movement with the ship, and only modify it's translation +speed*delta.time it won't work? How would I give my ship an acceleration/speed type movement, that would add kinematic based movement to push things and give them momentum?
Try greatly reducing the mass of your asteroids. In addition, you may want to change the physic material to something like "Bouncy".
Tried lowering the mass to its $$anonymous$$imum, took off all friction and drag, my ship just keeps pushing it and then when I stop moving so does the asteroid.
Em3rgency spoke about applying force ins$$anonymous$$d of just editing the ship's translate.position += speed during movement?
case shipState.$$anonymous$$OVINGUP:
transform.localPosition = Vector3(transform.localPosition.x, transform.localPosition.y + (speed*Time.deltaTime), transform.localPosition.z);
break;
case shipState.$$anonymous$$OVINGDOWN:
transform.localPosition = Vector3(transform.localPosition.x, transform.localPosition.y + (-speed*Time.deltaTime), transform.localPosition.z);
break;
case shipState.$$anonymous$$OVINGLEFT:
transform.localPosition = Vector3(transform.localPosition.x + (-speed*Time.deltaTime), transform.localPosition.y, transform.localPosition.z);
break;
case shipState.$$anonymous$$OVINGRIGHT:
transform.localPosition = Vector3(transform.localPosition.x + (speed*Time.deltaTime), transform.localPosition.y, transform.localPosition.z);
break;
To my understanding, moving with this code will fix the issue? http://docs.unity3d.com/Documentation/ScriptReference/Rigidbody.AddForce.html
I think it's a problem with the Transform.Translate method. Since it doesn't actually transform the speed into ship's rigidbody, the speed calculations are inacurrate, because the actual momentum of your ship is 0. Try setting the ship to non-kinematic and directly setting ship's rigidbody.velocity the same way you'd set Translate, but without deltaTime.
Congrats to Em3rgency on solving this one! Found out there's variables to mess with the rigidbody's settings and position, ins$$anonymous$$d of moving the entire prefab object with translate etc. With force as a variable now acting on my prefab, the asteroids react properly as I expected them to. Congrats and thank you so much!
Yup, that's exactly what I meant too :) Good luck on future progress ;)
Answer by Em3rgency · Jun 29, 2013 at 05:15 PM
Lowering their mass would make them easier to start moving, and lowering drag would make them move for longer before lumbering to a halt.
Technically in space there is no drag and nothing would ever stop moving, except that objects get constantly bumped into by miniscule asteroids, and even particles. (Photons CAN stop a moving object. Radiation pressure, look it up).
Additionally, for your desired effect, I'd suggest applying force to your objects to make them move, instead of just changing speed.
Answer by DavidDebnar · Jun 29, 2013 at 09:33 PM
To fix your issue, you need to add up the directions.
rigidbody.velocity = Vector3.zero;
case shipState.MOVINGUP:
rigidbody.velocity += Vector3.up;
break;
case shipState.MOVINGDOWN:
rigidbody.velocity -= Vector3.up;
break;
case shipState.MOVINGLEFT:
rigidbody.velocity -= Vector3.right;
break;
case shipState.MOVINGRIGHT:
rigidbody.velocity += Vector3.right;
break;
rigidbody.velocity = rigidbody.velocity.normalized; //to prevent faster diagonal movement
rigidbody.velocity *= speed;
--David--
That'll work brilliantly! Any idea how I can always make sure the velocity of the object is happening on the plane of the main camera? $$anonymous$$y camera is flying through the level and doing all this cinematic panning and stuff (tons of rotation as you can imagine) so I want the velocity to always push in the local x and y axis of the camera.main object in my level. I managed to get translation working in local space of the main camera, but I can't seem to get fixed velocity working in the same manner.
Any idea how I can fix the velocity movement on the x and y plane of the camera? The ship is set as a child object of the camera for reference.
You'd do it exactly the same way as with Translation, just ins$$anonymous$$d of putting the stuff into .Translate(..), you'd set it into rigidbody.velocity = ..; but without deltaTime.
Example:
transform.Translate(Vector3(1,0,1) * speed * Time.deltaTime);
is almost exactly the same as:
rigidbody.velocity = Vector3(1,0,1) * speed;
--$$anonymous$$--
Thanks Dave! You sorted out my key press problem with (1,0,1) I've added two extra keys checks for if( up && right) { move top right (1,0,1).
It's an extra four if functions, but never $$anonymous$$d :P
I assume I could affect only the .x axis of velocity though? So if (right pressed) { rigidbody.velocity.x = 1} then the same for left but -1?
Also I think someone already described this method, and the velocity wasn't relative to the camera, even though the ship is a child of the camera. I have a script to make the camera constantly rotate in a circle, and I think the ship kept co$$anonymous$$g towards and away from the camera even though z was frozen, and it would constantly move out of its constraints within the camera. Basically wasn't staying in the x and y axis zone of the camera :S To clarify, the camera is spinning around and doing tons of flight path movement, and I want the ship to move around in the local x and y plane of where the camera is looking. rigidbody.velocity will affect the ship in world coords, even though it's a child of the camera. I've already tried using transform direction and inverted version to get the local vector of where to translate the world velocity into a local one, I must be doing it wrong because it still doesn't work.
Lol, that's not what I meant :D. But you said you already had a code for the camera relative thing, so what you should do is take that code and assign it to rigidbody.velocity (it was previously assigned in .Translate). If this doesn't work out for you, create a new question, because this is getting far from the original question ;).
What I meant by "I have the code for relative thing" is that I was using transform.localtranslate or whatever it is, which works because it's a local position edit.
With velocity, I assumed it would do the same because the object is a child of the camera, but it won't. That's the difficulty I'm having XD
(and ye, I'm gonna make a new question I think now...)