- Home /
How to move an object to a specific distance on a click of arrow key?
I am trying to move my character, but as long as i press the arrow key, he keeps moving. I want him to move in a direction for a particular distance at a press of an arrow key and stop. he must again move when next arrow key is pressed.
I wrote the following code.
using UnityEngine;
using System.Collections;
public class move : MonoBehaviour
{
float playerSpeed = 5.0f;
void Start ()
{
transform.position = new Vector3 (-3, 3, -2);
}
void Update ()
{
transform.Translate(Vector3.right * Input.GetAxis("Horizontal") * playerSpeed * Time.deltaTime);
transform.Translate(Vector3.up * Input.GetAxis("Vertical") * playerSpeed * Time.deltaTime);
}
}
Please Help!
Answer by malkere · Jan 11, 2015 at 11:29 AM
You're using Update to look at the Axis which means as long as the Axis is in use Update will apply the translate every frame.
What it sounds like you want is for something to watch for a KeyDown rather than an axis which are used more for steady movement. On the KeyDown (up arrow or whatever) translate a Vector3 (newPosition) you can predefine separate from the player as where the player needs to go. The use Vector3.Lerp(player.transform.position, newPosition, playerSpeed) in Update() to move the player closer each frame.
In this case, if the player whams on the up arrow a bunch it will translate the newPosition Vector3 many times, but the player will still take time (dependant on the playerSpeed you've defined) to Lerp closer.
you'll probably also want player speed to be a lot less, or make the code in Lerp more like playerSpeed * .01 because 5f per frame is a lot of allowed movement.
@malkere I tried these 2 statements :
void Update ()
{
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.LeftArrow))
{
Vector3.Lerp(transform.position, transform.position += new Vector3(-2,0,0) , playerSpeed);
}
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.RightArrow))
{
transform.position += new Vector3(2,0,0);
these 2 statements works exactly similar. For the statement in the 1st If loop...i kept the playerSpeed as 0.01f but then too my player does not moves smoothly, it just gets disappear from the initial position and appears on the final position! Sorry for the trouble...but m new to unity and c#, so it would be a great help if you could suggest me something!
if you're going to use [ transfer.position += new Vector3(-2,0,0) ] you're going to want to wrap that all in it's own 'new' statement. adding += or = anywhere using what should be somewhat stable/constant values is dangerous, like with an if statement: if (a = b) that will set b and a equal, so you use the operand == (is equal to). in your case what you were writing should have been something more like:
Vector3.Lerp(transform.position, new Vector3(transform.position + new Vector3(-2,0,0)), playerSpeed);
but this in the update function will move the player -2(x) as much as playerSpeed allows only on the frame that the key is pressed.
you should store the destination separate:
Vector3 destination;
void Update () {
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.LeftArrow)) {
destination = new Vector3(transform.position.x - 2,transform.position.y,transform.position.z);
}
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.RightArrow)) {
destination = new Vector3(transform.position.x + 2,transform.position.y,transform.position.z);
}
Vector3.Lerp(transform.position, destination, playerSpeed);
}
This way on Get$$anonymous$$eyDown(which is only once, not per frame) the destination gets updated. While the Lerp(which is every frame), will move the current position towards the destination, as much per frame as playerSpeed will allow.
hey @malkere this code makes sense...completely...but when i executed it, the player is now not moving at all...I kept playerSpeed = 1.. I guess this code will work but i dont knw why its not working! :(
public class move2 : $$anonymous$$onoBehaviour
{
public float playerSpeed = 1f;
Vector3 destination;
void Start ()
{
transform.position = new Vector3 (-3, 3, -2);
}
void Update ()
{
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.LeftArrow))
{
destination = new Vector3(transform.position.x-2,transform.position.y,transform.position.z);
}
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.RightArrow))
{
destination = new Vector3(transform.position.x+2,transform.position.y,transform.position.z);
}
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.UpArrow))
{
destination = new Vector3(transform.position.x,transform.position.y+2,transform.position.z);
}
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.DownArrow))
{
destination = new Vector3(transform.position.x,transform.position.y-2,transform.position.z);
}
Vector3.Lerp(transform.position, destination, playerSpeed);
}
}
I just found your comment in my junk box in outlook =[ sorry I didn't see the post until now. I hope you figured it out!
You might need to say:
transform.position = Vector3.Lerp(tranform.position, destination, playerSpeed);
but the code looks good!
Answer by Omar47i · Jan 11, 2015 at 11:39 AM
as i understood you want your character to move for a short distance and then stop, then another key press is required to move him again. if that what you want then you can simply you can declare a variable first to simulate the momentum associated with the key press then decrease its value each frame until another key is pressed, here is the code (not tested but should work)
public float speed = 5f;
public float momentum = 0;
public float damping = 5;
void Update()
{
float momentumSpeed = 5f; // initial speed that is added to the character
float damping = 5; // increase this value to stop quickly
bool arrowKeysUp = true; // boolean flag to indicate that the arrow keys arn't pressed
float momentum = 0;
// if user press any arrow key and you wern't press the any arrow key the last frame
if (Input.GetAxis("Horizontal") != 0f || Input.GetAxis("Vertical") != 0f && arrowKeysUp == true)
{
momentum = momentumSpeed;
arrowKeysUp = false;
}
else
arrowKeysUp = true;
transform.Translate(Vector3.right * Input.GetAxis("Horizontal") * momentum * Time.deltaTime);
transform.Translate(Vector3.up * Input.GetAxis("Vertical") * momentum * Time.deltaTime);
if (momentum > 0f)
// decrease the momentum each frame
momentum -= (damping * Time.deltaTime);
}
The main difference here would be the version I explained would move a destination variable around the player would slow move towards.
Hitman47's explanation will tap the player onward sort of like a flappy bird movement. Each tap will reset the momentum to max.
Good luck.
Answer by skylem · Jan 11, 2015 at 12:39 PM
You could use a float value to cool down from when the Key/Button was last pressed heres an example.
public float CD = 3; // public so u can see it in inspector but this value can be private / //This is your CoolDown
public bool doCD; // can also be private, This will tell your cooldown to count.
void Update() {
if(Input.GetKeyDown(Keycode.W) && CD <= 0) { // check ur keypress and if ur Cooldowns at 0
transform.position += Vector3.forward * 10; // the actual movement applied.
CD = 3; // reset the count of the cooldown
doCD = true; // tell our cooldown to count
}
if(doCD) { // check if we should be cooling
CD -= 1 * time.deltaTime; // subtracting time from the cooldown
}
if(CD < 0) {
doCD = false; // turning off the cooldown when it hits 0
CD = 0;
}
}
hope this helps.
Your answer
Follow this Question
Related Questions
C# move y position of object not working 2 Answers
Stop Object From Moving After Key Release 2 Answers
Moving on uneven terrain issue 3 Answers
Opening a door at proximity 2 Answers