I’m having trouble with understanding the code in a script that is shown below. The script is attached to a player game object and basically consists of a ray cast that detects ledges from the top right corner of the Bounding Box of the player game object.
private Vector2 topOfPlayer;
private Collider2D col;
private void Start()
{
col = GetComponent<Collider2D>();
}
topOfPlayer = new Vector2(col.bounds.max.x + .1f, col.bounds.max.y);
RaycastHit2D hit = Physics2D.Raycast(topOfPlayer, Vector2.right, .2f);
if (hit && hit.collider.gameObject.GetComponent<Ledge>())
{
//code to be executed
}
What I don’t understand is the condition that is in the if statement:
if (hit && hit.collider.gameObject.GetComponent<Ledge>())
It’s like the ray cast has to hit something but also something else has to be hit in order for the code within the if statement to execute?
I don’t know what hit.collider.gameObject.GetComponent means… is it like if the ray cast also hits a game object that has a component called “Ledge” or something along those lines?
But why do I have to specify those two things are the same time? Why can’t I just say:
if (hit.collider.gameObject.GetComponent<Ledge>())
Why do I have to specify whether the ray cast hit something first and THEN specify whether the thing it hit was a Ledge component? Why can’t I just say if the ray cast hit a Ledge component on its own?
RaycastHit2D just contains information about what was hit, such as the Collider2D it detected, the distance, the position in the scene it was hit at, etc.
The GetComponent part is simply checking if the GameObject that the ray cast hit has a Ledge component.
The if(hit) part caught my interest though. I didn’t realize there was an operator overload for it, since normally, a struct (like RaycastHit2D) cannot be null.
I’m assuming if(hit) is really just a shorthand for if(hit.collider != null)
Because if the raycast hit nothing, then there is no collider, and hit.collider.gameObject would throw a NullReferenceException because it doesn’t exist.
I know I’m going off on a tangent here but why is RaycastHit2D considered a “struct” and not a “type”? I thought that when you write " RaycastHit2D hit" you are creating a variable called “hit” of type “RaycastHit2D”.
So if I wrote:
if (hit.collider.gameObject.GetComponent<Ledge>()) as the condition in the if statement and if I started playing the game and the ray cast isn’t hitting anything yet then the console would continuously output a “NullReferenceException” until I actually hit a collider that has a component called Ledge? Is this correct?
Other than the error message appearing constantly in the console(even though I have to test this out myself when I have the time) what are the negatives of writing the if statement condition in this manner? Is it just bad practice and could drain memory or resources in some way?
A struct is a type. “Type” is just the most abstract name for anything.
Struct, class, interface, GameObject, int, string, Vector3, and everything else are all “types”.
A RaycastHit2D is a type of struct in the same way a GameObject is a type of class. The difference between a class and a struct is that classes are reference-types, whereas structs are value-types.
You can read more about what that means here:
Correct.
The Unity editor is somewhat of a special case in that it does not crash when an exception is thrown, but in a typical program (like a standalone build of your Unity game), if an exception is thrown and you do not have any logic to handle it, the program will crash.
In general, exceptions are, by design, intended to let you know when something is wrong with your program, and they should be treated as such. You do not want exceptions to be thrown during runtime.
Vryken already answered it, but to reiterate, you need zero errors in your application. Warnings are ok (i think), but errors will introduce weird behavior, that is if your lucky enough not to have a full blown crash.
Okay I understand what value types are in that they are variables that directly contain a value. Or in other words it stores a value inside its own memory space. So something like:
int = 100;
However in the link that you provided a reference type is described as follows:
So that means that a reference type stores the location of where the value is. But doesn’t the location of where the value is need to be a value type itself? Am I right in saying that a value needs to be stored in a variable of some kind? So in other words a reference types stores the location of where a value is AND that value is itself contained within a value type(such as int,float,bool)?
So a simple example would be a class(reference type) and an integer(value type) that has a variable of 5? A class stores the location of where the “5” is and the “5” is contained within a value type(int)? Is this correct?
Pretty much. References merely point to where values are in memory.
Imagine this:
You declare 10 different integer variables and give them all the same value. Each integer is its own value, so changing the value of any one integer does not affect the value of any other.
On the other hand, you declare 10 different GameObject variables and have them all reference the same GameObject instance in the scene. If you change anything about that GameObject instance, all the variables will reflect that change, because they’re all pointing to the same GameObject.
So I declared 10 different GameObject variables in a script like so:
public GameObject _go1;
public GameObject _go2;
public GameObject _go3;
public GameObject _go4;
public GameObject _go5;
public GameObject _go6;
public GameObject _go7;
public GameObject _go8;
public GameObject _go9;
public GameObject _go10;
How would I go about having them all reference the same GameObject instance in a scene?
You mentioned in a previous post that RaycastHit2D is a struct within the Unity API. I’m just wondering why is a Rigidbody2D considered a class within the API yet RaycastHit2D is a struct? Is it because Rigidbody2D is inheriting something whereas RaycastHit2D is not? I don’t understand.