1
\$\begingroup\$

I'm trying to to detect when two 3D objects overlap each other 'visually' without actually touching. For example, if I have two spheres in a scene that are 1 meter apart and I rotate my camera around the objects so that one sphere is blocked by the sphere in front of it, I want to detect when this occurs.

After many searches in this forum, I patched together the solution below. However, it only partially works: it only detects overlap when the center of the occluded object is reached (i.e., "bounds.center"). I read that there is a way to use the bounds in this scenario so that it samples multiple rays from around the object. This way, overlap is detected at the objects visual boundary and not just it's center. Unfortunately, my coding abilities are meager and I can't figure out how to do it.

Any help would be greatly appreciated.

using UnityEngine;
using System.Collections;

public class OverlapCheck : MonoBehaviour {

     public Transform myCamera;
     private Color mouseOverColor = Color.green;
     private Color originalColor; 
     private Vector3 objectExtents;


     // Use this for initialization
     void Start () {
         originalColor = gameObject.GetComponent<Renderer> ().material.color;
         objectExtents = gameObject.GetComponent<Collider>().bounds.center;
     }

     // Update is called once per frame
     void Update () {
         if (Physics.Linecast (objectExtents, myCamera.position)) {
             gameObject.GetComponent<Renderer> ().material.color = Color.yellow;
         } else {
             gameObject.GetComponent<Renderer> ().material.color = originalColor;
         }
     }
 }
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

you should Line Cast near object to Camera.if you want know when object is behind me , you can use Vector3.Dot

https://docs.unity3d.com/ScriptReference/Vector3.Dot.html

Dot Product of two vectors. The dot product is a float value equal to the magnitudes of the two vectors multiplied together and then multiplied by the cosine of the angle between them. For normalized vectors Dot returns 1 if they point in exactly the same direction, -1 if they point in completely opposite directions and zero if the vectors are perpendicular.

using UnityEngine;
using System.Collections;

public class CheckInDirection : MonoBehaviour {
    private Color originalColor; 
    public GameObject  otherObject;
    public GameObject CurrenCheck;


    // Use this for initialization
    void Start () {
        originalColor = gameObject.GetComponent<Renderer> ().material.color;
    }

    // Update is called once per frame
    void Update ()
    {
        if (otherObject) {
            Vector3 forward = transform.TransformDirection (Vector3.forward);
            Vector3 toOther = otherObject.transform.position - transform.position;

            if (Vector3.Dot (forward, toOther) < 0) {
                print ("The other transform is behind me!");
                CurrenCheck = gameObject;
            } else {
                CurrenCheck = otherObject;
            }
            Debug.DrawLine (CurrenCheck.transform.position, Camera.main.transform.position, Color.white);
            if (Physics.Linecast (CurrenCheck.transform.position, Camera.main.transform.position)) {
                CurrenCheck.GetComponent<Renderer> ().material.color = Color.yellow;
            } else {
                CurrenCheck.GetComponent<Renderer> ().material.color = originalColor;
            }
        }
    }
}

another solution that don't need LineCast is calculating degree between camera and behind object.

enter image description here

using UnityEngine;
using System.Collections;

public class CheckDirection : MonoBehaviour {
    public Transform otherObj;
    public float angle1,angle2;
    public int Different;

    void Update ()
    {
        Debug.DrawLine (transform.position, Camera.main.transform.position,Color.white);
        Debug.DrawLine (transform.position, otherObj.position,Color.white);
        Vector3 targetDir1 = otherObj.position - transform.position;
        Vector3 targetDir2 = Camera.main.transform.position - transform.position;
         angle1 = Vector3.Angle( targetDir1, transform.forward );
         angle2 = Vector3.Angle( targetDir2, transform.forward );
        Different = (int)Mathf.Abs(Mathf.Round (angle2) - (int)Mathf.Abs(Mathf.Round (angle1) - 180));

        if(Different < 3)//Measurement accuracy
            print( "equal" );
    }
}
\$\endgroup\$

You must log in to answer this question.

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