0
\$\begingroup\$

I want to make a collider for a line that I've drawn on the screen using mouse. so the detection should be cover the whole line that has drawn.

What I've learned from edge collider is you can have collider if you assign the position of a certain point in col.transform.position (for example I can assign the startpos of my line and the collider works only for that point).

the green line which is drawn by mouse in front of car is using the LineRenderer and requires EdgeCollider to be a road that car can drive on it's surface

enter image description here

and my functions:

private LineRenderer line; // Reference to LineRenderer
private Vector3 mousePos;
private Vector3 startPos;   // Start position of line
private Vector3 endPos; // End position of line
public Material material;


void Update()
{
    // On mouse down new line will be created 
    if (Input.GetMouseButtonDown(0))
    {
        if (line == null)
        { 
            createLine();
            mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            line.SetPosition(0, mousePos);
            startPos = mousePos;
        }
    }
    else if (Input.GetMouseButtonUp(0))
    {
        if (line)
        {
            mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            line.SetPosition(1, mousePos);
            endPos = mousePos;
            addColliderToLine();
            line = null;
        }
    }
    else if (Input.GetMouseButton(0))
    {
        if (line)
        {
            mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            line.SetPosition(1, mousePos);
        }
    }
}
// Following method creates line runtime using Line Renderer component
private void createLine()
{
    line = new GameObject("Line").AddComponent<LineRenderer>();
    line.material = material;
    line.SetVertexCount(2);
    line.SetWidth(1.1f, 1.1f);
    line.SetColors(Color.black, Color.black);
    line.useWorldSpace = true;
}
// Following method adds collider to created line
private void addColliderToLine()
{
    EdgeCollider2D col = new GameObject("Collider").AddComponent<EdgeCollider2D>();
    col.transform.parent = line.transform; // Collider is added as child object of line


    col.points[0] = startPos; 
    col.points[1] = endPos;

    Vector3 midPoint = (startPos + endPos) / 2;
    col.transform.position = midPoint; // setting position of collider object
    // Following lines calculate the angle between startPos and endPos
    float angle = (Mathf.Abs(startPos.y - endPos.y) / Mathf.Abs(startPos.x - endPos.x));
    if ((startPos.y < endPos.y && startPos.x > endPos.x) || (endPos.y < startPos.y && endPos.x > startPos.x))
    {
        angle *= -1;
    }
    angle = Mathf.Rad2Deg * Mathf.Atan(angle);
    col.transform.Rotate(0, 0, angle);
}

btw i don't know what that col.points[] used for. I just found it from the unity documentation which won't make any collision

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

The problem with the collision was that the edge collider points were not being set properly. Instead of setting individual points you actually need to supply Vector2 array of two elements. This is always the case in C# , in javascript it works fine. As the start and end points were not set , the collider was taking default 0.5 co ordinates.

You can see in the attached image that the collider is not covering the whole line. enter image description here

So following are the changes done to the original code.

private LineRenderer line; // Reference to LineRenderer
private Vector3 mousePos;
private Vector3 startPos;   // Start position of line
private Vector3 endPos; // End position of line
public Material material;


void Update()
{
    // On mouse down new line will be created 
    if (Input.GetMouseButtonDown(0))
    {
        if (line == null)
        { 
            createLine();
            mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            Debug.Log("mouse pos "+mousePos);
            line.SetPosition(0, mousePos);
            startPos = mousePos;
        }
    }
    else if (Input.GetMouseButtonUp(0))
    {
        if (line)
        {
            mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            Debug.Log("mouse pos "+mousePos);

            line.SetPosition(1, mousePos);

            endPos = mousePos;
            addColliderToLine();
            line = null;
        }
    }
    else if (Input.GetMouseButton(0))
    {
        if (line)
        {
            mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            Debug.Log("mouse pos "+mousePos);
            line.SetPosition(1, mousePos);
        }
    }
}

// Following method creates line runtime using Line Renderer component

private void createLine()
{
    line = new GameObject("Line").AddComponent<LineRenderer>();
    line.material = material;
    line.SetVertexCount(2);
    line.SetWidth(1.1f, 1.1f);
    line.SetColors(Color.black, Color.black);
    line.useWorldSpace = true;
}

// Following method adds collider to created line

private void addColliderToLine()
{
    EdgeCollider2D col = new GameObject("Collider").AddComponent<EdgeCollider2D>();

// Collider is added as child object of line
    col.transform.parent = line.transform;

    Vector2[] pointsArray = new Vector2[]{new Vector2(startPos.x,startPos.y),new Vector2(endPos.x,endPos.y)};

    col.points = pointsArray; 

    Debug.LogWarning("mos pos "+col.points[0]+" end pos "+col.points[0] );

}

This rectifies the collider points and you can see that now it covers the whole line :)

enter image description here

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .