- Home /
2D Character controller that moves in increments.
Hello,
I need some help with creating a controller for my 2D character. The problem I am having is that the character should move in a constant speed forward and then move to a specific Y-coordinate when a button is pressed.
In essence,
character moves forward in X with a constant speed.
If button is pressed, move character 3 units in Y while not losing speed in X.
If button is pressed again, move character another 3 units in Y from the new position. etc.
How could I do this in a neat way, I would like the Y-movement to be smooth, so using a lerp seems reasonable. The only thing I can accomplish myself is the movement in Y or X, not both at the same time.
Thanks in advance, Martin.
Answer by giano574 · Feb 05, 2014 at 11:10 PM
You can use Transform.Translate with a constant in the X-position. You can use it in a coroutine like this:
IEnumerator moveCharacter()
{
while (transform.position.y < moveToThisY)
{
transform.Translate(xSpeed * Time.deltaTime, ySpeed * Time.deltaTime,
0);
yield return null;
}
transform.Translate(xSpeed * Time.deltaTime, 0, 0);
}
Then, each time the button is pressed increment the moveToThisY by 3. You should probably set the y position to this variable as well, to ensure that it is exactly right, like this.
transform.position = new Vector3(transform.position.x, moveToThisY,
transform.position.z);
Place this line right after the while loop in the coroutine. You will also have to call the coroutine once in the Start function, like this:
StartCoroutine(moveCharacter());
EDIT: Also note, that you should never actually use "transform" if you have to use it often. You should store a reference to it instead. In the class declare a variable:
private Transform myTransform;
And in the Start function assign myTransform to transform:
void Start()
{
myTransform = transform;
}
You could, of course do the exact same thing within the Update function, using an if statement ins$$anonymous$$d.
void Update()
{
if (myTransform.position.y < moveToThisY)
{
myTransform.Translate(xSpeed * Time.deltaTime, ySpeed * Time.deltaTime,
0);
}
else
{
myTransform.position = new Vector3(myTransform.position.x,
moveToThisY, myTransform.position.z);
myTransform.Translate(xSpeed * Time.deltaTime, 0, 0);
}
}
Thank you, your solution works perfect, it even seems that the Transform.Translate gives better performance than moving rigidbodys.
Cheers!
That's great. Did you use the coroutine method? I'm curious to know, since I am not sure that it works correctly.
I actually never got the coroutine to work to well with both X & Y, so I used the "if" way ins$$anonymous$$d.
Okay. Looking back at it, I don't see any reason to use a coroutine anyway. And the way I made it was obviously wrong, as you say. But I'm glad it worked out for you.