Local Velocity for Rigidbody?

I was the guy that asked the Asteroid physics question a few days ago. Basically we solved it, the reason the Asteroids weren’t being knocked away by the ship, is because I was translating it, instead of adding velocity and force to the rigidbody.

So now I have an additional problem that has come as a result of solving that initial issue:

This is the result I want = PSX Longplay [089] G-Darius - YouTube
I want my camera to be able to pan around the environment on an animated track, and my ship alongside all of the action taking place on the X and Y axis of the camera.

I’ve decided the easiest way to do this was to take all my assets that were being instantiated, and make them children of the main camera so they would follow it and maintain rotation etc.

That all worked fine when I moved my ship using transform.localtranslate (or the equivalent), and everything worked the way I wanted it to. For extra flair, I wanted to have asteroids in the first level that the player ship could push away with their ship, and later on ships would explode and the debris would bounce off the player ship and collapsing bricks from buildings etc would all interact with the player ship.

So then after solving the rigidbody issue (I had to use velocity instead of just transforming the object), sure we solved the problem of other rigidbodies not behaving with the ship properly, but now the ship won’t move along the camera’s x and y axis, and just moves to the world’s axis again (because I’m now using velocity).

Any way to create local velocity for the ship, and what would be the best way to kill velocity once it has been set. So far I just put in Update() to set the velocity to 0 first before doing key checks, so that if no keys are pressed, the system resets the velocity to 0 (Standing still). Is that the best way to do it? It works so :S

So basically, how to create and maintain local velocity?

Here are the steps:

  1. Take player’s input and assign it to a localPos, variable representing ship’s position in camera’s local space
  2. Calculate camera viewport’s bounds in camera’s local space. ViewportToWorldPoint(0,0) is bottom-left, ViewportToWorldPoint(1,1) is top-right. These values are in world coordinates, so they have to be converted to local with Cam.InverseTransformPoint().
  3. When the min and max variables are set, clamp the local position.
  4. Lastly, convert the localPos into world coordinates with TransformPoint() and assign it to the rigidbody via rigidbody.MovePosition(). Last thing is to use rigidbody.MoveRotation(Cam.rotation) to make the ship face the right way.

All of this has to happen in FixedUpdate() to make all the MovePosition’s collisions/forces behave correctly.

P.S.: The ship is not a child of the camera, because Rigidbodies don’t like to be children of moving objects ;).

private var localPos = Vector3.zero;
var Speed = 0.2;
var DistanceFromCamera = 10.0;
var Cam : Transform;

function FixedUpdate () {
	localPos.x += Input.GetAxis("Horizontal") * Speed;
	localPos.y += Input.GetAxis("Vertical") * Speed;
	localPos.z = DistanceFromCamera;

	var min : Vector3 = Cam.InverseTransformPoint(Cam.camera.ViewportToWorldPoint(Vector3(0,0,DistanceFromCamera)));
	var max : Vector3 = Cam.InverseTransformPoint(Cam.camera.ViewportToWorldPoint(Vector3(1,1,DistanceFromCamera)));

	if(localPos.x - transform.localScale.x/2 < min.x) localPos.x = min.x + transform.localScale.x/2;
	if(localPos.x + transform.localScale.x/2 > max.x) localPos.x = max.x - transform.localScale.x/2;
	if(localPos.y - transform.localScale.y/2 < min.y) localPos.y = min.y + transform.localScale.y/2;
	if(localPos.y + transform.localScale.y/2 > max.y) localPos.y = max.y - transform.localScale.y/2;

	var worldPos = Cam.TransformPoint(localPos);