- Home /
Move an object using GetKeyDown gradually
So I am creating a 2d game where basically the player is driving a car and must change lanes to avoid collisions with other cars. I'm using the arrow keys that when you press the left arrow key, you move one lane left, and when you press the right arrow key, you move one lane right. The code I'm currently using is
function Update () {
if (Input.GetKeyDown (KeyCode.LeftArrow)) transform.Translate (Vector2(-1.2,0));
if (Input.GetKeyDown (KeyCode.RightArrow)) transform.Translate (Vector2(1.2,0));
}
this works except that vehicles don't teleport when they change lanes, they gradually move to the next lane. How would I go about having an object move gradually when a key is pressed?
Answer by Invertex · Feb 16, 2014 at 03:30 PM
Vector2.MoveTowards(); should work for you.
IEnumerator moveTo(float posX,float posY, float speed)
{
while((transform.position.x != posX) && (transform.position.y != posY))
{
transform.position = Vector2.MoveTowards (transform.position,new Vector2(posX,posY),speed * Time.deltaTime);
yield return null;
}
}
And call it with:
StartCoroutine( moveTo(targetX,targetY,speed) );
So in your case here you'd go:
if (Input.GetKeyDown (KeyCode.LeftArrow))
{
StartCoroutine( moveTo(transform.position.x + 1.2,0,20) );
}
else if (Input.GetKeyDown (KeyCode.LeftArrow))
{
StartCoroutine( moveTo(transform.position.x - 1.2,0,20) );
}
I'm having trouble implementing and getting this to work. I'm new to unity and it would be helpful if I could see the whole code so I can just copy and paste it in.
Here it is in Javascript:
#pragma strict
function Update ()
{
if(Input.Get$$anonymous$$eyDown ("t"))
{
moveTo(transform.position.x + 5,transform.position.y + 3, 20); //Feed the moveTo() function the X/Y positions you want it to move to, and the Speed you want it to move at
}
}
function moveTo(posX : float,posY : float, speed : float)
{
while((transform.position.x != posX) && (transform.position.y != posY))
{
transform.position = Vector2.$$anonymous$$oveTowards (transform.position,new Vector2(posX,posY),speed * Time.deltaTime);
yield;
}
}
moveTo() is a custom function, it sits outside of your other stuff like Update() or Start();, and then gets called from wherever you want to use it in your script, whether that be in Update() or whatever. You can feed it different values to get different results, without having to write new lines of code each time.
Answer by N_E_D · Feb 16, 2014 at 01:46 AM
So it looks like you want the object to move over 1.2 units in either direction when you press the arrows.
Try storing the position that you want to move to (1.2 units away from the cars current position) into a variable, and then each frame, translate the car by a fixed amount until reaching that goal position, and then stop moving!
Do you need example code for this or does that make sense?
Answer by erick_weil · Feb 16, 2014 at 01:57 AM
try creating a function and calling the if have pressed the button, seting a boolean true like this :
#pragma strict
var translating : boolean;
var amount : float;
var time : float;
var timetotranslate : float = 0.3;
function Update () {
if (Input.GetKeyDown (KeyCode.LeftArrow)&&!translating)
{
amount = -1.2;
translating = true;
}
if (Input.GetKeyDown (KeyCode.RightArrow)&&!translating)
{
amount = 1.2;
translating = true;
}
if(translating)
{
time += Time.deltaTime;
smoothTranslate(Vector2(amount,0),timetotranslate);
}
}
function smoothTranslate(amount : Vector2,delay : float)
{
if(time<=delay)
transform.Translate (amount*Time.deltaTime/delay);
else
{
time = 0;
translating = false;
}
}
i copy and pasted this into my project and it works, except every time you move, the vehicle gets off of its original position slightly, so if i was to play this game for a while, my car would no longer be in between the lanes.
try this code, fixed the threshold issue
#pragma strict
var translating : boolean;
var time : float;
var timetotranslate : float = 0.3;
var targetposi : Vector2;
var previousposi : Vector2;
function Update () {
if (Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.LeftArrow)&&!translating)
{
previousposi=transform.position;
targetposi=previousposi-Vector2(1.2,0);
translating = true;
}
if (Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.RightArrow)&&!translating)
{
previousposi=transform.position;
targetposi =previousposi+Vector2(1.2,0);
translating = true;
}
if(translating)
{
time += Time.deltaTime;
smoothTranslate(targetposi,timetotranslate,"x");
}
}
function smoothTranslate(target : Vector2,delay : float,axis : String)
{
var amount : Vector2=target-previousposi;
if(time<=delay)
{
if(axis == "x")
transform.Translate ((amount*Time.deltaTime/delay).x,0);
if(axis == "y")
transform.Translate (0,(amount*Time.deltaTime/delay).y);
}
else
{
if(axis == "x")
transform.position.x = target.x;
if(axis == "y")
transform.position.y = target.y;
time = 0;
translating = false;
}
}
There is a crazy amount of code being written here for such a simple task... All OP really needs is Vector2.Lerp();
https://docs.unity3d.com/Documentation/ScriptReference/Vector2.Lerp.html
or even Vector2.$$anonymous$$oveTowards();
This is a lot of code and when I copy and pasted it in, it didn't work.
Answer by byurocks23 · Feb 16, 2014 at 06:32 PM
I believe I have found my solution. I stumbled upon the plugin iTween and it seems to be helping a lot.