Raycast or Linecast to existing Raycast hit.point, to check Line of Sight

Unfortunatly I have had very rough time simply attempting to determin if I have Line of Sight to a target from the player’s position, whilst the camera’s location determins input and sight of the level.

So what happens in the game is:
The player is out and about in the level, the camera is away and thus can see around objects, and the ‘user’ interacts by clicking via the camera view. As long as no objects are inbetween the player and its targets, everything is fine, however if I have objects where the player theoretically would not be able to see the targets, I need to respond to the ‘user’ with a visual que that they cannot shoot through that object.

Such visual que is they fire anyway and they see thier weapons fire stop at the wall.

here’s an example image:
alt text

I have tried using both Linecast and Raycast, to no avail.

LineCast:

When using linecast, I only get 1 response instead of a choice of a response. It is either always ‘colliding’ or it is never ‘colliding’.

Here’s an example snip of LINECAST:

function MousePoint() : Vector3{
	var ray : Ray = cameraMain.ScreenPointToRay(Input.mousePosition);// Cast a ray from the main camera to mouse coordinates, cached
	var hit : RaycastHit;

	var clearLOS : boolean = true;
	if (Physics.Raycast (ray, hit))
	{
		var hitLOS : RaycastHit;

		if (!Physics.Linecast (PlayerGO.transform.position, hit.point, hitLOS))
		{
			if (hitLOS.point == hit.point)
			{
				Debug.Log("TRUE We have LOS");
				Debug.Log("hitLOS.point is " + hitLOS.point + "hit.point is " + hit.point);
				clearLOS = true;
				hitLocation = hit.point; //Do FX spawns based at this location, as nothing was in our way
			}
			else
			{
				Debug.Log("FALSE We Dont Have LOS");
				Debug.Log("hitLOS.point is " + hitLOS.point + "hit.point is " + hit.point);
				clearLOS = false;
				hitLocation = hitLOS.point; //Do FX spawns based at this location, where the collision happened
			}
		}
		
		//DO some stuff if clearLOS == true;
		
		
	}

}

Unfortunatly, hitLOS.point never is equal to hit.point I find that odd even if there is nothing in its way.

Here is a result:
hitLOS.point is (34.5, 8.0, 96.6)hit.point is (35.9, 11.3, 106.8)

I understand that !Physics.Linecast is ‘supposed’ to imply that if the line doesnt reach its target, then true something is in its way. At least this is what the documentation says. Either way, I have tried with the ‘not’ and without. The only consistancy I get is that with the ‘not’ (!) it is always intersecting with something, but it is reporting FALSE, and never reports TRUE.


I have tried to simply create a new raycast from Player to Target, but unfortunatly Raycasting can only be done in a direction, and since the direction is normalized,
well it ends up being off more than is acceptable.

here is an example:

hitLOS.point is (31.1, 0.3, 66.9)hit.point is (30.6, -0.3, 57.8)

Where the *.point.z is off by 9 units, and that is unacceptable for my use. If it were only off by 1 unit, I *might be able to utilize it, but it frustrates me that I cannot get accurate numbers as I depend upon them to be able to create reliable results that a user can understand.


Unfortunatly I need the exact location of both Raycasthits, so I can spawn the appropiate effects, so using things like the collider’s transform or even the collider itself, is simply not accurate enough to do this.


Any help or slaps on the noggin are appreciated, thank you.

Well I’m not sure this is the best answer, but its now working to a point that I can at least expect to know what the results are.

function MousePoint() : Vector3{
	var ray : Ray = cameraMain.ScreenPointToRay(Input.mousePosition);// Cast a ray from the current camera to mouse coordinates
	var hit : RaycastHit;
	var clearLOS : boolean = true;
	if (Physics.Raycast (ray, hit))
	{
		var hitLOS : RaycastHit;
		hitLocation = hit.point;
		if (!Physics.Linecast (PlayerGO.transform.position, hit.point, hitLOS))
		{
			//Debug.Log("hitLOS Collider is " + hitLOS.collider + " hitcollider is " + hit.collider);
			Debug.Log("true We have LOS");
			//Debug.Log("hitLOS.point is " + hitLOS.point + "hit.point is " + hit.point);
			clearLOS = true;
			hitLocation = hit.point;
		}
		else 
		{
			if (hitLOS.collider == hit.collider)
			{
				//Debug.Log("true We Dont Have LOS But it is the same collider so could be the opposite side to camera");
				clearLOS = true;
				hitLocation = hit.point;
				//Debug.Log("This collider's tag is: " + hitLOS.collider.tag);
			}
			else if (hitLOS.collider != hit.collider)
			{
				//Debug.Log("true We Dont Have LOS & Different Collider assume no LOS");
				//Debug.Log("hitLOS.point is " + hitLOS.point + "hit.point is " + hit.point);
				clearLOS = false;
				hitLocation = hitLOS.point;
			}
		}
		
		//Do some stuff
		
	}
}

The only bummer is that if you have like a large complex structure with mesh collision or unique collision, this will ignore it and shoot through the walls to the wall you hit with your mouse. So missing a target inside such a structure can mislead users to think they are able to fire through walls.

To get around it I just made some invisible collision blocks to cover walls where needed. Kind of a tedious thing to have to do but I really want to move on.

Hope this helps other folks.