Hello.
My player object is moving with velocity change, and it has velocity limit.
But problem is that it sometimes need to travel faster than the limit such as getting hit by explosion…
Can I give two different limits for them? or is there better way to handle this issue…?
Are we talking about custom scripted motion, or Unity physics motion?
Thanks for reply. scripted it is.
this is the code for player movement.
playerRigidbody.velocity = playerRigidbody.velocity + (new Vector3(h, 0f, v) * currentSpeed * Time.fixedDeltaTime);
and it is for explotion impulse.
if (0 < targetTransform.position.x - transform.position.x) {
// player’s at the right of the stone. Push player to right side.
rb.AddForce(Vector3.right * pushPower * Time.deltaTime, ForceMode.VelocityChange);
} else {
// player’s at the left of the stone. Push player to left side.
rb.AddForce(Vector3.left * pushPower * Time.deltaTime, ForceMode.VelocityChange);
}
Ok… looks like you’re using physics.
The usual way i handle this in a physics-based game is to check your character’s velocity. If the magnitude of velocity is greater than your speed limit, then you do this:
- Get the normalized version of the velocity vector. This represents the direction of current velocity.
- take the velocity vector you were about to ADD to the current velocity.
- Use Unity - Scripting API: Vector3.Project to get the projection of the velocity you were about to ADD that is in the same direction of the current motion. For example
Vector3 projection = Vector3.Project(velocityToAdd, currentVelocityDirection)
- SUBTRACT that result from what you were going to add to the velocity.
velocityToAdd -= projection
This will subtract any velocity in the same direction as the current motion from what you are adding to the velocity. The end result is that your player is allowed to still manipulate your character’s speed, but they can never add velocity to your current velocity if your current velocity is over the speed limit.
Thanks for your solution. I’ve never used vector3.project thing so it’s very new for me.
Is this correct?
if (0 < targetTransform.position.x - transform.position.x) {
// player’s at the right side. Push player to right.
Vector3 projection = Vector3.Project(Vector3.right * pushPower * Time.deltaTime, rb.velocity);
rb.AddForce(Vector3.right * pushPower * Time.deltaTime - projection, ForceMode.VelocityChange);
} else {
// player’s at the left side. Push player to left.
Vector3 projection = Vector3.Project(Vector3.left * pushPower * Time.deltaTime, rb.velocity);
rb.AddForce(Vector3.left * pushPower * Time.deltaTime - projection, ForceMode.VelocityChange);
}
using this code, the impulsed player object flies to upper and lower angles only, according to the player’s Y direction at the moment of impulse.
I’ve done that – a normal max speed and a temporary “bonus” force. I think I simply added the bonus speed (just a float) to the max speed before clamping it down. Roughly:
float maxVel= ...
float bonusVel=0;
void wham() {
// just add it the normal way:
rigidBody.velocity+=whamForce;
bonusVel=whamforce.magnitude;
}
void applySpeedLimit() {
float max2=masSpeed+bonusVel;
bonusVel-=smallAmount; if(bonusVel<0) bonusVel=0;
// standard clamp vector to alength:
if(rigidbody.velocity.magnitude>max2) ...
If you get whacked against your movement, this probably won’t do anything, which seems fine. When whacked from behind it allows you to go faster than normal for little.
The other thing I’ve done is even easier and might have looked better. Use a “soft” max speed. If I want a max of 10, I pick 9.5. If if gets over that, tamp it down a little. Revving your engines fights that and gets to about 10. But if something instantly blasts you to speed 15, it takes a second or two for the code to clamp it down.