0
\$\begingroup\$

So I was making an android game in unity3d. I wrote a script to draw straight lines with touch what I do is I first create a gameobject named temp and add line renderer to it and give the line renderer properties. Then I create a collider gameobject , parent it to the line and change its dimensions to the dimension of the line. What I am trying to do is add two colliders one while the line is being moved i.e "touch.phase == TouchPhase.Moved" and delete this collider and add another collider when "touch.phase == TouchPhase.Ended". For some weird reasons I am not able to delete the first collider.

Here is my code

void Update()
{

    foreach (Touch touch in Input.touches)
    {

        if (touch.phase == TouchPhase.Began)
        {
            temp = new GameObject();
            temp.AddComponent<LineRenderer>();
            temp.layer = LayerMask.NameToLayer("lines");


            lr = temp.GetComponent<LineRenderer>();
            lr.positionCount = 2;
            lr.SetWidth(0.2f, 0.2f);
            lr.material = new Material(Shader.Find("Sprites/Default"));
            lr.SetColors(Color.black, Color.black);

            temp.transform.position = camera.ScreenToWorldPoint(touch.position) + camOffset;
            fingerUp = camera.ScreenToWorldPoint(touch.position)+camOffset;

            lr.useWorldSpace = true;
            spawnCollider = false;



        }

        //Detects Swipe while finger is still moving
        if (touch.phase == TouchPhase.Moved)
        {
            lr.SetPosition(0, fingerUp);
            fingerDown = camera.ScreenToWorldPoint(touch.position)+camOffset;
              lr.SetPosition(1,fingerDown);
            spawnCollider = true;

            lastLine = temp;

            // The first collider temporary one

            BoxCollider2D col1 = new GameObject().AddComponent<BoxCollider2D>();
            col1.transform.parent = temp.transform;
            float lineLength = Vector2.Distance(fingerUp, fingerDown);
            col1.size = new Vector2(lineLength, 0.2f);
            Vector2 midPoint = (fingerUp + fingerDown) / 2;
            col1.transform.position = midPoint;
            float angle = (Mathf.Abs(fingerDown.y - fingerUp.y) / Mathf.Abs(fingerDown.x - fingerUp.x));
            if ((fingerUp.y < fingerDown.y && fingerUp.x > fingerDown.x) || (fingerDown.y < fingerUp.y && fingerDown.x > fingerUp.x))
            {
                angle *= -1;
            }
            angle = Mathf.Rad2Deg * Mathf.Atan(angle);
            col1.transform.Rotate(0, 0, angle);

        }

        if (touch.phase == TouchPhase.Ended)
        {
            if (spawnCollider == true)
            {  
                Destroy(col1);  // Deleting the first collider

                // Adding the final collider 
                BoxCollider2D col = new GameObject("Collider").AddComponent<BoxCollider2D>();
                col.transform.parent = temp.transform;
                float lineLength = Vector2.Distance(fingerUp, fingerDown);
                col.size = new Vector2(lineLength, 0.2f);
                Vector2 midPoint = (fingerUp + fingerDown) / 2;
                col.transform.position = midPoint;
                float angle = (Mathf.Abs(fingerDown.y - fingerUp.y) / Mathf.Abs(fingerDown.x - fingerUp.x));
                if ((fingerUp.y < fingerDown.y && fingerUp.x > fingerDown.x) || (fingerDown.y < fingerUp.y && fingerDown.x > fingerUp.x))
                {
                    angle *= -1;
                }
                angle = Mathf.Rad2Deg * Mathf.Atan(angle);
                col.transform.Rotate(0, 0, angle);
            }
        }




    }


}

I have added comments where I am doing what.

\$\endgroup\$
2
\$\begingroup\$

I assume that col1 is also declared elsewhere in the code, otherwise I don't understand how this would've compiled.

Notice this line:

BoxCollider2D col1 = new GameObject().AddComponent<BoxCollider2D>();

You're re-declaring col1 within a limited scope, and so you're not setting the external col1, which is used when the touch phases ends. Use

col1 = new GameObject().AddComponent<BoxCollider2D>();

Instead, and it should work, although you will get a new collider on every move, which sounds excessive.

On a side note, try to avoid calls to AddComponent/GetComponent in the Update() method - it will incur a significant performance hit. These should be cached in a local field once, instead of queried repeatedly. Also, avoid creating temporary game objects.

