2
\$\begingroup\$

I'm having an odd issue in my implementation of distance based object interaction in Unity. Basically it's a simple "Press [key] to [search/pickup/open/etc]" function which requires the player to be within a certain distance of the object before interaction is allowed (via mouse over). In my scene I have 2 test objects which I have set up as similarly as possible, but they are acting differently and I cannot seem to work out why. * https://i.stack.imgur.com/Y8vKJ.jpg * https://i.stack.imgur.com/2DWGw.jpg These are the setups, and the script which is on both parent objects is as follows:

public class DisplayUI : MonoBehaviour
{
    public string itemName;
    bool isSelected;
    bool isNear;

    void OnTriggerEnter(Collider col)
    {
        isNear = true;
    }

    void OnTriggerExit(Collider col)
    {
        isNear = false;
    }

    void OnMouseOver()
    {
        if (isNear)
            isSelected = true;
        else
            isSelected = false;
    }

    void OnMouseExit()
    {
        isSelected = false;
    }

    void OnGUI()
    {
        if(isSelected == true)
        {
            GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 200, 20), "Press E to search " + itemName);
        }
    }
}

For some reason the sphere/cube game object is acting as desired where the mouseover detects the edge of each mesh perfectly, and relies on the distance (within the trigger collider) too, creating the gui label as coded. The trash can however seems to think the main trigger collider is the edge of the mesh so even when the mouse is way outside the physical mesh, the gui label is showing. Where am I going wrong with this?

\$\endgroup\$
2
  • \$\begingroup\$ Is the problem possibly because you're using a box collider on a cyllindrical object, whilst the colliders around both the sphere and the box are near perfect matches for the objects they are surrounding? \$\endgroup\$
    – Pharap
    Apr 25, 2017 at 7:45
  • \$\begingroup\$ Please mention the unity version. \$\endgroup\$ Sep 1, 2018 at 7:11

2 Answers 2

1
\$\begingroup\$

Your object Trash1 has two non-triggering colliders attached to it: A Box Collider and a Mesh Collider. The OnMouseOver and OnMouseExit events will take both of them into account. So the OnMouseOver event gets fired when the mouse is over the BoxCollider which surrounds the model.

Your Sphere1 also has two colliders, but in this case they are a Sphere Collider and a Mesh Collider which have almost the same shape, so the problem is not noticeable. But it's still a slight performance hook (not noticeable in such a simple scene but it could become problematic when you have a lot of these).

I don't know why you attached two colliders to your objects, but it seems to me like one for each of them would suffice. In general you should prefer the "Geometric Object" colliders over Mesh Colliders because they are far more performance-friendly (especially when the mesh colliders are directly derived from high-polygon models and not based on simplified versions). But in the case of the trash can you have no choice because there is no optimized "Cylinder Collider" in Unity.

\$\endgroup\$
2
  • \$\begingroup\$ Ok, so I removed all colliders from the Trash Can and its child object, just added the box collider as a trigger around the parent and tried every geometric object collider on the child (which is the object mesh) making sure the edges of the collider were as close to the edges of the mesh as possible. But the mouse over event still gets fired as soon as I step inside the trigger collider. I don't understand why this isn't the case with the sphere/cube model, it detects the mesh edge to pixel accuracy there based on the sphere and box colliders which are on the child objects. \$\endgroup\$ Dec 14, 2015 at 1:30
  • \$\begingroup\$ I'd do a raycast to the mouse coordinates with a certain maximum distance, if it hits something it is in range, if it doesn't hit then it's not. \$\endgroup\$
    – ElDuderino
    Sep 25, 2017 at 18:10
0
\$\begingroup\$

You could use a vector 3 to check if the object is near.

Example:

if (Vector3.Distance ( "Put your player here".transform.position, "Put object to check for here".position) < 5) 
{
    "Block of code here"
}
\$\endgroup\$

You must log in to answer this question.

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