I am trying to make a script that will move a rigidbody to the left or right by 2m/s or 9m/s depending on if the left arrow key has been pressed down or double tapped and held down.
The velocity levels out at 4.8m/s and 12m/s after 2 seconds but I am not able to set the velocity’s acceleration after key up.
What I’m trying to do is make a script where the velocity increases and plateaus each time the character stops and starts. The movement is also dependent double tapping and holding down a key or just holding down a key.
should I be using rigdbody or character controller if I need control over the physics.
using UnityEngine;
using System.Collections;
public class walktest : MonoBehaviour {
//declare variables
private Vector3 moveh; //for input
private float velo = 0.0f;//velocity
float lastTime = -1.0f; //double tap
bool upPressed = false; //for left arrow
//tsec time in seconds movement has gone on for mod-up hill down hill
private float tsec = 0.000f;
//math for walking acceleration and running acceleration
private float accel=2f;
private float accelR=9.0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//checking for left arrow
if(Input.GetKeyDown(KeyCode.LeftArrow))
{upPressed = true ;}
else if(Input.GetKeyUp(KeyCode.LeftArrow))
{upPressed = false ;}
tsec += 1 * Time.deltaTime;// this converts fram rate into seconds no matter the frame
//rate. multiplies it by 1 so once per second tsec is increasing.
//trigger walking and runnng
if(upPressed==true){
if (Time.time - lastTime < 0.2f){ lastTime = Time.time;// turn on running
if (velo>= 12.0f){velo=12.8f;}//stop accelerating past certain speed
else {velo=accelR*tsec;} //accelerate
print ("run speed is"+velo);//check
}
}
else{ lastTime = Time.time;// turn on (or switch to) walking
if (velo>= 4.8f){velo=4.8f;}//stop accelerating past certain speed
else {velo=accel*tsec;} //accelerate
print (" walk speed is"+velo);//check
}
// actual walking WILL NEED TO BE MODED FOR WALKING BACKWARDS
//if(Input.GetKey (KeyCode.LeftArrow)){
moveh = new Vector3(Input.GetAxisRaw("Horizontal"),0,Input.GetAxisRaw("Vertical"));
rigidbody.velocity=(moveh*velo);
print("leftkey"+velo);
if (upPressed == false){
print("released LeftArrow");tsec=0;} //reset tsec
}
}
can some one at least point me in the right direction for the double tap I got it to reset sort of by moving the Time.deltTime inside of the upPressed if statement. But the run and walk parts don’t function right
if(upPressed==true){
tsec += 1 * Time.deltaTime;
// this converts fram rate into seconds no matter the frame
//rate. multiplies it by 1 so once per second tsec is increasing.
if (Time.time - lastTime < 0.2f){
lastTime = Time.time;// turn on running
if (velo>= 12.0f){velo=12.8f;}//stop accelerating past certain speed
else {velo=accelR*tsec;} //accelerate
print ("run speed is"+velo);//check
}
else{
lastTime = Time.time;// turn on (or switch to) walking
if (velo>= 4.8f){velo=4.8f;}//stop accelerating past certain speed
else {velo=accel*tsec;} //accelerate
print (" walk speed is"+velo);//check
}
}
I haven’t looked to deep into your code yet, but preliminary look through, I see one critical issue.
Whenever you set ‘velo’, you SET it, yet you comment it with ‘accelerate’.
Acceleration is applied over time, it doesn’t get set, you sum it on.
Lets take gravity, gravity accelerates at 9.8 m/s/s downward, that means velocity in the downward direction is going to increase by 9.8 m/s every second.
So, by seconds:
0 : 0m/s
0.5: 4.9m/s
1 : 9.8m/s
1.5: 14.7m/s
2 : 19.6m/s
You could get this by summing it every update:
var v = new Vector3(0f, -9.8f, 0f);
velo += v * Time.deltaTime; //note the +
Positive acceleration will increase your velocity, negative will decrease your velocity.
If you want to clamp, then you just check:
velo += accel * tsec;
if(velo.magnitude > maxSpeed) velo = velo.normalized * maxSpeed;
I’m confused isn’t multiplying the velocity with Time.deltaTime just converting it from fps to m/s then multiplying it by the acceleration.
in your example you are multiplying it by a vector but I would not think that this would mater since I have a cap on the direction by limiting it to the left arrow.
lastly why do velo += accel * tsec and
var v = new Vector3(0f, -9.8f, 0f)
if accel equals -9.8
Technically yes, that’s part of it. What that means is that when you say:
velo=accel*tsec;
You’ve effectively set ‘velocity’ to ‘acceleration in terms of m/s’. You set velocity to acceleration.
Velocity and acceleration aren’t the same thing. Acceleration is the derivative, the tangent, the slope, the rate of change (all these things mean the same thing) of velocity.
My car travels at a speed of 60mph, but I accelerate UPTO 60 mph at a rate of 10 mph per second. Taking me from 0 to 60 in 6 seconds (pretty fast car).
I was merely using a vector for example puproses. Velocity and acceleration in 3d space is usually 3d and to represent velocity and acceleration in 3 dimensions would require a data structure that can handle 3 dimensions. A Vector3 does this.
This is why in Physics and Calculus classes you often use vectors.
because acceleration is -9.8. But speed is not. Speed INCREASES (hence the +=, a sum) over time at the rate of acceleration.
That’s why acceleration’s is often in m/s/s. That’s meters per second per second.
what should have been written is velo==accel*tsec; but I don’t know if that will work.
still if my velocity starts at 0 and I add acceleration to it per time (tsec) isn’t that enough.
it seems to me that v and accel should be the same variable.
or maybe do
accel += -9.8 * Time.deltaTime;
wait wait wait is Time.deltaTime taking the place of time in m/s/s. I’m just confused
wait so -9.8* timeΔt is -9.8m/s and when Update is called it turns it into -9.8m/s/s
Is this right, I just want to multiply acceleration by a variable that is measured in second and then assign that value to a variable velo
Well your code was this:
if (velo>= 4.8f)
{
velo = 4.8f;
}//stop accelerating past certain speed
else
{
velo = accel*tsec;
} //accelerate
If it’s supposed to be “==”, 2 things.
-
it doesn’t contextually make sense. “==” is a comparison operator that results in a bool, what would you put that in the brackets rather than in the parens?
-
never compare floats with an equality comparison. >, >=, <, <= are fine, but floats are far to error prone to do exact comparison with == or !=. Especially if it’s just after a fractional multiplication which will most certainly result in float precision error.
Well no, because then you’ll accelerate forever, you need to accelerate UPTO your max speed.
I will watch out for using != in the future with floats.
I understand deltatime better so removed tsec and created another velocity. This code works but I am not quite able to figure out why double tap is buggy yet. the only thing I’m worried about is if adding a bunch of variables called every frame will start to slow things down.
using UnityEngine;
using System.Collections;
public class walktest : MonoBehaviour {
//declare variables
private Vector3 moveh; //for input
private float velo = 0.000f;//velocity walking
private float veloR = 0.000f;//velocity running
float lastTime = -1.0f; //double tap
bool upPressed = false; //for left arrow
//tsec time in seconds movement has gone on for mod-up hill down hill
private float Kvelocity = 0.000f;
//math for walking acceleration and running acceleration
private float accel=2f;
private float accelR=9.0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//checking for left arrow
if(Input.GetKeyDown(KeyCode.LeftArrow))
{upPressed = true ;}
else if(Input.GetKeyUp(KeyCode.LeftArrow))
{upPressed = false ;}
//tsec += 1 * Time.deltaTime;// this converts fram rate into seconds no matter the frame
//rate. multiplies it by 1 so once per second tsec is increasing.
//trigger walking and runnng
if(upPressed==true){
// this converts fram rate into seconds no matter the frame
//rate. multiplies it by 1 so once per second tsec is increasing.
if (Time.time - lastTime < 0.2f){
lastTime = Time.time;// turn on running
veloR += accelR * Time.deltaTime;
Kvelocity=veloR;//speed holder
if (Kvelocity>= 12.0f){Kvelocity=12.8f;}//stop accelerating past certain speed
print (Kvelocity+"run speed is"+veloR);//check
}
else{
lastTime = Time.time;// turn on (or switch to) walking
velo += accel * Time.deltaTime;
Kvelocity=velo;
if (Kvelocity>= 4.8f){Kvelocity=4.8f;}//stop accelerating past certain speed
print (Kvelocity+"walk speed is"+velo);//check
}
}
// actual walking WILL NEED TO BE MODED FOR WALKING BACKWARDS
//if(Input.GetKey (KeyCode.LeftArrow)){
moveh = new Vector3(Input.GetAxisRaw("Horizontal"),0,Input.GetAxisRaw("Vertical"));
rigidbody.velocity=(moveh*Kvelocity);
print("keydown speed"+Kvelocity);
if (upPressed == false){
print("released LeftArrow");Kvelocity=0; veloR=0;velo=0;} //reset