How do I allow my player object to continue rotating once it's met a clamped boundary?
I have a spaceship I'm moving around on the screen, when the player moves the ship, it rotates on its axis. However, when the ship meets a clamped boundary(on the x-axis) it abruptly stops. How do I make it so that the ship will still rotate when meeting the clamped boundary?
void Controls(){
Rotate();
MoveShip();
}
void Rotate(){
player.rotation = Quaternion.Euler((player.velocity.y * -pitchAngle), 0f, (player.velocity.x * -bankRotation));
}
void MoveShip(){
float moveVertical = Input.GetAxis("Vertical");
float moveHorizontal = Input.GetAxis("Horizontal");
Vector3 bank = new Vector3(moveHorizontal, 0f, 0f);
Vector3 pitch = new Vector3(0f, moveVertical, 0f);
player.AddForce(bank * bankSpeed);
player.AddForce(pitch * pitchSpeed);
player.position = new Vector3(Mathf.Clamp(player.position.x, xMin, xMax), Mathf.Clamp(player.position.y, yMin, yMax), 0f);
if((player.position.x == xMin) || (player.position.x == xMax) || (player.position.y == yMin) || (player.position.y == yMax)){
player.velocity = new Vector3(0f, 0f, 0f);
player.angularVelocity = new Vector3(0f, 0f, 0f);
}
}
Answer by Eno-Khaon · May 15, 2016 at 06:03 PM
First, there's your Rotate() function:
void Rotate(){
player.rotation = Quaternion.Euler((player.velocity.y * -pitchAngle), 0f, (player.velocity.x * -bankRotation));
}
Your rotational control is tied to your current velocity. You could apply a minimum potential multiplier to it in order to prevent complete immobility if desired:
public float minMult; // minimum velocity multiplier
// ...
player.rotation = Quaternion.Euler((Mathf.Max(player.velocity.y, minMult) * -pitchAngle), 0f, (Mathf.Max(player.velocity.x, minMult) * -bankRotation));
Next, there's the physics-based aspect.
When you reach any boundary, all motion is immediately and entirely halted for both player.velocity and player.angularVelocity. First, you clamp the position. Then, if the position is at a boundary edge, you stop every frame.
Because all motion is stopped every frame upon reaching a boundary edge, no new motion can be applied. Depending on the intended behavior, the solution may be as simple as clamping position without stopping motion, or it may be more complicated, such as determining whether the player is moving towards or away from each boundary.
I'm assu$$anonymous$$g clamping the position without stopping the motion would cause an issue such as continuing to move outside of the designated boundary?
If I went with using a $$anonymous$$imal potential multiplier, would it be safe to assume that it would need to be the same as my bank speed so it would continue to rotate at the same speed?
If you only clamp the position every frame, then you'll still have velocity trying to pull you beyond the boundaries, though you shouldn't be moving further.
At the moment, your rotational speed scales up with your current velocity. With that in $$anonymous$$d, the $$anonymous$$imum would simply act as a safety to permit rotation at all while you're not moving.
That was an issue I was having was when I called the $$anonymous$$oveShip function in FixedUpdate, the ship would still rotate when it hit be clamped positions, but would actually continue to move passed them as well at a very slow pace. I'm guessing was happening because the velocity was scaled up and still had a value greater than zero since I was holding the button down.
Your answer
Follow this Question
Related Questions
vector3 rotatetowards don't work 1 Answer
angle add constant at vector3 1 Answer
Roatate object to player on tag 0 Answers
How to Rotate on Y Axis by 90 degrees left or right? 1 Answer
it is possible to rotate a texture ? 0 Answers