c sharp raycast bug?

Hi all!

What I am trying to do: I am currently working on a script attached to my main camera, registers clicks in the update and casts rays onto the terrain from the mouse position, grabs the hit info for the cast and then assigns an avatar to move to that position on the terrain. This script is in C#.

What my problem is: Based on documentation and thoroughly looking over the forums, this is not an uncommon script. The issue I have run into though, is doing it in C#, seems to get confused about which overloaded version of Raycast I am using and throws errors in the script. I have tried it every way it is documented, with and without default values, and it always seems to think I’m using the wrong function. For instance, one overload is this:

static function Raycast (ray : Ray, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : bool

and my code looked like this:

void Update ()
{
	if(Input.GetButtonDown("Fire1"))
	{
		Ray ray = Camera.main.ScreenPointToRay( Input.mousePosition );
		RaycastHit rc_hit = new RaycastHit();
			
		if( Physics.Raycast(ray, rc_hit) )
		{
			print("Hit something");
		}
	}
}

And I got the errors:
error CS1502: The best overloaded method match for `UnityEngine.Physics.Raycast(UnityEngine.Vector3, UnityEngine.Vector3)’ has some invalid arguments

error CS1503: Argument 1: Cannot convert type UnityEngine.Ray' to UnityEngine.Vector3’

These errors made sense if I was calling the version of Raycast like this:

static function Raycast (origin : Vector3, direction : Vector3, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : bool

So when I rearranged my code to call that one, it thought I was calling yet another version of the Raycast function. I am new to unity, but certainly not new to programming and was wondering what I am missing? I can’t seem to find a C# answer to using Raycast, but obviously it must be different than the JS versions. Stepping out on a limb I thought, well, C# might not return Bools from Raycast, perhaps it doesn’t like the RaycastHit object in the function, which seemed very likely. So just to test I tried to catch RaycastHit from the call rather than check it as Bool, but no, it does indeed return Bool, so how am I supposed to call this in C# and get my RaycastHit object as well? I was able to call Raycast and it worked, but I had to exclude any form of the call that used RaycastHit. I hope I have explained this well enough. Thank you in advance, sorry for long post.

If you examine the function signature from the docs carefully, you’ll see that it says ‘out’ before the RaycastHit parameter. In Javascript, this is implicit, but in C# you have to explicitly write ‘out’ before that parameter:

void Update() 
{ 
	if(Input.GetButtonDown("Fire1")) 
	{ 
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
		RaycastHit rc_hit; 

		if(Physics.Raycast(ray, out rc_hit)) 
		{ 
			// Hit something
		} 
	} 
}

Also, because Physics.Raycast will be filling out that variable for you, there’s no need to initialise it with new on the preceding line.

1 Like

Awesome, thanks!

The ‘out’ keyword is interesting, I assumed since everything in C# was a pointer, kind of like Java or even Flash AS3, that an out identifier wouldn’t be necessary. Anyways, I only used C# for a couple weeks sometime mid last year so I guess I am still unfamiliar with some of its catches :?

Not everything in C# is a pointer. Actually, every objects are passed by reference but not primitive types (like int, char, …).

Note, there is also the keyword ‘ref’ that allows you to pass a primitive type by reference.

But yeah, I guess the out keyword is not only useful in the case of primitive types but also to warn developers that this argument is not supposed to be initialized before, it’s just going to be updated once the function returns (which is not explicit otherwise, if you don’t have access to the core of a function).

Just to clarify things a bit :slight_smile: