RaycastHit getScreenTarget (Vector3 pos) {
Ray ray = Camera.main.ScreenPointToRay (pos);
if (Physics.Raycast (ray, out RaycastHit hit))
return hit;
}
Can anyone help me fix the above function to work and with some explanation why it wouldnt work just like it is?
You need to declare the RaycastHit before you pass it to Physics.
RaycastHit getScreenTarget(Vector3 pos)
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(pos);
Physics.Raycast(ray, out hit);
return hit;
}
The “out” decorator means to pass by reference. RaycastHit is a struct, not a class and as a value type, you have to use either “out” or “ref” if you want the function to be able to fill out fields and then see those changes on the calling side.
The difference between “out” and “ref” is that when you use “out”, the function promises to completely initialize the thing passed in. While with “ref” its the caller that’s responsible for initialization. This is why you can use that hit variable as a function argument without having called new. If Physics.Raycast was “ref” instead of “out”, compiler would insist you do a new on it before passing it in.
I made some other changes to get it to compile. Since your function is declared to return a RaycastHit, you need to return one no matter what, even if there was no hit. This is kind of a problem because whoever is getting that hit is going to need to be able to figure out there was no hit based on the contents of a default-constructed RaycastHit.
You’d be better off matching the form of the Physics function.
bool getScreenTarget(Vector3 pos, out RaycastHit hit)
{
Ray ray = Camera.main.ScreenPointToRay(pos);
return Physics.Raycast(ray, out hit);
}
If you’re going to be using C# and you’re developing on a Windows platform, you should get Visual C# Express from Microsoft and use that as your editor. Its free. While you can’t debug running Unity C# scripts with Visual Studio (alas) its compiler will give you much better messages for syntax errors than the default Unity text editor will.
thanks for the tip, i think you are right about checking if there was a hit or not first.
one more question, is this how im going to use the function now?
RaycastHit hit;
main update here {
if (getScreenTarget (Input.mousePosition, out hit))
hit.point...etc;
}
bool getScreenTarget(Vector3 pos, out RaycastHit hit) {
Ray ray = Camera.main.ScreenPointToRay(pos);
return Physics.Raycast(ray, out hit);
}
}
Yes, that should work.
I will say that I don’t think its worth running another funcition over the stack just to make that ray. If it was me, I’d kill that helper function entirely and make the call to Physics directly from Update. But suit yourself.