Search Unity

Collider gets stuck in floor.. Research has been fruitless

Discussion in 'Scripting' started by Magnumstar, May 31, 2016.

  1. Magnumstar

    Magnumstar

    Joined:
    Oct 3, 2015
    Posts:
    304
    My floor is a collider, my player is a collider. On jump, the player reaches apex and downward velocity is applied to simulate a real jump. Sometimes, when the player lands, his collider ends up in the floor collider and the player cannot move. I've tried setting kinematic = true when the player almost reaches the floor, checking with a ray before the player lands setting velocity.Y to 0, nothing works, player still penetrates floor which is annoying.

    My current endeavor is trying to detect OnCollisionEnter and tag = floor then get bounds of floor and get the top, and set the players foot above that point...

    Is this a good way to go about this, and how the hell would I code that?
     
  2. image28

    image28

    Joined:
    Jul 17, 2013
    Posts:
    457
    Have you tried changing the interpolate options in the Rigidbody. Also might be moving to quickly try playing with the PhysicManager settings in the Edit->Project Settings menu. Also what type of collider are you using on your player.
     
    Magnumstar likes this.
  3. Magnumstar

    Magnumstar

    Joined:
    Oct 3, 2015
    Posts:
    304
    Extrapolate seems to help, but the issues still occurs which as you know means it didn't work. I tried to adjust the gravity but I liked the gravity at -9.81.

    I'm using Box Collider.

    Not sure why this is an issue. In real life you don't get stuck in floors. I wish there were a way to set collider density and hardness so this kind of thing could be avoided.

    Capture.PNG

    Perhaps the issue is his animation. The player apparently rocks back and forth while running, maybe this diagonal rotation to the collider is wedging into the floor??? Not sure

    Capture2.png

    The code that brings player back to Earth checks if player isn't grounded and time in air is greater than maxTimeinAir then Add Force downwards * X every update till grounded. I've since only applied this force once and the issue remains. I even cast ray down and if hit within .3f distance then set rigidbody velocity y axis to 0... no cigar
     
    Last edited: May 31, 2016
  4. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    Why not have circle collider for feet? Maybe even a capsule collider, but sadly there isn't one for 2D. This collider shouldn't be swaying with animation, but look like sliding along the ground.
     
    Magnumstar likes this.
  5. Magnumstar

    Magnumstar

    Joined:
    Oct 3, 2015
    Posts:
    304
    I think colliders no matter what type will have the same issue. I tried to detect OnCollisionStay if player is in floor using bottom of player collider < top of floor collider then add -.1f to the Y position of player, but I can't get the correct calculations apparently because the player is in the floor and my breakpoint isn't hitting. What am I doing wrong?

    Code (csharp):
    1.  
    2.     protected void OnCollisionStay(Collision contact)
    3.     {
    4.         GameObject contactObj = contact.gameObject;
    5.  
    6.         float length = contactObj.transform.localScale.x * ((BoxCollider)contactObj.GetComponent<BoxCollider>()).size.x;
    7.         float width = contactObj.transform.localScale.z * ((BoxCollider)contactObj.GetComponent<BoxCollider>()).size.z;
    8.         float height = contactObj.transform.localScale.y * ((BoxCollider)contactObj.GetComponent<BoxCollider>()).size.y;
    9.         Vector3 dimensions = new Vector3(length, height, width);
    10.         float topCollider = contactObj.transform.position.y + dimensions.y / 2;
    11.  
    12.         float lengthPlayer = transform.localScale.x * ((BoxCollider)GetComponent<BoxCollider>()).size.x;
    13.         float widthPlayer = transform.localScale.z * ((BoxCollider)GetComponent<BoxCollider>()).size.z;
    14.         float heightPlayer = transform.localScale.y * ((BoxCollider)GetComponent<BoxCollider>()).size.y;
    15.         Vector3 dimensionsPlayer = new Vector3(lengthPlayer, heightPlayer, widthPlayer);
    16.         float bottomPlayer = transform.position.y - dimensions.y / 2;
    17.  
    18.         if (contact.gameObject.GetComponent<MovingObject>() != null)
    19.         {
    20.             MovingObject movingContact = contactObj.gameObject.GetComponent<MovingObject>();
    21.             if (movingContact.tag == "Enemy")
    22.             {
    23.                 if (movingContact._attackCoolDownTimer == 0)
    24.                 {
    25.                     CauseDamage(movingContact);
    26.                     movingContact._attackCoolDownTimer += 1;
    27.                 }
    28.                 else
    29.                 {
    30.                     movingContact._attackCoolDownTimer -= 1;
    31.                     if (movingContact._DamageFrequency == movingContact._attackCoolDownTimer)
    32.                         movingContact._attackCoolDownTimer = 0;
    33.                 }
    34.             }
    35.         }
    36.         else if (contactObj.tag == "Floor")
    37.         {
    38.             if(bottomPlayer < topCollider)
    39.             {
    40.  
    41.                 bool inFloor= true;
    42.  
    43.             }
    44.         }
    45.     }
    46.  
    inFloor isn't hitting when my player is clearly in the floor...?
     
  6. Magnumstar

    Magnumstar

    Joined:
    Oct 3, 2015
    Posts:
    304
    Actually, capsule colliders for feet worked, Nice! Thanks Zalfis!
     
    image28 likes this.
  7. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I think the real problem here may be that you are assigning a velocity, so the next frame will pretty much always have a penetration amount (depending on max depenetration velocity). If you use forces this may be less visible. How are you moving it?
     
  8. Magnumstar

    Magnumstar

    Joined:
    Oct 3, 2015
    Posts:
    304
    As I said, when jump time in air > max time in air (apex), begin applying downward force with AddForce (-Vector3.up, 50f) in update context. I even tried casting ray down .3f and if the floor is hit set velocity.y to 0. Did not worko.. The player would stop an inch above the ground and float down the rest but even then sometimes he'd penetrate
     
  9. image28

    image28

    Joined:
    Jul 17, 2013
    Posts:
    457
    Just Checking you have your physics code in FixedUpdate and not Update right?
     
  10. Magnumstar

    Magnumstar

    Joined:
    Oct 3, 2015
    Posts:
    304
    This is something I looked at and yes it's in fixed update. I call ReceiveControl in fixed update in the class player which derives from movingobject. ReceiveControl then calls method Jump which has a virtual override in base that gets called. Then JumpController method in the base is called in fixedupdate that does the max in air time check and applies the down force when jump hits apex.