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. * http://imgur.com/a/hoAIH * http://imgur.com/a/HbvrO 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\$
  • \$\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 '17 at 7:45
  • \$\begingroup\$ Please mention the unity version. \$\endgroup\$ – Shuvo Sarker Sep 1 '18 at 7:11
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\$
  • \$\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\$ – PatientZero Dec 14 '15 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 '17 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\$

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.