Cannot enable collider

All I am doing is setting collider to false and then true in Update(). The false part is working, the true part is giving me error.

Cannot create Collider2D shapes if shapes already exist.
UnityEngine.Behaviour:set_enabled(Boolean)
PlayerMovement:Update() (at Assets/Scripts/PlayerMovement.cs:34)

Assertion failed on expression: ‘GetShape() == NULL’
UnityEngine.Behaviour:set_enabled(Boolean)
PlayerMovement:Update() (at Assets/Scripts/PlayerMovement.cs:34)

Unity Version - 2019.2.6f1
OS : Windows 10

5179418–514199–PlayerMovement.cs (1.57 KB)

Please, post your code using code tags.

Disabling and enabling colliders:

using UnityEngine;

public class Test : MonoBehaviour
{
    public Collider cube;

    private void Start()
    {
        cube.GetComponent<Collider>();
    }
    private void Update()
    {
        if(cube.enabled == false)
        {
            cube.enabled = true;
        }
        else
            return;
    }
}

Hi @
Thanks for your reply.

All I am doing is inside Update(), setting collider to false, then immediately true.
This is giving me the above errors.

    Collider2D col;

    Rigidbody2D rb;

    void Start()
    {
        JumpForce = new Vector3(0, JumpForceMagnitude, 0);
        rb = GetComponent<Rigidbody2D>();
        col = GetComponent<Collider2D>();
    }


   void Update()
    {
        if (rb.velocity.y > 0)
        {
            if(col.enabled == true)
            col.enabled = false;
        }
        else
        {
            if (col.enabled == false)
                col.enabled = true;
        }
}

You didn’t post your original script, so I had to download it and open it. Your Update () looks like that:

void Update()
    {
        //if (rb.velocity.y > 0)
        //{
        //    GetComponent<BoxCollider2D>().enabled = false;
        //}
        //else
        //{
        //    GetComponent<BoxCollider2D>().enabled = true;
        //}

        col.enabled = false;
        col.enabled = true;

        //if (max < transform.position.y)
        //    max = transform.position.y;

        //Debug.Log(max);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (transform.parent != null) // If player is on platform, jump up
            {
                rb.AddForce(JumpForce, ForceMode2D.Impulse);
            }
            else
                rb.AddForce(-JumpForce, ForceMode2D.Impulse);

        }
    }
  • “col.enabled = false;” immediately followed by “col.enabled = true;” doesn’t make any sense,
  • you must put “GetComponent()” only once in Start () not in Update().

This compiles:

    public float JumpForceMagnitude = 10000f;
    public float max = 0;
    Vector3 JumpForce;

    Collider2D col;
    Rigidbody2D rb;

    void Start()
    {
        JumpForce = new Vector3(0, JumpForceMagnitude, 0);
        rb = GetComponent<Rigidbody2D>();
        col = GetComponent<Collider2D>();
    }

    void Update()
    {
        if(rb.velocity.y > 0)
        {
            col.enabled = false;
        }
        else
            return;

        if(max < transform.position.y)
            max = transform.position.y;

        Debug.Log(max);

        if(Input.GetKeyDown(KeyCode.Space))
        {
            if(transform.parent != null)
            {
                rb.AddForce(JumpForce, ForceMode2D.Impulse);
            }
            else
                rb.AddForce(-JumpForce, ForceMode2D.Impulse);
        }
    }

The code for the file is:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float JumpForceMagnitude = 10000f;
    Vector3 JumpForce;
    float MaxHeight = 20.97323f; // This is the height that the player jumps
    //float max = 0;
    Collider2D col;

    Rigidbody2D rb;

    void Start()
    {
        JumpForce = new Vector3(0, JumpForceMagnitude, 0);
        rb = GetComponent<Rigidbody2D>();
        col = GetComponent<Collider2D>();
    }

    void Update()
    {
        if (rb.velocity.y > 0)
        {
            if(col.enabled == true)
            col.enabled = false;
        }
        else
        {
            if (col.enabled == false)
                col.enabled = true;
        }



        //if (max < transform.position.y)
        //    max = transform.position.y;

        //Debug.Log(max);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (transform.parent != null) // If player is on platform, jump up
            {
                rb.AddForce(JumpForce, ForceMode2D.Impulse);
            }
            else
                rb.AddForce(-JumpForce, ForceMode2D.Impulse);

        }
    }

    private void OnCollisionStay2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Platform")
        {
            transform.parent = collision.transform;
        }
    }
    private void OnCollisionExit2D(Collision2D collision)
    {
        transform.parent = null;
    }
}

I am calling GetComponent exactly once.

As you said, setting collider to false and true immediately doesnt make sense, yeah but it should work right. I am getting the Runtime Errors (not compilation errors) as :

Cannot create Collider2D shapes if shapes already exist.
UnityEngine.Behaviour:set_enabled(Boolean)
PlayerMovement:Update() (at Assets/Scripts/PlayerMovement.cs:32)

Assertion failed on expression: ‘GetShape() == NULL’
UnityEngine.Behaviour:set_enabled(Boolean)
PlayerMovement:Update() (at Assets/Scripts/PlayerMovement.cs:32)

I don’t know about your error messages; I cannot get them to reproduce.

The thing is that the following code makes the collider be enable and disabled once per frame, one frame the collider is enabled, the following frame it’s disabled and so on (which could explain your error messages):

    if(col.enabled == false)
        {
            col.enabled = true;
        }
        else
            if(col.enabled == true)
        {
            col.enabled = false;
        }

The following code avoids this flipping problem:

    if(col.enabled == false)
        {
            col.enabled = true;
        }
        else
            return;

Yeah you are correct about the way to set collider enabled or disabled!
But I am doing this:

if (rb.velocity.y > 0)
        {
            if(col.enabled == true)
            col.enabled = false;
        }
        else
        {
            if (col.enabled == false)
                col.enabled = true;
        }

Which means if object is going up, then its velocity is +ve, else -ve. So while going up I am setting it as false.

Thanks for your time!

For reproducing the issue:
https://github.com/Mithil467/L-B

You can please try to clone this to see the bug, I updated my unity to latest version and still got the bug.

It’s not a bug. Just change the script as I mentioned and the problem will be solved. I cannot help you more if you don’t want to listen.

But your script is setting the collider to on if it’s off. I want it to toggle when it goes up vs comes down. I think my code is fine and the instantaneous toggle isn’t causing the runtime error. There is something else about this.

1 Like

I got it working by keeping the exact same code but changing col.enabled = true and false to isTrigger = false and true. So instantaneous toggle isn’t really a problem, else this code would also have given unexpected results.

You might try putting the relevant code into FixedUpdate, to avoid calling it more than once in a single fixed time step.

Also, you really don’t ever need “== true”, that’s purely superfluous. E.g. “if(col.enabled == true)” is exactly the same as “if(col.enabled)”.

Ok thanks @Pyrian