Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

My Player dies only when he wants to?!?

Discussion in 'Scripting' started by harraj128, Sep 30, 2016.

  1. harraj128

    harraj128

    Joined:
    Sep 25, 2016
    Posts:
    6
    I have a problem where the character will not die randomly but he will at other times. for example if he falls into lava he should die but sometimes he can survive.

    Code (CSharp):
    1.     void OnCollisionEnter2D (Collision2D other)
    2.         {
    3.  
    4.      if (other.gameObject.tag == "killbox" && spawnProtection == false && lava == true) {
    5.                 theGameManager.RestartGame ();
    6.     }
    7.     }
    My lava contains the killbox tag, but it just won't work properly. Yet if I remove the Lava == trueit will kill the player everytime he lands in the lava. I however need this condition to detect if the player is in collision with the lava to destroy him.

    My lava snippet:

    Code (CSharp):
    1. lava = Physics2D.IsTouchingLayers (myCollider, whatIsLava);
    Any help would be grateful! Thanks
     
    Last edited: Sep 30, 2016
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
  3. harraj128

    harraj128

    Joined:
    Sep 25, 2016
    Posts:
    6
  4. Pagi

    Pagi

    Joined:
    Dec 18, 2015
    Posts:
    132
    I don't get it. You mean there are many killboxes, but only some of them are lava and that's why you have the 'lava' check? In that case,when do you assign the lava variable? If you call IsTouchingLayers once and then use the variable for all collisions, 'lava' will still hold answer from the one check, it doesn't check again. To do that, you could set lava like this:
    Code (CSharp):
    1. bool Lava{
    2. get{return Physics2D.IsTouchingLayers(myCollider, whatIsLava);}
    3. }
    If all killboxes are lava, then the lava check is pointless.

    I would propose other solution than using tags, which could tell you what kind of killbox it is, and also without using that nasty physics check(I'd guess it checks against all colliders in that layer in the scene, and while it will not lag your game, it is not fast). You can do something like this:
    Code (CSharp):
    1. //untested
    2. public enum DamageType{
    3.     Lava,
    4.    DeadlyRay,
    5.    HotPan
    6. }
    7. class KillBox{
    8.    public DamageType damageType;
    9. }
    10. class Player{
    11.    void OnCollision...(Collision2D other){
    12.       KillBox box = other.gameObject.GetComponent<KillBox>();
    13.       if(box != null && box.damageType = DamageType.Lava){
    14.       Destroy(this.gameObject);//restart game or something
    15.    }
    16. }
    17. }
    You put on all dangerous object the KillBox class and set the damage type in inspector. You can also add how much damage it does and so on if you want.

    EDIT: I don't know the real answer to your question, but it is really pointless to collide and then go through all colliders to know if the thing was lava. You could also just check the 'other' collider's physics layer if it is the lava one
     
  5. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Still don't get what you're going.

    I first make a "death" collider that's a trigger, which the player has to touch. I tag that collider as "death" or whatever you want.

    Then, I put this code on the player (make sure player has a solid collider and Rigidbody).

    Code (CSharp):
    1. void OnTriggerEnter(Collider other)
    2. {
    3.     if (other.gameObject.Tag == "death")
    4.     {
    5.         //die
    6.     }
    7. }
    That's what I've used in every single one of my projects with no problems.
     
    Ryiah likes this.
  6. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    967
    You should be using CompareTag instead. For an explanation why, see this link.
     
    DroidifyDevs likes this.
  7. harraj128

    harraj128

    Joined:
    Sep 25, 2016
    Posts:
    6
    Basically the problem I have is this. When the player jumps and lands on the lava he dies. However if I press continue which allows me to continue the game, if the player just doesn't move at all, he will not die. It requires him to actually "collide" by jumping and falling down into that lava.. This is what i'm trying to overcome
     
  8. harraj128

    harraj128

    Joined:
    Sep 25, 2016
    Posts:
    6
    How would I implement CompareTag in function with multiple conditions??

    Example:

    Code (CSharp):
    1. else if (other.gameObject.tag == "killbox" && spawnProtection == false && deathCount <= 0)
    Thanks
     
  9. Pagi

    Pagi

    Joined:
    Dec 18, 2015
    Posts:
    132
    Code (CSharp):
    1. else if (other.gameObject.CompareTag("killbox") && spawnProtection == false && deathCount <= 0)
    When already colliding with an object, reenabling the rigidbody or collider can help, or else moving the objectaway and back(hacky). In that case IsTouchingLayer is not that bad, BUT checking for it in collision code is useless, because you are trying to solve the problem of collision code not firing at all. If you put that code into the continue method though, its should work
    Code (CSharp):
    1. void ClickedContinue(){
    2.     if(!Physics2D.IsTouchingLayers (myCollider, whatIsLava)){
    3.         ContinueGame();
    4.     }
    5.     else GameOver();
    6. }
     
  10. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    967
    Just replace other.gameObject.tag == "killbox" with other.gameObject.CompareTag("killbox")

    Code (CSharp):
    1. else if (other.gameObject.CompareTag("killbox") && spawnProtection == false && deathCount <= 0)
    Don't remember if you need .gameObject, you can probably also use just other.CompareTag()
     
  11. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    967
    This is because you are using OnCollisionEnter2D, this will only trigger when the player enters the collider. You could use IsTouchingLayers, IsTouching, Physics2D.Overlap* methods, or just use OnCollisionStay2D instead, which will trigger every frame the collision occurs, not just when it enters.
     
    DroidifyDevs likes this.