How can I make my ball roll a little bit further after I release the w,a,s,d keys (directional movement keys)? Currently, if I stop pressing w,a,s,d, the ball just stops moving immediately, but I'd like it to have momentum and keep rolling a bit after I release the keys.
Here is what I've written so far:
public float speed = 6f;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
// Update is called once per frame
void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if(direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
CodePudding user response:
Basically add physics and momentum. A key press equalizer expertise force/transfer energy (E=0.5mv^2 ro get the speed) Every update a fractioneel force is applied (see wiki, constant v^3 if I remember correct)
Result is a ball that gradually gains speed, granulaat slows down and does not change direction immediatly. Make the friction big compared to the force to make controle snappen.
CodePudding user response:
The best approach would be to use a rigidbody to intereact with the physics engine (the effect you are looking for would be easier achieved this way). However, if you rather use a character controller then I suggest first creating a method to execute your input (example / psuedocode):
void MovePlayer(moveDir) {
// Your moving logic
}
Next, you could create a timer that automatically calls this method for an 'x' amount of time after your input is stopped (example / psuedocode):
float rollTimer = 0;
void Update() {
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
// Add your logic to calculate when to activate the rolling effect
// possibly a toggle based on your horizontal & vertical input
timer = (horizontal != 0 && vertical != 0) ? 0 : 3;
// Add an if statement, so that you arent constantly setting timer to 0
if(timer > 0) {
while(timer > 0) {
MovePlayer(/* Simulated input */);
rollTimer -= time.deltaTime;
}
// Reset the timer
rollTimer = 0;
}
}
I can not test this right now, so you may have to tweak it more to fit your exact code, but the concept remains true. This is the simpliest logic I could think of that doesn't use a rigidbody. If you decide to switch to a rigidbody approach, then you can just use the AddForce() method which can give the same effect with natural looking results from the physics engine.