!(not)Linecast not working _but Linecast works

My question relates to using !Physics.Linecast compared to Physics.Linecast.

I just tried using Linecast for the first time. In the Unity Scripting reference, the example is given :

var target : Transform;    
function Update() {
	if (!Physics.Linecast (transform.position, target.position)) {
		ProcessData.AndDoSomeCalculations();
	}
}

So I applied this with (on false statement):

var playerObject : GameObject;    
function Start() {
	playerObject = GameObject.FindWithTag ("Player");
	Debug.Log("Player Position " + playerObject.transform.position);
}

function Update() {
	Debug.DrawLine (transform.position, playerObject.transform.position, Color.red);
	//if (!Physics.Linecast (transform.position, playerObject.transform.position)) 
	if (!Physics.Linecast (transform.position, playerObject.transform.position, rayHit)) 
	{
		Debug.Log("Player is Sighted : rayHit " + rayHit.collider.tag);
	}
}

However , it is not printing anything at all , whether Player is in line-of-sight or not. Whereas this works (on true statement):

var playerObject : GameObject;    
function Start() {
	playerObject = GameObject.FindWithTag ("Player");
}

function Update() {
	Debug.DrawLine (transform.position, playerObject.transform.position, Color.red);
	if (Physics.Linecast (transform.position, playerObject.transform.position, rayHit)) 
	{
		if (rayHit.collider.tag == "Player")
		{
			Debug.Log("Player is Sighted : rayHit " + rayHit.collider.tag);
		}
	}
}

I have a working solution , but I cannot understand why my first script (mirrored from the Unity Script Reference) is not working.

This is a minor question , so please just leave a comment , so I can remove this question when I understand what I am missing here.

Many thanks.

  • Edited [1] to include var setup and relevant Start info.
  • Edited [2] to clarify where the code is in my script.

Actually, the reason is quite simple. Looking at your code :

if (!Physics.Linecast (transform.position, playerObject.transform.position, rayHit)) 
{
    Debug.Log("Player is Sighted : rayHit " + rayHit.collider.tag);
}

If Physics.Linecast returns false, this means that nothing was hit. Therefore, rayHit is not populated. So rayHit.collider.tag will trigger a NullReferenceException. Thus no log.

See http://unity3d.com/support/documentation/ScriptReference/RaycastHit-collider.html


Edit:

Does your object have a collider? If true, then there is always at least a collider : your object’s collider itself.

You can use the optional layerMask to prevent your collider from being considered, assuming your are probing on objects in different layers. If not, try to send the linecast from a position that is outside your own collider.

I know this is an older thread, but you should understand that the Scripting Reference given by Unity assumes that you want to do something if the linecast is not colliding with an object. If your intentions are to collect information about an object that your linecast “hits,” then take out the not statement (!).

Just to be clear, linecast returns true if an object intersects the line between the origin and target. information about that object is stored in a Raycasthit variable (rayHit in the case of the OP). Remember, the contents of an if statement is only executed if the condition evaluates to true. If the linecast returns true (an object is hit) then !true becomes false and the contents of the if statement are not executed.