Search Unity

"Dodgy" Mesh Collision with Rigidbody

Discussion in 'Physics' started by Studio_Akiba, Sep 19, 2016.

  1. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    I don't think this has anything to do with my character controller, but I have included that at the bottom in case it is causing this.

    On the inverse corners of my map (the acute 90-degree angle INSIDE a box), if I continuously push against them and look around a bit I clip through it pretty violently.

    I wouldn't have even noticed had I not tried to use my staircase (a stairwell encased in a long vertical rectangular tube) as once I try to go up it fast and hit a corner on the way up I go straight through it with little to no effort and end up falling forever.

    I am using a mesh collider as the stairwell as 2 doorways, 1 at the top and 1 at the bottom which meant I can't use a box collider for obvious reasons.

    Why is the collision in Unity so dodgy and not in other engines, despite them all using PhysX? And is there any way to fix this? Flying through walls while going up a flight of stairs is a pretty show-stopping issue...

    As promised...my controller, just in case:
    Code (CSharp):
    1. /*
    2. * ---- Character Controller: Character Movement ----
    3. *
    4. * To Add:
    5. *      Smoother Movement
    6. *      Better Collision w/ Movement
    7. *      Setup as Static to Save Settings
    8. * */
    9.  
    10. using UnityEngine;
    11.  
    12. public class CharacterController : MonoBehaviour
    13. {
    14.  
    15.     public static CharacterController playerController;
    16.  
    17.     public float speed = 10.0f;
    18.  
    19.     void Start()
    20.     {
    21.         Cursor.lockState = CursorLockMode.Locked;
    22.     }
    23.  
    24.     void Update()
    25.     {
    26.         if (!PlayerControl.playerControl.isPaused)
    27.         {
    28.             if (Input.anyKeyDown)
    29.             {
    30.                 Cursor.lockState = CursorLockMode.Locked;
    31.             }
    32.  
    33.             float translation = Input.GetAxis("Vertical") * speed;
    34.             float straffe = Input.GetAxis("Horizontal") * speed;
    35.             translation *= Time.deltaTime;
    36.             straffe *= Time.deltaTime;
    37.  
    38.             Vector3 moveDir = new Vector3(straffe, 0, translation);
    39.             moveDir = transform.TransformDirection(moveDir);
    40.             GetComponent<Rigidbody>().MovePosition(transform.position + moveDir);
    41.  
    42.             if (Input.GetKeyDown(PlayerControl.playerControl.pauseKey))
    43.             {
    44.                 Cursor.lockState = CursorLockMode.None;
    45.             }
    46.         }
    47.     }
    48. }
    The PlayerControl stuff is just a static class holding control schemes.
     
  2. GlenoJacks

    GlenoJacks

    Joined:
    Oct 5, 2016
    Posts:
    2
    It likely is your call to GetComponent<Rigidbody>().MovePosition(transform.position + moveDir);
    It will mostly bypass the rigid bodies collision resolution.
    You may be able to get away with setting the velocity of the Rigidbody directly. That should help it resolve collisions at the intersections of props.

    Generally though you should be using AddForce() on the rigid body instead as that will allow it to void penetrating objects.
    Also you should be setting forces on the rigid body inside void FixedUpdate() instead of void Update() on the MonoBehavior as FixedUpdate() is always called just before the rigid body is simulated.
     
  3. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    putting it in FixedUpdate would be a good start.

    Try to avoid doing physics stuff in Update
     
  4. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    Sorry for the late reply, had a few scripts die on me over the last week or so.

    I have tried a few things to counteract this including:

    Code (CSharp):
    1. GetComponent<Rigidbody>().AddForce(moveDir);
    Code (CSharp):
    1. GetComponent<Rigidbody>().AddForce(transform.position + moveDir);
    Neither of which worked, and left me unable to control the character.

    Is there something different I need to be doing with Force to use it in the same way as MovePosition?
     
  5. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421