I want make my player keep moving forward using AddForce, but i dont want the player move to fash so i limit it use Vector3.ClampMagnitude and maxSpeed.
Then i find some trouble where the player now cant do Dash / Jump because i set the maxSpeed.
Any suggesion ?
Instead of flat-out clamping movement, you could apply a force in the opposite direction of the players movement if it moves too fast. This force could get bigger as the player gets faster (I would figure out how fast your player is going over your max speed, get X% of that number (so if your player is going 10 units over the max speed, and you take 50%, you get 5 units, but if they are going 100 units over the max speed, you then get 50 units), then add that much force in the opposite direction of player movement.)
There are more elegant solutions, but it was the first one that came to my mind that was easy enough to explain, but if you are confused, let me know and I can either provide code or provide a different awnser.
Sorry for the long wait, went on a little “suprise trip” and did not have acess to a device that could open visual studio. However, this should be what you need:
//Replaced "Speed" With "Acceleration" To Make It More Clear, As This Value Is How Fast Your Speed Increases
public float acelleration = 3f;
[SerializeField] float jumpForce = 70f;
//This Should Be Just A Bit Less Than What You Want The Normal Max Walking Speed To Be.
//When The Player Moves Faster Than This Speed, They Get A Force Acting On
[SerializeField] float slowdownSpeed = 10f;
//This Should Be A Speed You Never Want Your Players To Reach, Even When Dashing/Jumping/Etc
[SerializeField] float absoluteMaxSpeeed = 20f;
//The Higher The Value, The Faster The Player Will Be Slowed Down When They Are Over The Max Speed
[SerializeField] float overspeedReductionStrength = 0.5f;
private void FixedUpdate()
{
TryAutomove();
if (isGrounded())
{
// Player Jump
if (Input.GetMouseButtonDown(0))
{
playerRb.AddForce(focalPoint.transform.up * jumpForce, ForceMode.Impulse);
}
}
}
void TryAutomove()
{
float playerSpeed = playerRb.velocity.magnitude;
if(playerSpeed > slowdownSpeed)
{
//How Fast The Player Is Above The Max Speed
float overspeedAmount = slowdownSpeed - playerSpeed;
//If The Player Is Way Above The Speed Limit, We Want The Slowdown Force To Be Much Stronger
//Higher The OverspeedReductionStrength == Faster Slowdown Speed
float slowDownForce = overspeedAmount * overspeedReductionStrength;
//You May Want To Change The Force Mode, Idk What Your Project Loooks Like Though.
playerRb.AddForce(focalPoint.transform.forward * -1 * slowDownForce);
}
//This Is Your Automove Code, I Moved It To Here Just To Make It A Bit More Readable
playerRb.AddForce(focalPoint.transform.forward * acelleration);
//We Still Clamp Magnitude, But This Should Bascially Do Nothing 99% Of The Time.
//If Players Are Reaching This Speed, Try Increasing The Overspeed Reduction Strength Varible
playerRb.velocity = Vector3.ClampMagnitude(playerRb.velocity, absoluteMaxSpeeed);
}
1- I added [SeralizeField] to some of your private variables. This allows you to change them in the inspector (The box generally on the right side of the screen that shows info about your object when you select it)
2- I changed your “Speed” variable to “Acelleration”, because that varible determines how fast your speed chagnes over time
3- I moved your Update function to FixedUpdate, which executes at a (more or less) constant speed, unlike Update which sometimes can be called 30 times per second and other times can be called 100 times per second. (This is an issue because you apply force every time you run the code, so if your update function runs more or less times a second, there will be more/less force applied to your character over time)
4- I moved the whole Automove code to its own function, just so that way you have an easier time knowing what code deals with what.
5- I replaced “MaxSpeed” with three variables, “slowdownSpeed”, “absoluteMaxSpeed”, and “overspeedReductionStrength”. SlowdownSpeed is the fastest speed the character can move before we start to add force in the opposite direction the focalPoint is facing. OverspeedReductionStrength tells the computer how strong the force pushing against the player should be (although it should be noted that the force will always be very small when the player is just barley going faster than the slowdownSpeed, and it will always be notably bigger when the player is way above the slowdownSpeed.). AbsoluteMaxSpeed does the exact same thing MaxSpeed used to do, but you want to set this to a value well above the players normal movement speed, as the player will never ever be able to move faster than that speed, even when jumping, dashing, and doing whatever else you want at the same time. Idealy, the player should never be able to reach this speed, as your OverspeedReductionStrength should be high enough to slow down the player before they reach the AbsoluteMaxSpeed.
Once (or if) you understand the code, I would get rid of a lot of the comments, but they are there just in case something does not make sense
I did notice a problem with my code, if the player is falling, the Overspeed will push the player backwards but not up, so you may want to replace the following line of code: playerRb.AddForce(focalPoint.transform.forward * -1 * slowDownForce);
with playerRb.AddForce(playerRb.velocity * -1 * slowDownForce);
I try this code. but somehow it didnt work when i used FixedUpdate function , but it work when i put it on Update function…
I found another glitch, but i can handle it… Thanks man, this is really-really helpfull