Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

CharacterController and ignoring Collision

Discussion in 'Physics' started by teremy, Sep 11, 2015.

  1. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    Hello.
    I'm creating a 3D bomberman game.
    I just started using the character controller. My problem is, when the character plants a bomb, the bomb is inside of him, if I start moving while the bomb is inside of the character, then the character gets pushed away in an unwanted manner.
    When I made the game in 2D I was just ignoring collision with the bomb and had another trigger collider attached to the bomb that made enabled collision with the character, when the character exited the trigger.
    I used Physics2D.IgnoreCollision and I know there is Physics.IgnoreCollision, but how do I get the collider of the CharacterController ? I can put in a reference to the CharacterController as an argument to IgnoreCollision, but it is still colliding with the bomb. Is there any way to not have the CharacterController collide with a specific collider? I can't just disable the bombs collider, because there are also other players...
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    1,349
    How about just putting player and bomb in a layer, then in Physics settings make it ignore itself, or put bomb in one layer and player in other, and make them ignore each other. In Bomberman/Dynablaster like game player shouldn't collide with bomb before he is outside of surface of a bomb, then you can maybe deal with the blocking effect, by enabling some collider that is in a layer that collider with player.
     
  3. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    What you describe about bomberman/dynablaster is the behaviour I want in my game. It worked when using 2D, I just don't know how I can manage the Collider of the CharacterController.
    How do I get a reference to the Collider of the Character Controller? Then I could just use Physics.IgnoreCollision.
    If I ignore collision with whole layers, then the problem is, that other players will also ignore the collision and can walk through the bomb, which is not what I want. I just want to ignore the collision with players that stand in the bomb, when the bomb is planted, then whatever player is not touching the bomb anymore, the collision won't be ignored anymore, so they cannot go through the bomb again.
    As I said, I have done this before, I just don't know how to use Physics.IgnoreCollision with the CharacterController's collider.
     
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    1,349
    I don't know if Ignore collision is your best choice. I'd make this setup with trigger.
     
  5. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    I am also using triggers, but what exactly do you mean? The bomb has 2 BoxColliders, one so you can't just walk into a bomb, and the second one is a trigger, so when planting the bomb, I can use the trigger collider to call Physics.IgnoreCollision with the other collider and the collider of the player. Now the only problem is, the player doesn't have a collider, it only has the CharacterController, but I don't know how to access the collider of the CharacterController ( the CapsuleCollider ), so I can use it as an argument for Physics.IgnoreCollision. This solution worked great when the game was 2D, now I just need to get a reference to the CharacterController's collider, which I don't know how.
     
  6. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    1,349
    Sorry if I sound bit too dense (I am). Simply put, CharacterController *is collider* as it inherits from collider class, you can use something like this:

    Code (csharp):
    1.  
    2. Physics.IgnoreCollision(charCon, bombTra.GetComponent<Collider>());
    3.  
    Does this get you past your problem?
     
  7. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    1,349
    To make sure, I had to code along:

    Bomb setup:
    BoxCollider, as trigger
    BoxCollider, not trigger

    Player setup:
    CharacterController
    DropBomb Script:
    Code (csharp):
    1.  
    2. void Start ()
    3. {
    4.    charCon = this.GetComponent<CharacterController>();
    5. }
    6.  
    7. void Update ()
    8. {
    9.    if (Input.GetKeyDown(KeyCode.Space)) LayBomb();
    10.    if (Input.GetKey(KeyCode.RightArrow)) charCon.Move(Vector3.right * Time.deltaTime);
    11.    if (Input.GetKey(KeyCode.LeftArrow)) charCon.Move(-Vector3.right * Time.deltaTime);
    12. }
    13.  
    14. void LayBomb()
    15. {
    16.    // drop bomb
    17.    bombTra = Instantiate(bombFab) as Transform;
    18.    bombTra.position = transform.position;
    19.  
    20.    // Start ignoring collisions
    21.    Physics.IgnoreCollision(charCon, bombTra.GetComponent<Collider>());
    22. }
    23.  
    24.  
    25. void OnTriggerExit(Collider col)
    26. {
    27.    // stop ignoring collisions
    28.    Physics.IgnoreCollision(charCon, bombTra.GetComponent<Collider>(),false);
    29. }
    30.  
    Now the player can drop a bomb, walk inside it, but as soon as he exits the perimeter, collisions are once again active. As this should only happen between player-bomb, other players and enemies won't be able to walk past bomb when it's dropped and player is "inside" bomb. Didn't test this part, but other than that it works. Let me know if you got it working!
     
  8. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    Thanks for your effort!
    So you are just passing the charactercontroller as an argument to Physics.IgnoreCollision, but that doesn't seem to work.
    Also using .GetComponent<Collider>() on the bomb object I don't know what I get, since I have 2 colliders.
    Here is my code:
    Code (CSharp):
    1. Collider collider = null;
    2. foreach (Collider coll in bomb.GetComponents<Collider> ())
    3. {
    4.   if (!coll.isTrigger) { collider = coll; }
    5.   else { }
    6. }
    7. Physics.IgnoreCollision(collider, controller);
    This doesn't work, its still colliding with the bomb. I also tried it without GetComponent instead of GetComponents, but to no avail. :/

    EDIT: I tried to ignore other colliders of the map and it behaved very strangely, anyway I am away for 8 days now, will take a look at it with a fresh mind then ;D.
     
    Last edited: Sep 11, 2015
  9. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    547
    There is a huge bug currently with physics.ignore collision where all objects in the hierarchy reset there trigger states calling on trigger exit and enter. Watch out for it. It will cause tons of issues that are hard to track. sounds like this bug could be part of your problem.
     
  10. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    Looks like there is something wrong with it. Has anyone tried using Physics.IgnoreCollision with the CharacterController? Maybe I will start looking for a custom character controller.
     
  11. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    547
    The problem with physics.ignore collision is related to unity integration of physx. Needs to be fixed by them.
     
  12. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    That's bad... I'm stuck with this problem for too many days now.
    I added another CharacterController in the scene and Physics.IgnoreCollision works if I put the two CharacterControllers in it. I wonder why it's not working with other colliders.
    Maybe I will just use a trigger collider instead and solve collision ( pushing back the character ) myself...
     
  13. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    547
    Yeah, that's what I did for my projectiles. I changed everything to work with triggers so I could not use Physics.IgnoreCollision at all (as this important feature is almost 100% useless due to the resetting of trigger states) and then in my OnTriggerEnter code manually apply the early out. E.g.
    OnTriggerEnter
    {
    if(!hasLeftBomb)
    return;
    }

    Also I'd open the bug with Unity. I contacted people there directly as the functionality is in their manual and thus they didn't see it as a bug, but it would help to show this is effecting more people in the community.
     
  14. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    It works now. -.-
    It was my mistake all along. I had a child game object that had a sphere collider ( didn't knew about that ). That's why it was always colliding. You can actually use Physics.IgnoreCollision with the CharacterController and any collider. I don't know if there is a problem with OnTriggerEnter or something though. For now everything seems to work. I wanted to create workaround using Physics.IgnoreLayerCollision and at some point noticed the other collider.
     
  15. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    547
    Glad it works for you:
    When you call Physics.IgnoreCollision on say a bullet and a gun held in a characters hand the following will happen:

    The bullet, gun, and character holding the gun:
    Will leave all triggers (causing OnTriggerExit() to call)
    Will enter all triggers (causing OnTriggerEnter() to call).

    So imagine a character is standing on a pressure plate trigger that opens a door. Each time they fire their gun the bullet will ignore the gun and thus the entire hierarchy leaves the trigger. So you the door would get a message to close and then to open again as if the character stepped off and back onto the pressure plate (you'd hear both sounds) Watch out for the above condition. Sounded like your problem, glad it wasn't.
     
  16. teremy

    teremy

    Joined:
    May 2, 2015
    Posts:
    76
    Thanks for your help btw., you told me I could just use the CharacterController as a collider, which I didn't know. Everything else was just my mistake ;)