4
\$\begingroup\$

I am currently building a game where I need to generate some wires (as Bézier curves) using LineRenderer. After changing the width of each line

lineRenderer.SetWidth (0.15f, 0.15f);

I am attaching an EdgeCollider2D to the same game object (specifying the same points used in generating the Bézier curve). This seems to work. However, I would like to be able to know if the Mouse Pointer is at any time over the EdgeCollider2D (something similar to the popular Fruit Ninja game). I'm using Raycast as follows:

void CastRay() {
    Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    RaycastHit2D hit = Physics2D.Raycast (ray.origin, ray.direction, Mathf.Infinity);

    if (hit) {
        Debug.Log (hit.collider.gameObject.name);
    }
}

I'm calling the CastRay method inside the Update method. Because EdgeCollider2D does not have width (as expected), the log message is never produced.

Do I need to use a different type of Collider? Do I need to call CastRay somewhere else?

\$\endgroup\$
4
\$\begingroup\$

Ok. After some experiments I ended up replacing the EdgeCollider2D with a PolygonCollider2D. I generated the collider points (taking the width of the wire into account) by computing the Euclidean distance between two consecutive points on the curve (you need to iterate through all the points) and the perpendicular on the distance vector (using the cross product).

Here's an example:

List<Vector2> edgePoints = new List<Vector2> ();
PolygonCollider2D collider = new PolygonCollider2D ();

for (int j = 0; j < bezierPoints.Count; j++) {
    Vector2 distanceBetweenPoints = bezierPoints[j-1] - bezierPoints[j];
    Vector3 crossProduct = Vector3.Cross (distanceBetweenPoints, Vector3.forward);

    Vector2 up = (wireWidth / 2) * new Vector2(crossProduct.normalized.x, crossProduct.normalized.y) + bezierPoints [j-1];
    Vector2 down = -(wireWidth / 2) * new Vector2(crossProduct.normalized.x, crossProduct.normalized.y) + bezierPoints [j-1];

    edgePoints.Insert(0, down);
    edgePoints.Add(up);

    if (j == bezierPoints.Count - 1) {
        // Compute the values for the last point on the Bezier curve
        up = (wireWidth / 2) * new Vector2(crossProduct.normalized.x, crossProduct.normalized.y) + bezierPoints [j];
        down = -(wireWidth / 2) * new Vector2(crossProduct.normalized.x, crossProduct.normalized.y) + bezierPoints [j];

        edgePoints.Insert(0, down);
        edgePoints.Add(up);
    }
}

collider.points = edgePoints.ToArray();

This will generate a Polygon collider that will wrap the entire wire (curve) based on the wireWdth.

PolygonCollider2D on top of Line Renderer

I wanted to post the solution in case someone else is having similar issues.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Horia Jurcut can you explain that what is bezier points here? \$\endgroup\$ – junaid May 4 '18 at 4:31

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.