I’m working on a rail shooter. Instead of translating and rotating the object every frame, I zero out my ship’s position vector and rotation quaternion, then use Translate and Rotate on my ship’s transform to reset it. That way, I can bound how far the ship deviates from the spline, rotations, etc. The problem is, my collision response doesn’t seem to work. I added a rigid body, and when I apply translate/rotate incrementally, it works fine, however, I can’t bound my position anymore.
Here’s what I have for a script:
#pragma strict
var flip : boolean = false;
var wobble : float = 0.0f;
var lift : float = 0.0f;
var turn : float = 0.0f;
var maxWobble : float = 2.0f;
var maxLift : float = 30.0f;
var maxTurn : float = 30.0f;
var speed : float = 250.0f;
var position : Vector3 = new Vector3(0.0f, 10.0f, 0.0f);
var force : Vector3 = new Vector3(0.0f, 0.0f, 0.0f);
var maxOffset = new Vector2(25.0f, 25.0f);
function Update ()
{
// choose how to tilt the ship
if(flip)
{
wobble += Time.deltaTime * 1.5707;
if(wobble >= maxWobble)
{
wobble = maxWobble;
flip = false;
}
} else {
wobble -= Time.deltaTime * 6.26f;
if(wobble <= -maxWobble)
{
wobble = -maxWobble;
flip = true;
}
}
// allow the ship to descend
if(Input.GetButton("forward_button"))
{
lift += Time.deltaTime * 45.0f;
if(lift >= maxLift) lift = maxLift;
} else {
if(lift > 0.0f)
{
lift -= lift * Time.deltaTime * 3.14f;
if(lift < 0.0f) lift = 0.0f;
}
}
// allow the ship to ascend
if(Input.GetButton("back_button"))
{
lift -= Time.deltaTime * 45.0f;
if(lift <= -maxLift) lift = -maxLift;
} else {
if(lift < 0.0f)
{
lift -= lift * Time.deltaTime * 3.14f;
if(lift > 0.0f) lift = 0.0f;
}
}
// turn the ship left
if(Input.GetButton("left_button"))
{
turn -= Time.deltaTime * 45.0f;
if(turn <= -maxTurn) turn = -maxTurn;
} else {
if(turn < 0.0f)
{
turn -= turn * Time.deltaTime * 3.14f;
if(turn > 0.0f) turn = 0.0f;
}
}
// turn the ship right
if(Input.GetButton("right_button"))
{
turn += Time.deltaTime * 45.0f;
if(turn >= maxTurn) turn = maxTurn;
} else {
if(turn > 0.0f)
{
turn -= turn * Time.deltaTime * 3.14f;
if(turn < 0.0f) turn = 0.0f;
}
}
// update the position
position.x += Mathf.Sin(turn / 180.0f) * speed * Time.deltaTime;
position.y -= Mathf.Sin(lift / 180.0f) * speed * Time.deltaTime;
//position.z += speed * Time.deltaTime;
// bound the position
if(position.x < -maxOffset.x) position.x = -maxOffset.x;
if(position.x > maxOffset.x) position.x = maxOffset.x;
if(position.y < -maxOffset.y) position.y = -maxOffset.y;
if(position.y > maxOffset.y) position.y = maxOffset.y;
// reset rotation
transform.position = Vector3.zero;
transform.rotation = Quaternion.identity;
// apply position and rotation
transform.Translate(position);
transform.Rotate(Vector3(0.0f, 1.0f, 0.0f), turn);
transform.Rotate(Vector3(1.0f, 0.0f, 0.0f), lift);
transform.Rotate(Vector3(0.0f, 0.0f, 1.0f), wobble - turn);
}
The code moves and rotates my ship exactly as I want, and bounds the position and rotation correctly. Two problems, however: collision response doesn’t work, and I’m not sure if this is efficient (just started Unity3D last night). I believe writing JavaScript code should be like writing shaders: keep them as lean as possible!
My goal is to have my ship slide along the bottom of the ground if it’s smooth, but if it collides into an object such as a wall, the ship will respond to the collision by processing a shaking animation (based on manipulating transform values, and not modeled animation), and taking damage, and then continue going through the wall.
I’ll do most of the collision response actions by checking the collider collision callbacks in the script, but getting the object to slide along certain objects such as terrain is where I’m stuck.