I'm not near a work machine, so I haven't tested this code, and it'll probably need some adjustment for it to compile, but I think it shows the gist of my suggestion.

GameObject temp;
private LineRenderer lr;
private BoxCollider2D move_collider;
private BoxCollider2D final_collider;

void Start() {
    temp = new GameObject();
    lr = AddComponent<LineRenderer>();
    lr.positionCount = 2;
    lr.SetWidth(0.2f, 0.2f);
    lr.material = new Material(Shader.Find("Sprites/Default"));
    lr.SetColors(Color.black, Color.black);
    temp.layer = LayerMask.NameToLayer("lines");
    lr.useWorldSpace = true;
    move_collider = temp.AddComponent<BoxCollider2D>();

}

void Update()
{
    foreach (Touch touch in Input.touches)
    {

        if (touch.phase == TouchPhase.Began)
        {
            temp.transform.position = camera.ScreenToWorldPoint(touch.position) + camOffset;
            fingerUp = camera.ScreenToWorldPoint(touch.position)+camOffset;
            move_collider.enabled = true;
            final_collider.enabled = false;
        }

        //Detects Swipe while finger is still moving
        if (touch.phase == TouchPhase.Moved)
        {
            lr.SetPosition(0, fingerUp);
            fingerDown = camera.ScreenToWorldPoint(touch.position)+camOffset;
              lr.SetPosition(1,fingerDown);

            lastLine = temp;

            float lineLength = Vector2.Distance(fingerUp, fingerDown);

            move_collider.size = new Vector2(lineLength, 0.2f);
            Vector2 midPoint = (fingerUp + fingerDown) / 2;
            move_collider.transform.position = midPoint;
            float angle = (Mathf.Abs(fingerDown.y - fingerUp.y) / Mathf.Abs(fingerDown.x - fingerUp.x));
            if ((fingerUp.y < fingerDown.y && fingerUp.x > fingerDown.x) || (fingerDown.y < fingerUp.y && fingerDown.x > fingerUp.x))
            {
                angle *= -1;
            }
            angle = Mathf.Rad2Deg * Mathf.Atan(angle);
            move_collider.transform.Rotate(0, 0, angle);
        }

        if (touch.phase == TouchPhase.Ended)
        {
            if (spawnCollider == true)
            {  
                move_collider.enabled = false;
                final_collider.enabled = true;

                // Adding the final collider 
                final_collider.transform.parent = temp.transform;
                float lineLength = Vector2.Distance(fingerUp, fingerDown);
                final_collider.size = new Vector2(lineLength, 0.2f);
                Vector2 midPoint = (fingerUp + fingerDown) / 2;
                final_collider.transform.position = midPoint;
                float angle = (Mathf.Abs(fingerDown.y - fingerUp.y) / Mathf.Abs(fingerDown.x - fingerUp.x));
                if ((fingerUp.y < fingerDown.y && fingerUp.x > fingerDown.x) || (fingerDown.y < fingerUp.y && fingerDown.x > fingerUp.x))
                {
                    angle *= -1;
                }
                angle = Mathf.Rad2Deg * Mathf.Atan(angle);
                final_collider.transform.Rotate(0, 0, angle);
            }
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ Yes I have declared public BoxCollider2D col1. I tried your fix but the box collider is still not getting deleted. \$\endgroup\$ – Wasim Ahmad May 28 at 8:05
  • \$\begingroup\$ Are you certain that you don't initialize several colliders? Can the move event happen several times before it ends? \$\endgroup\$ – nihohit May 28 at 8:54
  • \$\begingroup\$ Also, why are you creating a new game object every time that you create a collider? that seems wrong, especially since you don't add these new objects into the hierarchy. \$\endgroup\$ – nihohit May 28 at 8:55
  • \$\begingroup\$ I think the best solution is to refactor your code so that you don't create so many new objects during an Update. Create all the relevant objects ONCE beforehand, and during update just enable and disable them. \$\endgroup\$ – nihohit May 28 at 8:57
  • 1
    \$\begingroup\$ I too think that the code here can be optimised. For example, I see that he is doing temp.AddComponent and then two lines later, doing a GetComponent on the same type of Component \$\endgroup\$ – Shraa1 May 28 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.