Slippery Surface

Hey there! So I want my character to slide on an ice platform, I’ve already tried making a Physics Material 2D and setting the friction and bounciness both to 0, but it doesn’t work. Maybe the solution is to make the slide by code, but I don’t know how to. Here you have the player’s scripts:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement : MonoBehaviour
{
    public JumpGizmos jg;


    private Rigidbody2D rb;
    public float speed = 10f;
    public int jumpForce = 10;

    public float fallMultiplier = 2.5f;
    public float LowJumpMultiplier = 2f;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        jg = FindObjectOfType <JumpGizmos>().GetComponent<JumpGizmos>();
    }

    void Update()
    {
        //======================================= WALK ======================================//

        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");
        Vector2 dir = new Vector2(x, y);

        Walk(dir);

        //======================================= JUMP ======================================//

        if (Input.GetButtonDown("Jump") && jg.onGround == true)
        {
            Jump();
        }

        if (rb.velocity.y < 0)
        {
            rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) * Time.deltaTime;        
        }
        else if (rb.velocity.y > 0 && !Input.GetButton("Jump"))
        {
            rb.velocity += Vector2.up * Physics2D.gravity.y * (LowJumpMultiplier - 1) * Time.deltaTime;
        }
    }

    //======================================= WALK ======================================//
    private void Walk(Vector2 dir)
    {
        rb.velocity = (new Vector2(dir.x * speed, rb.velocity.y));
    }

    //======================================= JUMP ======================================//
    private void Jump()
    {
        rb.velocity = new Vector2(rb.velocity.x, 0);
        rb.velocity += Vector2.up * jumpForce;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class JumpGizmos : MonoBehaviour
{

    public float collisionRadius = 0.25f;
    public Vector2 bottomOffset;
    private Color debugCollisionColor = Color.red;

    public bool onGround;
    public LayerMask groundLayer;


    void Update()
    {
        onGround = Physics2D.OverlapCircle((Vector2)transform.position + bottomOffset, collisionRadius, groundLayer);
    }


    void OnDrawGizmos()
    {
        Gizmos.color = Color.red;

        var positions = new Vector2[] { bottomOffset };

        Gizmos.DrawWireSphere((Vector2)transform.position + bottomOffset, collisionRadius);
    }
}

You directly set the velocity of the Rigidbody2D yourself in your “Walk” method so what else did you expect to happen? Stop pressing your inputs, you set it to zero. Press your inputs you move. Contact friction isn’t slowing you down here, you’re setting velocity to zero yourself.

If you’re going to do that then you need to reduce the velocity yourself (when not pressing inputs) rather than just set it to zero. I’m not going to write code for you because it depends on how your movement might need to work which I don’t know. In the end, velocity is just a Vector2 so reduce the X and/or Y when you’re not pressing until it hits zero.

You can actually implement a hybrid of using “real” Unity Physics2D and using your own velocity change blending, as long as you understand the difference.

The point of putting materials on specific colliders is to give you an easy way to author a level: ice here, dirt here, ice here, etc.

Your code bypasses the ice effect by directly setting velocity, as Melv points out.

You could use a 2D raycast downwards to find the collider you’re standing on, then query the collider to see if there is a material on it, then use that material in your speed smoothing calculations, rather than directly applying velocity.

For any and all smoothing of changes over time, I always use this:

Smoothing movement between any two particular values:

https://discussions.unity.com/t/812925/5

You have currentQuantity and desiredQuantity.

  • only set desiredQuantity
  • the code always moves currentQuantity towards desiredQuantity
  • read currentQuantity for the smoothed value

Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.

The code: https://gist.github.com/kurtdekker/fb3c33ec6911a1d9bfcb23e9f62adac4