Detect when no longer hittting an object with raycast

Im trying to make a sort of gui system where i only display an enemies stats (hp etc.) when im targetting them with the crosshair. To target them i use a raycast and i have it display the info when i hit them with it. But i need a way to tell the script that im no longer hitting the enemy with that raycast so it can disable the gui. Can anyone help?

Current code:

function LookRay()
{
	var direction = transform.TransformDirection(Vector3.forward);
	var ray = Camera.main.ScreenPointToRay(Vector3(Screen.width/2, Screen.height/2,0));
	var hit : RaycastHit;
	
	if(Physics.Raycast(ray, hit, range))
	{
		Debug.DrawLine(ray.origin, hit.point, Color.red);
		if(hit.rigidbody)
		{
			hit.transform.SendMessage("EnableGUI", SendMessageOptions.DontRequireReceiver);
		}
		
	}
	
}
1 Like
#pragma strict

var hittingTarget : boolean;

function Update () {

	if(!hit.rigidbody){
		hittingTarget = false;
	}
}

Just put a ! in front of something if you want to check if something is not true, or if it’s not hitting something… keyword “not”.

Note: Untested.

var objectPreviouslyHit;

function LookRay()
{
    // cast a ray into our scene from where our crosshair is looking to see if we are currently hitting
    // anything at all
    var direction = transform.TransformDirection(Vector3.forward);
    var ray = Camera.main.ScreenPointToRay(Vector3(Screen.width/2, Screen.height/2,0));
    var hit : RaycastHit;
    
    // when the ray hits nothing it means our crosshair isn't over anything of importance
    // we want to early out and perform no further tests, but we need to ensure we inform
    // the previously selected object, if there is one, to turn off the GUI.
    if(Physics.Raycast(ray, hit, range)==false)
    {
        if (objectPreviouslyHit != null)
        {
            objectPreviouslyHit.transform.SendMessage("DisableGUI", SendMessageOptions.DontRequireReceiver);
            objectPreviouslyHit = null;
        }

        return;
    }

    // when the ray hits something of interest, confirm that it is a new object, and if 
    // it is, tell the previously selected object, if one was selected, to turn off the GUI.
    if ((objectPreviouslyHit != hit)  (objectPreviouslyHit != null))
    {
        objectPreviouslyHit.transform.SendMessage("DisableGUI", SendMessageOptions.DontRequireReceiver);
        objectPreviouslyHit = null;
    }
    
    // display a debug line to let the user understand what is going on with the ray cast
    Debug.DrawLine(ray.origin, hit.point, Color.red);
    // our ray may have hit something, but that "something" might not have a rigid body attached
    // so test for that, and if no rigid body is found, early out because we don't need to do
    // anything else
    if(hit.rigidbody == null)
    {
        return;
    }

    // our ray hit an object of interest, let that object of interest know that
    // the GUI should be enabled.
    hit.transform.SendMessage("EnableGUI", SendMessageOptions.DontRequireReceiver);

    // store the object our ray hit for future use so that when we come back through
    // we can check to see if we are hovering over the same object and thus don't
    // accidentally re-enable the GUI again.
    // we also store the object to detect switching between two objects or deselecting 
    // the current object.
    objectPreviouslyHit = hit;
}

Hey thanks man it worked. Only difference is objectPreviouslyHit must be a rigidbody and set to hit.rigidbody otherwise works like a charm.

Here is the code for anyone else who wants to use it.

function LookRay()
{
	var direction = transform.TransformDirection(Vector3.forward);
	var ray = Camera.main.ScreenPointToRay(Vector3(Screen.width/2, Screen.height/2,0));
	var hit : RaycastHit;
	
	
	
	if(Physics.Raycast(ray, hit, range) == false)
	{
		if(objectPreviouslyHit != null)
		{
			objectPreviouslyHit.transform.SendMessage("DisableGUI", SendMessageOptions.DontRequireReceiver);
			objectPreviouslyHit = null;
		}
		
		return;
	}
	
	if((objectPreviouslyHit != hit)  (objectPreviouslyHit != null))
	{
		objectPreviouslyHit.transform.SendMessage("DisableGUI", SendMessageOptions.DontRequireReceiver);
		objectPreviouslyHit = null;
	}
	
	Debug.DrawLine(ray.origin, hit.point, Color.red);
	
	if(hit.rigidbody == null)
		return;
		
	hit.transform.SendMessage("EnableGUI", SendMessageOptions.DontRequireReceiver);
	
	objectPreviouslyHit = hit.rigidbody;
	
}

EnemyHealth Enable/Disable Functions

function OnGUI()
{
	if(flag)
	{
		GUI.Box(Rect(200, 200, 100, 50), "Enemy HP: " + hp.ToString());
	}
	if(!flag)
	{
		GUI.enabled = false;
	}
	
}

function EnableGUI()
{
	flag = true;
}

function DisableGUI()
{
	flag = false;
}

Glad it worked for you and thank you for posting back the modified script for others to make use of.

An alternative that worked for me (might help out) is as follows. Slightly different example but hopefully makes sense:

if (Physics.Raycast(ray, out raycastHit, 10.0f))
        {
            // Select Menu Item look at
            if (raycastHit.collider.tag == "MenuItem") { //in the editor, tag anything you want to interact with and use it here
                raycastHit.collider.gameObject.GetComponent<MenuItemManager> ().SetToSelectedState (true);
                lastHitMenuItem = raycastHit.collider.gameObject;
            } else {
               // Deselect the menu item no longer looked at
                lastHitMenuItem.gameObject.GetComponent<MenuItemManager> ().SetToSelectedState (false);
            }

        }