Search Unity

How to prevent a kinematic rigidbody to move through walls?

Discussion in 'Scripting' started by CydonianKnight, Jun 24, 2012.

  1. CydonianKnight

    CydonianKnight

    Joined:
    May 19, 2012
    Posts:
    54
    Hello,

    I see this might be quite a basic thing, but I simply can get it to work as intended and am a bit confused with the physics and rigidbody stuff.
    My player character can pick up boxes, that are then parented to the player body to move and rotate according to that object. The boxes are rigidbodies, which are set to kinematic when the player picks them up. However, as the player carries them around, they will just move through the walls of my level, which have only a box collider (not set to trigger) attached. I know that kinematic rigidbodies are not affected by physics but how can I prevent them from passing through level geometry? Do I have to add some additional component to the walls or change something on the boxes?
    Many thanks in advance,

    Kevin
     
  2. cat_ninja

    cat_ninja

    Joined:
    Jul 14, 2010
    Posts:
    197
    jaxsonmorgan76 likes this.
  3. Tiles

    Tiles

    Joined:
    Feb 5, 2010
    Posts:
    2,481
    You could trigger if the objects are touching the walls. And then for example reverse the movement. Depends of the situation.
     
  4. CydonianKnight

    CydonianKnight

    Joined:
    May 19, 2012
    Posts:
    54
    @Cat_Ninja: Well, I'm not explicitly moving the boxes. They are moving according to the player as they are children of this object. I assume, however, that they are moved by internally by using their transform component (it's just a guess though). I will definitely try your suggestion using Rigidbody.MovePosition, I didn't know of that way to move stuff. Thanks alot!
     
    Last edited: Jun 24, 2012
  5. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,822
    Do you have a box collider on your ehhh.. boxes?

    They shouldn't be going through your walls. If so are your walls planes? Rather make the walls cubes.
    By the way, if something is kinematic, it still interacts with physics.

    EDIT : Got this from the documentation..

    "If you move the Transform of a non-Kinematic Rigidbody directly it may not collide correctly with other objects. Instead you should move a Rigidbody by applying forces and torque to it. You can also add Joints to rigidbodies to make the behavior more complex. For example, you could make a physical door or a crane with a swinging chain."

    In summary, perhaps it's best to disable the rigidbody component on a box when you pick it up.
    Then when it gets unparented, re-enable the rigidbody.
     
    Last edited: Jun 24, 2012
  6. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,655
    When dealing with kinematic rigidbodies, Unity assumes that if you moved it somewhere, then you know what you're doing. If that somewhere is halfway inside a wall, then it assumes you know that too. It will try to move other non-kinematic rigidbodies around to account for that, but that's all.

    Ultimately, you've got to decide what should happen when you're holding a crate and walk into a wall. Having the crate intersect the wall is no good, so what should happen instead? Should it stop the whole of your movement? Should the crate slide around in your hands? Should the crate get crushed?

    Half-Life 2's gravity gun, for example, would let you pick up objects, but if you bumped them into the environment they'd be pushed around (and potentially dropped if they got too far away from the tip of the gun). They'd return to the 'center' position when you moved back away from the obstacle. You could do something like this by not parenting the object to the player's hands and making it kinematic, but instead using a physics joint of some kind to have the object be 'pulled around' by the player's hand, while still having the physics system solve against collisions with walls etc.
     
    QuakiTutua and Lyudmil_P like this.
  7. CydonianKnight

    CydonianKnight

    Joined:
    May 19, 2012
    Posts:
    54
    First, yes the boxes have box colliders on them and the walls are cubes, that also have box colliders added.
    I tried disabling (or destroying) the rigidbody of the boxes on pickup but it didn't change anything. They would still go through the walls. Anyway, thanks for the answer.
     
    Last edited: Jun 25, 2012
  8. CydonianKnight

    CydonianKnight

    Joined:
    May 19, 2012
    Posts:
    54
    The player's movement should stop when the box he carries in front of him hits the wall, perhaps I should mention that it's a 2d game.

    I didn't work with such joints yet, but I'll try it out as soon as I have some time, thanks.
     
  9. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    What controller type are you using? if it is a character controller then the box is not counted as part of the collider of the character controller. You need to be using a physics character controller to make this work.
     
  10. CydonianKnight

    CydonianKnight

    Joined:
    May 19, 2012
    Posts:
    54
    I'm actually using a character controller on my character. Never came across a physcis character controller. Is that that simply another component to add (I didn't find such a one though) or how can I add one of these to my character?
     
  11. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,655
    OK. So effectively the box has become 'part' of the player.

    How do you stop the player from walking into walls the rest of the time? I'm guessing you're using CharacterController.(Simple)Move and it's just taking care of collisions for you?
     
  12. CydonianKnight

    CydonianKnight

    Joined:
    May 19, 2012
    Posts:
    54
    That's absolutely correct
     
  13. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
  14. CydonianKnight

    CydonianKnight

    Joined:
    May 19, 2012
    Posts:
    54
  15. Goodeddie

    Goodeddie

    Joined:
    Aug 3, 2016
    Posts:
    79
    Sorry for bumping this but I am having the same issue. I can do something simple where I check my own collisions with a spherecast but I was wondering if there was a built in method that does this now and since it has been 4 years, maybe?
     
  16. wabzi95

    wabzi95

    Joined:
    May 30, 2017
    Posts:
    1
    unity does have a manual layer based collision detection system in place so you could manually configure it so that your objects don't collide. Go to Edit --> Project Settings --> Physics 2D (or Physics, depending on which Physics you've used). At the bottom of that settings panel, you'll find a Layer Collision Matrix, which allows you to choose what can collide with another layer. since this is a layer based collision detection, you need to put all your game objects in layers. You can use existing layers, or better yet, create new layers for your game objects.
    In this case, you could have put the boxes in one layer (and call it Box Layer) and the walls in another layer (call it Environment). You can now uncheck collision between Box and Environment and
     
  17. sgarfer

    sgarfer

    Joined:
    Dec 20, 2017
    Posts:
    1
    Late answer, but also old problem.

    You have two ways;

    - When your Player picks up a box (I guess with OnTriggerEnter) send a message to that box (maybe same which you already use to be parented to Player) to set rigidbody.isKinematic=false; Then, as your Player leaves a box, just set rigidbody.isKinematic=true;

    - Use SweepTest in a script attached to box. It will act as a Raycast even if the box.transform.parent is set to Player and rigidbody.isKinematic is true or false;:
    In that script, just check if something (Wall) will collide with box and stop movement, change direction or whatever your Player should do;

    Code (CSharp):
    1. if (YourRigidBody.SweepTest(transform.forward, out hit, collisionCheckDistance))
    2. // is this object going to collide with something in forward direction in the distance=collisionCheckDistance?
    3. {
    4.    // ok we are in, did it collide whith a Wall?
    5.    if(hit.gameObject.tag=="Wall")
    6.  
    7.    {
    8.         // stop Player, change direction, play sound, drop.... or... set isKinematic=false;
    9.         do events......
    10.  
    11.     }
    12.  
    13. }
    Hope it will help you or anyone who needs
     
    Last edited: Jan 2, 2018
  18. Adam_Benko

    Adam_Benko

    Joined:
    Jun 16, 2018
    Posts:
    105
    Hi. I put my walls to Environment layer and player to player layer. However, my player (isKinematic based controller) always goes through walls (isKinematic walls). I have unchecked everything, tried many variations and still player can go through walls. What am I doing wrong? Thanks

    info: Cube(1), 2 are walls and Cube is player
     

    Attached Files:

  19. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,631
    Why are the walls kinematic? Are they moving walls?

    Do the walls have colliders?

    Are you using MovePosition to move your character?

    Edit: Actually, I think MovePosition will not do collision properly if everything is iskinematic. You can try it, though.

    If your walls are not moving, remove the rigidbodies, keep the colliders, and make them static.

    If you need both the walls and the player to be iskinematic for some reason, then I think you may have to implement your own collision handling. Rigidbody.SweepTest might help:

    https://docs.unity3d.com/ScriptReference/Rigidbody.SweepTest.html
     
    Last edited: Nov 1, 2018
  20. Adam_Benko

    Adam_Benko

    Joined:
    Jun 16, 2018
    Posts:
    105
  21. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,631
    So it works most of the time, but occasionally pokes through? Have you tried setting the collision mode of the player to continuous?
     
  22. Adam_Benko

    Adam_Benko

    Joined:
    Jun 16, 2018
    Posts:
    105
    Hi. I have messed up and now I cant reproduce the behaviour shown on the video. Now the player wont collide with the wall what so ever. Here are the 2 objects.
    Am I doing something wrong? Thanks for help.
     

    Attached Files:

  23. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,631
    One weird thing I noticed is that your PlayerController script has an unassigned Rigidbody2D but your object has a regular Rigidbody. Unity has a separate 2d and 3d physics system so you want to use either 1) only Rigidbodies and 3d colliders or 2) only Rigidbody2D and 2D colliders.

    If your PlayerController script relies on Rigidbody2d than you will either have to change your script, or change your Rigidbodies and colliders to the 2d equivalents.
     
    Adam_Benko likes this.
  24. Adam_Benko

    Adam_Benko

    Joined:
    Jun 16, 2018
    Posts:
    105
    Hi, I solved this problem by using 3D physics in 2D game. Player and ship has 3D colliders but still only 2D textures.
    Thanks for the response.
     
  25. Lyudmil_P

    Lyudmil_P

    Joined:
    Oct 11, 2017
    Posts:
    1
    Even in 2019 this post helped me :D
     
    Hagen and superpig like this.