OnMouseEnter Hoverable LinePoint Inefficiencies

I am creating multiple charts with multiple lines and about 70 points per line using Vectrosity (see attached image). My current solution for creating “hoverable” points (using OnMouseEnter and OnMouseExit to identify hovering) is to instantiate a prefab GameObject with a scale of about (.1, .1, .1) and a BoxCollider for each point. This certainly works, but I have a feeling it is extremely inefficient because for the four charts in the image I am instantiating 840 game objects, where a maximum of one of them is shown at each time.

Is there a more efficient way to look at this problem? Maybe saving the world position of each of these points in an array and then in the Update function check if the mouse is within x radius of the point and then create a hover box?

Any thoughts on this would be greatly appreciated because this inefficiency is only going to get worse as I scale to more lines and more charts.

Thanks!

Here is what I do. I think it should be more efficient than your current method, but I’m not 100% sure because I don’t use very many lines.

“Wire” is a class of mine, but that’s really not important. wire.points is just my VectorLine point array. (Continuous VectorLine) CheckWire loops through all points in a particular line, distance to wire calculates distance to the line segment made of points l1,l2. What I am looking for is the first line segment I can find that is less than 2px from my mouse cursor, but you could easily adjust this code to measure to individual points instead and return the nearest point.

public int CheckWire(Wire wire)
    {
        for (int i = 1; i < wire.points.Length; i++)
        {
            Vector2 l1 = Camera.mainCamera.WorldToScreenPoint(wire.points[i - 1]);
            Vector2 l2 = Camera.mainCamera.WorldToScreenPoint(wire.points[i]);
            Vector2 point = Input.mousePosition;

            float Distance = DistanceToWire(l1, l2, point);

            if (Distance < 2)
            {
                return i;
            }
        }
        return -1;
    }

    public float DistanceToWire(Vector2 l1, Vector2 l2, Vector2 p)
    {
        float lSquared = Mathf.Pow(Vector2.Distance(l1, l2), 2);
        float t = Vector2.Dot(p - l1, l2 - l1) / lSquared;
        Vector2 projection = l1 + t * (l2 - l1);

        if (lSquared == 0) { return Vector2.Distance(l1, p); }

        if (t < 0) { return Vector2.Distance(p, l1); }
        else if (t > 1) { return Vector2.Distance(p, l2); }

        return Vector2.Distance(p, projection);
    }

avidesk,

Thanks for the quick reply. Are these functions that you have in the Update() function of a script that you attach as a component to each wire/line that you create?

If I have a bunch of lines with 70 points each, I wonder if it would be more efficient to store the global position of each point in an array and then at each frame calculate the distance from the mouse cursor until a match is found.

Chris