I have a player character in a topdown game that moves in grid-like movements (1 unit at a time), but when it hits a patch of ice (square), I want it to switch to lerp-movement, slide to the edge, and stop.
Currently I have 5 different colliders as children for each patch of ice: the ice collider itself, and 4 slightly distanced colliders, one for each side of the ice. When it hits the ice collider, depending on which direction it was heading in, it should lerp to the distanced collider associated.
Like so (it's hard to see the main collider but it's there):
Here is the code I have been using for the down key (its basically the same for all keys):
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Vector2 movementDown = new Vector2(0, -1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, 0.05f);
if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
{
Debug.Log("N/A");
}
else if (onIce)
{
player.transform.position = Vector3.Lerp(transform.position, downIce.transform.position, 100 * Time.fixedDeltaTime);
}
else
{
player.transform.position += new Vector3(movementDown.x, movementDown.y, -0.1f);
}
}
EDIT: code that updates bool 'onIce':
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice") {
onIce = true;
}
}
void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice")
{
onIce = false;
}
}
Lerp is only getting called once, when you push the button. One way to fix it is by using a coroutine:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
And then you use it like this:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
I think this is still not exactly what you want in your game because it will lerp to the center of the collider. If that's the case you can easily fix it by changing how it calculates the end variable in the coroutine to make the player only slide along the correct axis.