Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to do slippery surface in 2D top vue ?

Discussion in '2D' started by joxthebest314, May 19, 2020.

  1. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    I was wondering how I could make the oil puddle be slippery (like if the tank stops accelerating, he still moves a little bit) Sans titreASasA.png .
    I don't use gravity in this scene and I use physics to move my character.
    I was hoping someone could give me a hint about how to do that (I am pretty bad when it comes to use physics and movements).
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @joxthebest314

    If you are using Physics2D in top down view, you can't probably use friction, but you could do trigger check, and whenever player vehicle enters a puddle.

    Modify your "braking" force which you normally use to stop your vehicle gradually when there is no movement input. Simply make it go to zero slower, and your vehicle will stop later than on solid ground. Of course, if you now stop immediately when you have no input, then you'll have to modify your stopping code too.
     
    joxthebest314 and MelvMay like this.
  3. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    For the movements, I just use the "Rigidbody2D.MovePosition" method, and the character stops as soon as there are no other inputs.

    I understand what you said, but I don't know really how to do a "stopping code".

    Is there an example somewhere ?
     
  4. brigas

    brigas

    Joined:
    Oct 4, 2014
    Posts:
    522
    ah you should move by using Rigidbody2D.Addforce
     
  5. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    Why ? This method works perfectly.
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,513
    If you want to control each position you move to then you'll also have to have your own version of velocity and be able to speed-up or slow-down. If you set the Rigidbody2D velocity or use forces then the physics system will automatically move it for you at that velocity. You then only have to manipulate velocity. You can even use Rigidbody2D.drag and Rigidbody2D.angularDrag to slow down and change this value when you're over different surfaces.

    It might work perfectly but you seem to now have a different movement behaviour where it's not so perfect and requies you to do more work yourself which you might not even have to be doing.

    If you're using MovePosition then I hope you're doing this with a Kinematic body otherwise you can cause problems when a Dynamic body contacts things and the physics system solves it but you then issue a MovePosition.
     
    Last edited: May 19, 2020
    joxthebest314 likes this.
  7. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    Thanks for the answer, but I don't really understand why I sould use a kinematic RB ( I wasn't and didn't noticed anything).

    In fact, I am really not good when it comes to physics and movements, but here is my code :

    Code (CSharp):
    1.  void FixedUpdate()
    2.     {
    3.         var movePosition = Vector2.zero;
    4.         var moveRotation = 0f;
    5.  
    6.         if(Input.GetKey(InputManager.IM.forwardOrange))
    7.         {
    8.             movePosition += new Vector2(Mathf.Cos(rotation),Mathf.Sin(rotation)) * speed;
    9.             anim.SetBool("isMovingForward", true);
    10.         }
    11.         else
    12.         {
    13.             anim.SetBool("isMovingForward", false);
    14.         }
    15.  
    16.         if(Input.GetKey(InputManager.IM.rotateRightOrange))
    17.         {
    18.             moveRotation -= rotationSpeed;
    19.             anim.SetBool("isRotatingRight", true);
    20.         }
    21.         else
    22.         {
    23.             anim.SetBool("isRotatingRight", false);
    24.         }
    25.  
    26.         if(Input.GetKey(InputManager.IM.rotateLeftOrange))
    27.         {
    28.             moveRotation += rotationSpeed;
    29.             anim.SetBool("isRotatingLeft", true);
    30.         }
    31.         else
    32.         {
    33.             anim.SetBool("isRotatingLeft", false);
    34.         }
    35.  
    36.         if(Input.GetKey(InputManager.IM.backwardOrange))
    37.         {
    38.              movePosition -= new Vector2(Mathf.Cos(rotation),Mathf.Sin(rotation)) * speed;
    39.              anim.SetBool("isMovingBackward", true);
    40.         }
    41.         else
    42.         {
    43.             anim.SetBool("isMovingBackward", false);
    44.         }
    45.  
    46.         rb.MovePosition(rb.position + movePosition * Time.fixedDeltaTime);
    47.  
    48.         rb.MoveRotation(rb.rotation + moveRotation * Time.fixedDeltaTime);
    49.  
    50.         rotation = Mathf.Deg2Rad * rb.rotation;
    51.     }
    This code is really strange, because I need the tank to still go forward using like W, even if the tank is facing the bottom of the screen (it means the A and D keys are rotating the tank and the W and S keys are moving it, according to its rotation).

    Someone helped me to do this code (I asked for help on a unity forum), so I don't really know if it is worth changing all my moving method.
     
  8. brigas

    brigas

    Joined:
    Oct 4, 2014
    Posts:
    522
    well you need it if you want to slide
     
  9. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    I just find out about the 2D effectors, is there a way to use them in my case (just an idea)
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,513
    You can use the method that's been outlined above. When you use MovePosition, there's no momentum to reduce (slow down), you're just instantly teleporting from position to position so no amount of drag or any force via an effector will apply will stop you from teleporting from position to position. Dump the velocity, you'll see it's zero all the time even though you're "moving".
     
    joxthebest314 likes this.
  11. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    Okay I understand, but I have troubles with the addforce (I really have poor knowledge about this):
    First there is an inertia-like feeling, then I absolutely don't know how to rotate an object with addforce and I also don't know how to do a braking force.

    Sorry to ask you so much, but could you help me ?
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,513
    AddForce has nothing to do with rotation which is why.

    A forum thread like this isn't the place because then it just becomes an attempt at a tutorial. There's plenty of tutorials out there showing how to use 2D physics. Why not get more familiar with the basics first then move onto your game? If you don't do this then you'll stuggle at each step and it'll get frustrating for you.

    Note that it was me who even wrote you an example on another thread here.

    How to do what you asked for has been described above so beyond that the only thing left is writing the code for you? What else would you need?
     
    Last edited: May 20, 2020
    joxthebest314 and brigas like this.
  13. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    Hahahaha no I don't need you to do my job don't worry. I figured out a way, using addforce and slowing the tank with a linear drag of 20. Befor going further, is this a viable solution ?
     
  14. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,513
    Using the built-in velocity of the body to move then yes! So much easier and less error prone than manipulating position yourself. Now to simulate slipping you can turn off drag and stop/reduce adding force when the input happens (because the tracks are skidding) and stuff like that. Basically just manipulating velocity and the forces you add.
     
    Last edited: May 21, 2020
    joxthebest314 likes this.
  15. joxthebest314

    joxthebest314

    Joined:
    Mar 31, 2020
    Posts:
    95
    Thank you so much !
     
  16. DearUnityPleaseAddSerializableDictionaries

    DearUnityPleaseAddSerializableDictionaries

    Joined:
    Sep 12, 2014
    Posts:
    135
    Thanks, the solution works - I implemented slippery floors top-down by adjusting the player drag once it touches the slippery floor. One problem is that I have to adjust the force (if I reduce the drag, I also have to reduce the force that is applied when the player moves, to keep the speed the same). I don't have the exact formula, so it's done arbitrarily. Additionally, if the player is already moving fast before touching the slippery floor, it seems to move faster than expected (though I have to debug more carefully to see if it's really the case). I've also tried increasing the mass instead of reducing the speed, but couldn't get the slippery floor to feel perfectly good, other than just messing around with parameters and trial and error to try improve.