Hello
I’m quite new to the Unity engine, and I’m currently working on a 2D top down game. I’m using Tilemaps to draw my levels, but I have a question. I’d like to create a slippery effect on some places of the map (like an ice floor). I’ve found a way, but I’m wondering if there are better solutions to achieve this goal.
I’m currently doing the following:
-
Created a new Tilemap on top of my default ground to draw my Ice patches on
-
Added a Tilemap Collider2D to that Tilemap and made it a trigger
-
When I enter the trigger, I update the movement of my player
-
I’ll add my code below
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MovementController : MonoBehaviour {
[SerializeField] private float topSpeed = 2.0f; private bool facingRight = true; private bool facingDown = true; private bool onIce = false; private Rigidbody2D rbody; private Animator animator; void Start() { rbody = GetComponent<Rigidbody2D>(); animator = GetComponent<Animator>(); Physics2D.gravity = Vector2.zero; Debug.Log("Initialized Player"); } void Update() { } void FixedUpdate() { updateMovement(); updateAnimator(); if (onIce && stoppedMoving()) { //print("Player stopped moving"); } } void updateMovement() { //Get input float moveHorizontal = Input.GetAxis("horizontal"); float moveVertical = Input.GetAxis("vertical"); //Define wheter moving horizontal and/or vertical bool vertical = Mathf.Abs(Input.GetAxisRaw("vertical")) > 0.1f; bool horizontal = Mathf.Abs(Input.GetAxisRaw("horizontal")) > 0.1f; //Update movement if (horizontal && vertical) //rbody.velocity = new Vector2(moveHorizontal, moveVertical) * topSpeed * 3 / 4; rbody.AddForce(new Vector2(moveHorizontal * topSpeed, moveVertical * topSpeed) * 3 / 4); else rbody.AddForce(new Vector2(moveHorizontal * topSpeed, moveVertical * topSpeed)); //rbody.velocity = new Vector2(moveHorizontal, moveVertical) * topSpeed; //Flip if needed if (moveHorizontal < 0 && facingRight) flipHorizontal(); else if (moveHorizontal > 0 && !facingRight) flipHorizontal(); //stop moving when needed too if (Mathf.Abs(Input.GetAxisRaw("horizontal")) < 0.1f && !onIce) rbody.velocity = new Vector2(0, rbody.velocity.y); if (Mathf.Abs(Input.GetAxisRaw("vertical")) < 0.1f && !onIce) rbody.velocity = new Vector2(rbody.velocity.x, 0); } void updateAnimator() { bool vertical = Mathf.Abs(Input.GetAxisRaw("vertical")) > 0.1f; bool horizontal = Mathf.Abs(Input.GetAxisRaw("horizontal")) > 0.1f; //Update animator //horizontal/vertical if (Mathf.Abs(Input.GetAxisRaw("vertical")) > 0.1f && Mathf.Abs(Input.GetAxisRaw("horizontal")) > 0.1f) { animator.SetBool("horizontal", true); animator.SetBool("vertical", false); } else { animator.SetBool("horizontal", horizontal); animator.SetBool("vertical", vertical); } //up/down if (facingDown && Input.GetAxisRaw("vertical") > 0.1f) { animator.SetBool("down", false); facingDown = false; } else if (facingDown && Input.GetAxisRaw("vertical") < -0.1f) { animator.SetBool("down", true); facingDown = true; } else if (!facingDown && Input.GetAxisRaw("vertical") < -0.1f) { animator.SetBool("down", true); facingDown = true; } else if (!facingDown && Input.GetAxisRaw("vertical") > 0.1f) { animator.SetBool("down", false); facingDown = false; } } void flipHorizontal() { facingRight = !facingRight; Vector3 localScale = transform.localScale; localScale.x *= -1; transform.localScale = localScale; } bool stoppedMoving() { return Mathf.Abs(rbody.velocity.x) < 0.05f && Mathf.Abs(rbody.velocity.y) < 0.05f; } void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.tag == "Icy") { print("Entered ice collider"); onIce = true; } } void OnTriggerExit2D(Collider2D other) { if (other.gameObject.tag == "Icy") { print("Exited ice collider"); onIce = false; } }
}