Search Unity

Jump diagonal from wall

Discussion in 'Scripting' started by Onlyboro, Nov 19, 2017.

  1. Onlyboro

    Onlyboro

    Joined:
    Oct 28, 2017
    Posts:
    4
    Hi!, I'm currently working on a 2D platformer game. It's similar to super meat boy . I'm currently struggling with the Wall Jump, actually it works but you can jump straight up in the Y direction, and I want to when you try to jump from the wall you get pushed a bit to the opposite direction so you can't go straight up, similar what you feel in Super meat boy, thi is what I have:

    This is the code for the gravity because I'm using a Kinematic type Rigidbody2D.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PhysicsObject : MonoBehaviour {
    6.     public float minGroundNormalY = .65f;
    7.     public float gravityModifier = 1f;
    8.  
    9.     protected Vector2 targetVelocity;
    10.     protected bool grounded;
    11.     protected Vector2 groundNormal;
    12.     protected BoxCollider2D col2D;
    13.     protected Rigidbody2D rb2d;
    14.     protected Vector2 velocity;
    15.     protected ContactFilter2D contactFilter;
    16.     protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
    17.     protected List<RaycastHit2D>hitBufferList = new List<RaycastHit2D> (16);
    18.        
    19.     protected const float minMoveDistance = 0.001f;
    20.     protected const float shellRadius = 0.01f;
    21.     void OnEnable()
    22.     {
    23.         col2D = GetComponent<BoxCollider2D> ();
    24.         rb2d = GetComponent<Rigidbody2D> ();
    25.     }
    26.  
    27.     // Use this for initialization
    28.     void Start ()
    29.     {
    30.         contactFilter.useTriggers = false;
    31.         contactFilter.SetLayerMask (Physics2D.GetLayerCollisionMask (gameObject.layer));
    32.         contactFilter.useLayerMask = true;
    33.     }
    34.    
    35.     // Update is called once per frame
    36.     void Update () {
    37.         targetVelocity = Vector2.zero;
    38.         ComputeVelocity ();
    39.     }
    40.  
    41.     protected virtual void ComputeVelocity(){
    42.     }
    43.  
    44.     void FixedUpdate()
    45.     {
    46.  
    47.         if (Input.GetButtonUp ("Grab"))
    48.         {
    49.             gravityModifier = 1f;
    50.         }
    51.  
    52.         velocity += gravityModifier * Physics2D.gravity * Time.deltaTime;
    53.         velocity.x = targetVelocity.x;
    54.  
    55.         grounded = false;
    56.  
    57.         Vector2 deltaPosition = velocity * Time.deltaTime;
    58.  
    59.         Vector2 moveAlongGround = new Vector2 (groundNormal.y, -groundNormal.x);
    60.  
    61.         Vector2 move = moveAlongGround * deltaPosition.x;
    62.  
    63.         Movement (move, false);
    64.  
    65.         move = Vector2.up * deltaPosition.y;
    66.  
    67.         Movement (move, true);
    68.  
    69.     }
    70.  
    71.     void Movement(Vector2  move, bool yMovement)
    72.     {
    73.         float distance = move.magnitude;
    74.  
    75.         if (distance > minMoveDistance)
    76.         {
    77.             int count = rb2d.Cast (move, contactFilter, hitBuffer, distance + shellRadius);
    78.             hitBufferList.Clear ();
    79.             for (int i = 0; i < count; i++)
    80.             {
    81.                 hitBufferList.Add (hitBuffer [i]);
    82.             }
    83.  
    84.             for (int i = 0; i < hitBufferList.Count; i++)
    85.             {
    86.                 Vector2 currentNormal = hitBufferList [i].normal;
    87.                 if (currentNormal.y > minGroundNormalY)
    88.                 {
    89.                     grounded = true;
    90.                     if (yMovement)
    91.                     {
    92.                         groundNormal = currentNormal;
    93.                         currentNormal.x = 0;
    94.                     }
    95.                 }
    96.  
    97.                 float projection = Vector2.Dot (velocity, currentNormal);
    98.                 if (projection < 0)
    99.                 {
    100.                     velocity = velocity - projection * currentNormal;
    101.                 }
    102.  
    103.                 float modifiedDistance = hitBufferList [i].distance - shellRadius;
    104.                 distance = modifiedDistance < distance ? modifiedDistance : distance;
    105.             }  
    106.  
    107.         }
    108.  
    109.         rb2d.position = rb2d.position + move.normalized * distance;
    110.     }
    111. }
    112.  
    And this is the player controller:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerPlatformerController : PhysicsObject {
    6.  
    7.     public float maxSpeed = 7f;
    8.     public float jumpTakeOffSpeed = 7f;
    9.     public bool grabbed;
    10.     public bool crouched;
    11.     public bool running;
    12.     public bool sliding;
    13.     public bool facingRight;
    14.     public bool checkSlide = false;
    15.     private bool used;
    16.     public Vector2 speed = new Vector2(2,2);
    17.  
    18.     private SpriteRenderer spriteRenderer;
    19.     private Animator animator;
    20.     // Use this for initialization
    21.     void Awake () {
    22.         spriteRenderer = GetComponent<SpriteRenderer> ();
    23.         animator = GetComponent<Animator> ();
    24.     }
    25.        
    26.  
    27.     protected override void ComputeVelocity()
    28.     {
    29.         Vector2 move = Vector2.zero;
    30.         // Movimiento personaje
    31.         if (!crouched)
    32.         {
    33.             if (sliding)
    34.             {
    35.                 // Comprobar en que direccion se esta moviendo
    36.                 if (!checkSlide)
    37.                 {
    38.                     move.x = Input.GetAxis ("Horizontal") ;
    39.                     if (move.x < 0.01) {
    40.                         facingRight = false;
    41.                     } else if (move.x > 0.01)
    42.                     {
    43.                         facingRight = true;
    44.                     }
    45.                     checkSlide = true;
    46.                 }
    47.                 // Si se mueve hacia la izquierda
    48.                 if (!facingRight)
    49.                 {
    50.                     move.x = Input.GetAxis ("Horizontal");
    51.                     if (move.x < 0.01) {
    52.                         move.x = Input.GetAxis ("Horizontal") * 1.5f;
    53.                     } else if (move.x > 0.01)
    54.                     {
    55.                         move.x = 0;
    56.                     }
    57.                 }
    58.                 // Si se mueve hacia la derecha
    59.                 else if (facingRight)
    60.                 {
    61.                     move.x = Input.GetAxis ("Horizontal");
    62.                     if (move.x < 0.01) {
    63.                         move.x = 0;
    64.                     } else if (move.x > 0.01)
    65.                     {
    66.                         move.x = Input.GetAxis ("Horizontal") * 1.5f;
    67.                     }
    68.                 }
    69.  
    70.             } else
    71.             {
    72.                 if (Input.GetButton ("Run") && grounded) {
    73.                     move.x = Input.GetAxis ("Horizontal") * 1.5f;
    74.                     running = true;
    75.                     animator.SetBool ("running", running);
    76.                 } else
    77.                 {
    78.                     move.x = Input.GetAxis ("Horizontal");
    79.                     running = false;
    80.                     animator.SetBool ("running", running);
    81.                 }
    82.             }
    83.  
    84.  
    85.         }
    86.  
    87.         // Finaliza movimiento
    88.  
    89.         if (Input.GetButtonDown ("Crouch") && grounded && !running)
    90.         {
    91.             used = true;
    92.             crouched = true;
    93.             animator.SetBool ("crouch", crouched);
    94.             col2D.size = new Vector2(col2D.size.x, col2D.size.y * 0.5f);
    95.             col2D.offset = new Vector2(col2D.offset.x, col2D.offset.y - 0.12f);
    96.         }
    97.         if (Input.GetButtonUp ("Crouch") && used) {
    98.             used = false;
    99.             crouched = false;
    100.             animator.SetBool ("crouch", crouched);
    101.             col2D.size = new Vector2(col2D.size.x, col2D.size.y * 2f);
    102.             col2D.offset = new Vector2(col2D.offset.x, 0);
    103.         }
    104.  
    105.         if (Input.GetButtonDown ("Jump") && running && grounded) {
    106.             animator.SetBool ("slide", true);
    107.             col2D.size = new Vector2(col2D.size.x, col2D.size.y * 0.5f);
    108.             col2D.offset = new Vector2(col2D.offset.x, col2D.offset.y - 0.12f);
    109.             sliding = true;
    110.             StartCoroutine (Slide());
    111.         }
    112.  
    113.         if (Input.GetButtonDown ("Jump") && grounded && !crouched && !running) {
    114.             velocity.y = jumpTakeOffSpeed;
    115.         }
    116.         else if (Input.GetButtonUp ("Jump"))
    117.         {
    118.             if (velocity.y > 0)
    119.             {
    120.                 velocity.y = velocity.y * .5f;
    121.             }
    122.         }
    123.  
    124.         if (Input.GetButtonDown ("Jump") && grabbed)
    125.         {
    126.             velocity.y = jumpTakeOffSpeed;
    127.         }
    128.  
    129.         bool fliSprite = (spriteRenderer.flipX ? (move.x > 0.01f) : (move.x < 0.01f));
    130.         if (fliSprite)
    131.         {
    132.             spriteRenderer.flipX = !spriteRenderer.flipX;
    133.         }
    134.  
    135.         animator.SetBool ("grabbed", grabbed);
    136.         animator.SetBool ("grounded", grounded);
    137.         animator.SetFloat ("velocityX", Mathf.Abs (velocity.x) / maxSpeed);
    138.         if (!grabbed) {
    139.             targetVelocity = move * maxSpeed;
    140.         }
    141.  
    142.  
    143.  
    144.     }
    145.  
    146.     void OnTriggerEnter2D (Collider2D col)
    147.     {
    148.         if (col.tag == "Climb" && Input.GetButton ("Grab"))
    149.         {
    150.             velocity.y = 0;
    151.             gravityModifier = 0.1f;
    152.             grabbed = true;
    153.         }
    154.  
    155.     }
    156.  
    157.     void OnTriggerExit2D (Collider2D col)
    158.     {
    159.         if (col.tag == "Climb")
    160.         {
    161.             gravityModifier = 1f;
    162.             grabbed = false;
    163.         }
    164.     }
    165.  
    166.     IEnumerator Slide()
    167.     {
    168.         yield return new WaitForSeconds (0.5f);
    169.         animator.SetBool ("slide", false);
    170.         col2D.size = new Vector2(col2D.size.x, col2D.size.y * 2f);
    171.         col2D.offset = new Vector2(col2D.offset.x, 0);
    172.         sliding = false;
    173.         checkSlide = false;
    174.     }
    175.  
    176.     IEnumerator Kinematic()
    177.     {
    178.         yield return new WaitForSeconds (0.1f);
    179.         rb2d.isKinematic = true;
    180.     }
    181.  
    182.  
    183. }
    As you can see the code to jump from the wall is on line 124, I tried with rb2d.AddForce but it wont work because of the kinematic rigidbody.
    Appreciate so much the help, had been struggling for hours with this
     
  2. Internetpolice

    Internetpolice

    Joined:
    Oct 16, 2017
    Posts:
    60
    Hey dude, looks like you just need to be pointed to a new vocabulary term for what you're looking to do.

    I believe the term of what you're looking for is Lerp.

    If this ends up being too rigid looking then you may need to get into a Slerp function which is slower but more in tune with multiple interactions than raw value forces applied.

    https://docs.unity3d.com/ScriptReference/Mathf.Lerp.html

    hope this sends you in the right direction.
     
    Onlyboro likes this.