Search Unity

2D character movement air and ground smoothing

Discussion in 'Scripting' started by Handy333, Oct 23, 2014.

  1. Handy333

    Handy333

    Joined:
    Oct 23, 2014
    Posts:
    11
    I'm working on a small prototype fighting game and started building a physics engine around the 2D physics engine tutorial and I have a couple of problems.
    I can't get the character (while on the ground) to slide after walking. The same is for the air, anytime I let go of the analog stick the character stops immediately. When I crouch with the character she slides but that's all. I was thinking that it had something to do with the 2D physics file that you can make but I experimented with those and the collider physics thing but none of it worked.
    I tried to code some functions by slowing down the speed when the analog stick is at 0 but that didn't work.
    What could I do?

    An example of what I'm trying to achieve is the motion in Super Smash Bros. where Luigi (would be the best example as a template adjusting the slipperiness) would slide all over the place when you let go of the stick. Or when you jump forward and let go of the stick the character would come to a slow stop rather than just stop immediately. Here is my code so far (its a mess):


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ControlScript : MonoBehaviour {
    5.    
    6.     public float maxSpeed = 10f;
    7.     public float walkSpeed = 6f;
    8.     bool facingRight = true;
    9.  
    10.     public Transform groundCheck;
    11.     float groundRadius = 0.2f;
    12.     public LayerMask whatIsGround;
    13.     public float jumpForce = 700f;
    14.  
    15.     public float chaFriction = 0f;
    16.  
    17.     bool grounded = false;
    18.  
    19.     Animator anim;
    20.  
    21.  
    22.  
    23.     // Use this for initialization
    24.     void Start () {
    25.         anim = GetComponent<Animator>();
    26.  
    27.     }
    28.    
    29.     // Update is called once per frame
    30.     void FixedUpdate () {
    31.         //
    32.         grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
    33.  
    34.         anim.SetBool(("Ground"), grounded);
    35.         anim.SetBool(("Walk"), false);
    36.  
    37.         //Variables
    38.         float move = Input.GetAxisRaw("Horizontal");
    39.         float tilt = Input.GetAxisRaw("Vertical");
    40.  
    41.         //Animation Variables
    42.         anim.SetFloat(("vSpeed"), rigidbody2D.velocity.y);
    43.         anim.SetFloat(("Speed"), Mathf.Abs(move));
    44.         anim.SetFloat(("Crouch"), (tilt));
    45.         anim.SetFloat(("rSpeed"), Mathf.Abs(rigidbody2D.velocity.x));
    46.  
    47.         //Control currentAxis Speed
    48.         //currentAxisVelocity = ;
    49.  
    50.         //Animation Before Jump
    51.         //anim.SetBool(("pJump"), false)
    52.  
    53.         //Stop Movement while Crouching(Stationary)
    54.         if(tilt > -0.5)
    55.         {
    56.             rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y);
    57.  
    58.             //if(currentAxis velocity is over a certain amount...)
    59.                 //then use max speed;      
    60.             if(anim.GetFloat("rSpeed") >= walkSpeed)
    61.             {
    62.                 maxSpeed = walkSpeed;
    63.             }
    64.         }
    65.  
    66.         //Stop Movement while Crouching(Stationary)
    67.         if(tilt <= -0.5 && grounded)
    68.             ApplyFriction();
    69.  
    70.         if(move > 0 && !facingRight && grounded && tilt > -0.5)
    71.             Flip ();
    72.         else if(move < 0 && facingRight && grounded && tilt > -0.5)
    73.             Flip ();
    74.  
    75.         //What's the character's Y
    76.         if(transform.position.y < -30)
    77.             StageOut();
    78.  
    79.         //Start Air Control Function
    80.         if(!grounded)
    81.             AirControl();
    82.  
    83.     }
    84.    
    85.     void Update()
    86.     {
    87.         if(grounded && Input.GetButtonDown("Jump")){
    88.             anim.SetBool("Ground", false);
    89.             rigidbody2D.AddForce(new Vector2(0,jumpForce));  
    90.         }
    91.  
    92.         if(chaFriction >= 1f)
    93.             chaFriction = 1f;
    94.         if(chaFriction <= 0.9f)
    95.             chaFriction = 0.9f;
    96.     }
    97.    
    98.     void Flip()
    99.     {
    100.         facingRight = !facingRight;
    101.         Vector3 theScale = transform.localScale;
    102.         theScale.x *= -1;
    103.         transform.localScale = theScale;
    104.     }
    105.  
    106.     void ApplyFriction()
    107.     {
    108.         float slide = rigidbody2D.velocity.x;
    109.    
    110.         rigidbody2D.velocity = new Vector2(slide * chaFriction, rigidbody2D.velocity.y);
    111.     }
    112.  
    113.     void AirControl()
    114.     {
    115.  
    116.     }
    117.  
    118.     void StageOut()
    119.     {
    120.         //Respawn when out of bounds
    121.         rigidbody2D.transform.position = Vector2.zero;
    122.     }
    123. }
    124.  

    Thanks for any help in advance.
     
  2. Handy333

    Handy333

    Joined:
    Oct 23, 2014
    Posts:
    11
    Please?
     
  3. Oana

    Oana

    Joined:
    Sep 28, 2012
    Posts:
    87
    Is chaFriction set to 0 in the editor too? If so, there's your problem! Try setting it to 0.9f or something
     
  4. Handy333

    Handy333

    Joined:
    Oct 23, 2014
    Posts:
    11
    Well actually, that was for crouching and it fixed the problem with the crouching. I set it to that exactly.
    I think it was the basic code from the tutorial done my Mike Gieg. Its like when I run (or in testing purposes walk) then stop. The character stops immediately with out sliding.
    Also in the air, the character moves instantly in the air if you move the analog stick backward or forward.

    I'm not exactly sure why it only works with the crouch animation actually. That part of the code I added myself.
     
  5. Oana

    Oana

    Joined:
    Sep 28, 2012
    Posts:
    87
    Oh, right. So tilt>0.5f is the case you want to have friction. You have this there:
    Code (csharp):
    1. float move =Input.GetAxisRaw("Horizontal");
    2. rigidbody2D.velocity=newVector2(move * maxSpeed, rigidbody2D.velocity.y);
    So when you stop pressing the button or let go of the joystick, move will be 0, and the velocity is set to 0.
    I take it you want to accelerate instantly? How about trying something like this then:
    Code (csharp):
    1.  
    2. if (rigidbody2D.velocity.x>=move*maxSpeed){
    3. rigidbody2D.velocity=newVector2(move * maxSpeed, rigidbody2D.velocity.y);
    4. }else{
    5. ApplyFriction();
    6. }
    7.  
     
  6. Handy333

    Handy333

    Joined:
    Oct 23, 2014
    Posts:
    11
    I'll try that out when I get near my computer.
     
  7. Handy333

    Handy333

    Joined:
    Oct 23, 2014
    Posts:
    11
    YOU DID IT!
    Its amazing but I can't move right for some reason. I think that was a problem from me experimenting with it.
    I think I can fix it. I have to clean up this code.

    *Offline Edit (because I don't have net)


    I tried something along the lines of this while experimenting but the character wan't sliding so I disregarded it multiple times. Now the character slides but doesn't walk to the left.
     
  8. Oana

    Oana

    Joined:
    Sep 28, 2012
    Posts:
    87
    Yeah, true, that is one sided. A proper two way one would be something like this:
    Code (csharp):
    1. if (Mathf.abs(rigidbody2D.velocity.x)>Mathf.Abs(move*maxSpeed) && (Mathf.Sign(rigidbody2D.velocity.x)==Mathf.Sign(move*maxSpeed) || move == 0)){
    2.    //If the movement is in the same direction, and the desired movement is less than the current movement, or move is 0
    3.     ApplyFriction();
    4. }else{
    5.     //we're either moving in the opposite directon, or accelerating
    6.     rigidbody2D.velocity=new Vector2(move * maxSpeed, rigidbody2D.velocity.y);
    7. }
    This is untested code, so there might still be errors. But that is the idea of it, at least.
     
  9. Handy333

    Handy333

    Joined:
    Oct 23, 2014
    Posts:
    11
    I had to do a little tweaking but it works. Thanks for your help. Sorry for the late reply by the way.
     
  10. Oana

    Oana

    Joined:
    Sep 28, 2012
    Posts:
    87
    Glad I could help!
     
  11. Handy333

    Handy333

    Joined:
    Oct 23, 2014
    Posts:
    11
    I'll also be sure to try your games. All of them.