- Home /
The question is answered, right answer was accepted
2D Top down physics with ground (slippery floor...)
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; } } }
Answer by Trevdevs · Aug 19, 2018 at 10:43 PM
Rather than programming friction which is very tedious why not just use https://docs.unity3d.com/Manual/class-PhysicsMaterial2D.html
Just create a sprite for normal ground and another for ice then place them together in a level. And set the friction on the ice physics material to something like 0.1 or lower to get a slippery effect
How can this be the solution? OP was saying a top down 2D game. And the floor has to be isTrigger. Whenthe player move onto the tile, it's not moving into the tile's collider. How can the object interacting with physics material?
Follow this Question
Related Questions
How to access a tile? 1 Answer
2D custom sort axis not working at all 2 Answers
How can i normalize 2d Vectors? 2 Answers
How to 2D Topdown Sprite order management 0 Answers
Player Character No Longer Moving 0 Answers