Search Unity

Box Collider 2D, trigger not working properly. Possible bug?

Discussion in '2D' started by scorpion77, Mar 18, 2018.

  1. scorpion77

    scorpion77

    Joined:
    Jan 13, 2018
    Posts:
    15
    Hi everyone, I'm trying to make a 2D platformer. I created a script that manages player interaction with a ladder. Everything works fine except for one thing, which I think is a Unity bug. I state first that I am using the latest version available (2017.3.1f1). If I open Unity and my player tries to climb the ladder, it will collide with it, as if the 2D Box Collider is not trigger (but it is trigger!). However, if I kill my player, after the respawn routine, the ladder works as it should, or rather the player can use it without going to collide with it. What can it depend on? Is it a known bug? Has this already happened to anyone?

    Thanks for your help.
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I've not heard of that bug, but ya never know. Just make sure to check that it's not hitting something else. You can even Debug.Log the name of the collider -> gameObject's -> name to see what you've hit to confirm what's going on in the scene before you respawn.
     
  3. xboxhelp

    xboxhelp

    Joined:
    Mar 19, 2018
    Posts:
    1
  4. scorpion77

    scorpion77

    Joined:
    Jan 13, 2018
    Posts:
    15
    I wrote this code:



    Debug.Log(myCollider);



    myCollider = GetComponent<CapsuleCollider2D>(); --> which is the collider attached to Player.



    When I press play, I got this in Unity Console:



    Player (UnityEngine.CapsuleCollider2D)
    UnityEngine.Debug:Log(Object)
    PlayerController:Update() (at Assets/Scripts/PlayerController.cs:102)



    I can't see anything useful. What am I doing wrong?
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I think you could add it into OnCollisionEnter2D.
    If it was on the player, just look for the collision object's 'collider.gameObject.name', I think. That should print out the name of the hit game object.
     
  6. scorpion77

    scorpion77

    Joined:
    Jan 13, 2018
    Posts:
    15
    OK, it seems weird! How is it possible?
    I wrote this into OnCollisionEnter2D:

    if (other.gameObject.name == "LadderStart")
    {
    Debug.Log("Ladder");
    }

    Nothing happens. But if I add the same into OnTriggerEnter2D, I got this on console:

    Ladder
    UnityEngine.Debug:Log(Object)
    PlayerController:OnTriggerEnter2D(Collider2D) (at Assets/Scripts/PlayerController.cs:348)

    Therefore, my player hit a trigger, not a normal collider. Why it get stuck in front of the ladder instead of go through it?
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You should try to add (on the player, just for testing) :
    Code (csharp):
    1. void OnCollisionEnter(Collision other) {
    2.    print("Collided with : " + other.gameObject.name);
    3.  }
    That way the player can report everything it runs into , so when you hit your ladders, just try to figure it out. :)
    Then if you can fix it, just erase that code ;)
     
  8. scorpion77

    scorpion77

    Joined:
    Jan 13, 2018
    Posts:
    15
    This is the output of console, copied from Editor Log:


    Collided with : PlatformLeft (1)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)

    Collided with : PlatformCenter (1)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)

    Collided with : GroundSurfaceCenter (4)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)

    Collided with : GroundSurfaceCenter (5)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)

    Collided with : OneWayPlatform
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)

    Collided with : OneWayPlatform (1)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)

    Collided with : GroundSurfaceCenter (6)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)

    Collided with : GroundSurfaceCenter (7)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    UnityEngine.MonoBehaviour:print(Object)
    PlayerController:OnCollisionEnter2D(Collision2D) (at Assets\Scripts\PlayerController.cs:374)
    (Filename: Assets/Scripts/PlayerController.cs Line: 374)


    No collision detected with the ladder, but my player actually collide with ladder! If it can be useful, I can share my entire project, with all assets, maybe in a private message, via Google Drive or similar.
    Thanks in advance.

    EDIT:

    I did some tests, maybe they can be useful to solve this problem.

    I built my project and ran the .exe file. I noticed that my player get stuck in the ladder, and he can only turn right and left, without advancing. While if I play the game in Unity, my player get stuck in the ladder, but he can climb the ladder until he reaches the end of the ladder and manages to free himself and If my player dies, interaction with the ladder works perfectly.

    On the contrary, using the .exe file, if my player dies, there is no interaction with the ladder, simply he goes through it, without the possibility to climb the ladder. I’m becoming crazy! Please help me! Thank you very much.
     
    Last edited: Mar 21, 2018
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Hmm.. that sucks. I'm sorry you couldn't figure out the answer from the logs. I thought you might noticing the character hitting some gameobject near the ladder or something.
    Though, overall it was confusing as the player can use the ladder after respawning.

    I suppose if you can attach the scene to the thread or a pm, either as a unity package or just zipped up on google drive, I could try to take a look when I have some time.
     
    scorpion77 likes this.
  10. scorpion77

    scorpion77

    Joined:
    Jan 13, 2018
    Posts:
    15
    I understood that the problem of collision with the ladder was caused by the player movement management inside the ladder script that was in conflict with the player movement management in the playercontroller script. I fixed that. However, there are still some problems. If the player reaches a ladder, onLadder variable stay false instead of being true. Why? Furthermore, when the player is in a piece of the ladder where there is also some terrain, gravity returns to normal, instead of staying at 0, as it should do according to OnTriggerExit2D. This is the source code of Ladder.cs:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Ladder : MonoBehaviour
    6. {
    7.  
    8.     public Collider2D platformCollider;
    9.     public PlayerController thePlayer;
    10.     public bool onLadder;
    11.     public bool isClimbing;
    12.  
    13.  
    14.     // Use this for initialization
    15.     void Start()
    16.     {
    17.  
    18.         thePlayer = FindObjectOfType<PlayerController>();
    19.     }
    20.  
    21.  
    22.  
    23.     void OnTriggerEnter2D(Collider2D other)
    24.     {
    25.  
    26.         if (other.tag == "Player")
    27.         {
    28.             onLadder = true;
    29.             thePlayer.GetComponent<Animator>().SetBool("Ladder", onLadder);
    30.             Physics2D.IgnoreCollision(thePlayer.GetComponent<Collider2D>(), platformCollider, true);
    31.         }
    32.  
    33.     }
    34.  
    35.     void OnTriggerExit2D(Collider2D other)
    36.     {
    37.         if (other.tag == "Player")
    38.         {
    39.             onLadder = false;
    40.             thePlayer.GetComponent<Animator>().SetBool("Ladder", onLadder);
    41.             isClimbing = false;
    42.             thePlayer.GetComponent<Animator>().SetBool("Climbing", onLadder);
    43.             thePlayer.GetComponent<Rigidbody2D>().gravityScale = 2.5f;
    44.             Physics2D.IgnoreCollision(thePlayer.GetComponent<Collider2D>(), platformCollider, false);
    45.         }
    46.     }
    47.  
    48. }
    This is the source code of PlayerController.cs:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerController : MonoBehaviour
    5. {
    6.  
    7.     public float moveSpeed;
    8.     private float activeMoveSpeed;
    9.  
    10.     public bool canMove;
    11.  
    12.     public Rigidbody2D myRigidbody;
    13.  
    14.     public float jumpSpeed;
    15.  
    16.     public Transform groundCheck;
    17.     public float groundCheckRadius;
    18.     public LayerMask whatIsGround;
    19.  
    20.  
    21.     public Transform ladderCheck;
    22.     public float ladderCheckRadius;
    23.     public LayerMask whatIsLadder;
    24.  
    25.     public Transform oneWayPlatformCheck;
    26.     public float oneWayPlatformCheckRadius;
    27.     public LayerMask whatIsOneWayPlatform;
    28.  
    29.     public bool isOneWayPlatform;
    30.  
    31.     //public bool onLadder;
    32.  
    33.     public bool isGrounded;
    34.  
    35.     public bool isClimbing;
    36.     public bool isJumping;
    37.  
    38.     private Animator myAnim;
    39.  
    40.     public Vector3 respawnPosition;
    41.  
    42.     public LevelManager theLevelManager;
    43.  
    44.     public GameObject stompBox;
    45.  
    46.     public float knockbackForce;
    47.     public float knockbackLenght;
    48.     private float knockbackCounter;
    49.  
    50.     public float invincibilityLenght;
    51.     private float invincibilityCounter;
    52.  
    53.     public AudioSource jumpSound;
    54.     public AudioSource hurtSound;
    55.  
    56.     private bool onPlatform;
    57.     public float onPlatformSpeedModifier;
    58.  
    59.     public GameObject background;
    60.  
    61.     //public float myGravity;
    62.  
    63.     public CapsuleCollider2D myCollider;
    64.  
    65.     public Ladder theLadder;
    66.  
    67.     // Use this for initialization
    68.     void Start()
    69.     {
    70.         myRigidbody = GetComponent<Rigidbody2D>();
    71.         myAnim = GetComponent<Animator>();
    72.  
    73.         respawnPosition = transform.position;
    74.  
    75.         theLevelManager = FindObjectOfType<LevelManager>();
    76.  
    77.         activeMoveSpeed = moveSpeed;
    78.  
    79.         canMove = true;
    80.  
    81.         //myRigidbody.gravityScale = myGravity;
    82.  
    83.         myCollider = GetComponent<CapsuleCollider2D>();
    84.  
    85.         theLadder = FindObjectOfType<Ladder>();
    86.  
    87.  
    88.     }
    89.  
    90.     // Update is called once per frame
    91.     void Update()
    92.     {
    93.  
    94.  
    95.         isJumping = true;
    96.  
    97.  
    98.         isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
    99.         //onLadder = Physics2D.OverlapCircle(ladderCheck.position, ladderCheckRadius, whatIsLadder);
    100.         isOneWayPlatform = Physics2D.OverlapCircle(oneWayPlatformCheck.position, oneWayPlatformCheckRadius, whatIsOneWayPlatform);
    101.  
    102.  
    103.  
    104.         if (isGrounded)
    105.         {
    106.             isJumping = false;
    107.  
    108.         }
    109.  
    110.  
    111.         myAnim.SetBool("OneWay", false);
    112.  
    113.         if (isOneWayPlatform)
    114.         {
    115.      
    116.             if (myRigidbody.velocity.y == 0f)
    117.             {
    118.                 isGrounded = true;
    119.                 isJumping = false;
    120.                 myAnim.SetBool("OneWay", isOneWayPlatform);
    121.             }
    122.  
    123.         }
    124.  
    125.         if (knockbackCounter <= 0 && canMove)
    126.         {
    127.  
    128.             if (onPlatform)
    129.             {
    130.                 activeMoveSpeed = moveSpeed * onPlatformSpeedModifier;
    131.             }
    132.             else
    133.             {
    134.                 activeMoveSpeed = moveSpeed;
    135.             }
    136.  
    137.  
    138.             if (Input.GetAxisRaw("Horizontal") > 0f)
    139.             {
    140.                 myRigidbody.velocity = new Vector3(activeMoveSpeed, myRigidbody.velocity.y, 0f);
    141.                 transform.localScale = new Vector3(1f, 1f, 1f);
    142.             }
    143.             else if (Input.GetAxisRaw("Horizontal") < 0f)
    144.             {
    145.                 myRigidbody.velocity = new Vector3(-activeMoveSpeed, myRigidbody.velocity.y, 0f);
    146.                 transform.localScale = new Vector3(-1f, 1f, 1f);
    147.             }
    148.             else
    149.             {
    150.                 myRigidbody.velocity = new Vector3(0f, myRigidbody.velocity.y, 0f);
    151.             }
    152.  
    153.  
    154.             if (theLadder.onLadder)
    155.             {
    156.  
    157.                 myRigidbody.velocity = new Vector3(0f, 0f, 0f);
    158.                 myRigidbody.gravityScale = 0f;
    159.  
    160.                 //onLadder = true;
    161.                 //thePlayer.GetComponent<Animator>().SetBool("Ladder", onLadder);
    162.                 isJumping = false;
    163.                 myAnim.SetBool("Jump", isJumping);
    164.  
    165.  
    166.                 if (Input.GetAxisRaw("Vertical") > 0f)
    167.                 {
    168.  
    169.                     myRigidbody.velocity = new Vector3(myRigidbody.velocity.x, activeMoveSpeed * 0.5f, 0f);
    170.                     isClimbing = true;
    171.                     myAnim.SetBool("Climbing", isClimbing);
    172.  
    173.  
    174.                 }
    175.                 else if (Input.GetAxisRaw("Vertical") < 0f)
    176.                 {
    177.  
    178.                     myRigidbody.velocity = new Vector3(myRigidbody.velocity.x, -activeMoveSpeed * 0.5f, 0f);
    179.                     isClimbing = true;
    180.                     myAnim.SetBool("Climbing", isClimbing);
    181.  
    182.                 }
    183.                 else if (Input.GetAxisRaw("Vertical") == 0f)
    184.                 {
    185.  
    186.                     isClimbing = false;
    187.                     myAnim.SetBool("Climbing", isClimbing);
    188.  
    189.                 }
    190.  
    191.             }
    192.      
    193.             //print("onLadder : " + theLadder.onLadder);
    194.             //print("isGrounded : " + isGrounded);
    195.  
    196.             if (Input.GetButtonDown("Jump") && isGrounded)
    197.             {
    198.  
    199.                 isJumping = true;
    200.  
    201.  
    202.                 if (myRigidbody.velocity.y > 0f)
    203.                 {
    204.  
    205.                 }
    206.                 else if (myRigidbody.velocity.y < 0f)
    207.                 {
    208.  
    209.                 }
    210.                 else if (myRigidbody.velocity.y == 0f)
    211.                 {
    212.                     myRigidbody.velocity = new Vector3(myRigidbody.velocity.x, jumpSpeed, 0f);
    213.                     jumpSound.Play();
    214.                 }
    215.  
    216.             }
    217.  
    218.         }
    219.  
    220.         if (knockbackCounter > 0)
    221.         {
    222.             knockbackCounter -= Time.deltaTime;
    223.  
    224.             if (transform.localScale.x > 0)
    225.             {
    226.                 myRigidbody.velocity = new Vector3(-knockbackForce, knockbackForce, 0f);
    227.             }
    228.             else
    229.             {
    230.                 myRigidbody.velocity = new Vector3(knockbackForce, knockbackForce, 0f);
    231.             }
    232.         }
    233.  
    234.         if (invincibilityCounter > 0)
    235.         {
    236.             invincibilityCounter -= Time.deltaTime;
    237.         }
    238.  
    239.         if (invincibilityCounter <= 0)
    240.         {
    241.             theLevelManager.invincible = false;
    242.         }
    243.  
    244.         myAnim.SetFloat("Speed", Mathf.Abs(myRigidbody.velocity.x));
    245.         myAnim.SetBool("Grounded", isGrounded);
    246.         //myAnim.SetBool("Ladder", onLadder);
    247.         //myAnim.SetBool("Climbing", isClimbing);
    248.         myAnim.SetBool("Jump", isJumping);
    249.  
    250.  
    251.         if (myRigidbody.velocity.y < 0)
    252.         {
    253.             stompBox.SetActive(true);
    254.         }
    255.         else
    256.         {
    257.             stompBox.SetActive(false);
    258.         }
    259.     }
    260.  
    261.     public void Knockback()
    262.     {
    263.         knockbackCounter = knockbackLenght;
    264.         invincibilityCounter = invincibilityLenght;
    265.         theLevelManager.invincible = true;
    266.         //Start the animation when hit a enemy or something damaging
    267.         myAnim.SetBool("Hit", true);
    268.         StartCoroutine("HitTime");
    269.     }
    270.  
    271.     public IEnumerator HitTime()
    272.     {
    273.         yield return new WaitForSeconds(0.5f);
    274.         myAnim.SetBool("Hit", false);
    275.     }
    276.  
    277.     void OnTriggerEnter2D(Collider2D other)
    278.     {
    279.         if (other.tag == "KillPlane")
    280.         {
    281.  
    282.  
    283.  
    284.             theLevelManager.Respawn();
    285.  
    286.  
    287.         }
    288.  
    289.         if (other.tag == "Checkpoint")
    290.         {
    291.             respawnPosition = other.transform.position;
    292.         }
    293.  
    294.     }
    295.  
    296.  
    297.     void OnCollisionEnter2D(Collision2D other)
    298.     {
    299.         if (other.gameObject.tag == "MovingPlatform")
    300.         {
    301.             transform.parent = other.transform;
    302.             onPlatform = true;
    303.         }
    304.  
    305.  
    306.         if (other.gameObject.tag == "OneWayPlatform")
    307.         {
    308.             isGrounded = false;
    309.         }
    310.  
    311.         //print("Collided with : " + other.gameObject.name);
    312.  
    313.     }
    314.  
    315.     void OnCollisionExit2D(Collision2D other)
    316.     {
    317.         if (other.gameObject.tag == "MovingPlatform")
    318.         {
    319.             transform.parent = null;
    320.             onPlatform = false;
    321.         }
    322.  
    323.     }
    324.  
    325. }
    Thank you for your help.
     
    Last edited: Mar 22, 2018
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Sorry, nothing really stood out at me, but I have a feeling that if you add some debug statements and investigate why what you want to happen isn't happening you can figure it out.

    Try to track down where & why your variables change (when you don't want them to) and what's causing it.