Hello! i hope someone can help me with this. So i have an object that moves in the x axis with the arrow keys, but i want the object to go from one specific position to another when i press the arrow key, something like movement in lanes i guess? with four positions. A professor told me i should define four x positions (done) and add or subtract to get to those positions, but idk how to do that even tho it seems easy. This is my script:
public class cube : MonoBehaviour {
public float moveSpeed;
/*
First position: -12.47
Second position: -3.1
Third position: 6.42
Fourth position: 13.98
*/
void Start () {
moveSpeed = 10f;
}
void Update () {
transform.Translate (moveSpeed*Input.GetAxis("Horizontal")*Time.deltaTime, 0f, 0f);
}
}
This would be a good use case for a Coroutine. If you’re not familiar, a coroutine is basically a threaded function, so it can run on its own. The general flow of the code should be:
- Player presses an arrow key.
- The coroutine begins processing, moving the player from point A to point B.
- Once the coroutine has finished, the player stops moving and the script can now accept other key presses.
Your code would look something like this:
public Vector3[] Positions;
public float MoveDuration;
private bool _canMove = true;
private int _currentPosition = 0;
void Update()
{
if(Input.GetAxis("Horizontal") && _canMove)
{
StartCoroutine(Move(Input.GetAxis("Horizontal") > 0));
}
}
private IEnumerator Move(bool moveRight)
{
// Check if this is a valid move. If there is no lane to move into, just return.
if(moveRight && _currentPosition + 1 < Positions.Length)
{
_currentPosition++;
}
else if(!moveRight && _currentPosition - 1 >= 0)
{
_currentPosition--;
}
else
{
return;
}
// Make sure the player can't move while switching lanes. Could cause all kinds of bugs otherwise.
_canMove = false;
// Now actually perform the move.
float timer = 0;
Vector3 startPosition = transform.position;
Vector3 endPosition = Positions[_currentPosition];
while (timer < MoveDuration)
{
timer += Time.deltaTime;
transform.position = Vector3.Lerp (startPosition, endPosition, timer / MoveDuration);
// In a coroutine, doing "yield return null" stops processing until the next frame.
yield return null;
}
// Make sure you set their final position after the loop is done processing.
transform.position = endPosition;
// Make sure the player can move once again.
_canMove = true;
}
I’m not at my dev computer so can’t verify that this is 100% correct, but hopefully it can get you along the right lines. Let me know if you have any questions, thanks!