GetComponent Question from 3D Platform Tutorial - Pickups

I stared at it, hoping it would hit me but it’s just not sinking in; in this function from the Pickup.js script in the 3DPlatformTutorial (page 45-46):

function OnTriggerEnter (col : Collider) 
{
	if (mover  mover.enabled) return;
	
	var playerStatus : ThirdPersonStatus = col.GetComponent(ThirdPersonStatus);
	
	//* Make sure we are running into a player
	//* prevent picking up the trigger twice, because destruction
	//  might be delayed until the animation has finished

	if (used || playerStatus == null)
		return;
	
	if (!ApplyPickup (playerStatus))
		return;

	used = true;

…what exactly am I assigning to this variable?

var playerStatus : ThirdPersonStatus = col.GetComponent(ThirdPersonStatus);

I have the ThirdPersonStatus.js script open, and I’m still not making the connection.

This leaves me equally confused about what is happening here:

function ApplyPickup (playerStatus : ThirdPersonStatus)

…which is located right above the OnTriggerEnter function in the same script.

Rest assured while I may be new to coding, I’m not new to ‘programming’, but my experience is more conceptual/theory. I come from a Virtools background so my actual coding knowledge needs to ‘robustification’, so please be gentle. :smile:

I AM understanding an awful lot, dare I say most of what I’ve read (which includes nearly everything from tuts, to videos, to forum posts, to the wiki, and every doc I could find) but there are instances like these that I’m bound to be tripped up by.

Otherwise so far so good and I’m very impressed with Unity (and enjoying the experience to boot, as I’m not only new to Unity, I’m new to Mac’s!)

Thanks guys!

var playerStatus : ThirdPersonStatus = col.GetComponent(ThirdPersonStatus);

ThirdPersonStatus is a script, which is a kind of component. In this case, GetComponent is being called on the collider to find the ThirdPersonStatus component that’s attached to the same GameObject as the collider that was passed to OnTriggerEnter. A reference to this component is put into the variable, and that allows the variable to be used as a means of accessing the functions and variables of that particular instance of the ThirdPersonStatus script:

playerStatus.AddHealth(amount);

That calls the AddHealth function on that specific ThirdPersonStatus component.

function ApplyPickup (playerStatus : ThirdPersonStatus)

This says that the ApplyPickup function takes one parameter, named playerStatus, whose type is ThirdPersonStatus. That means you can only pass references to ThirdPersonStatus components to the function, so it protects you from accidentally passing the wrong kind of data. Also, if the ‘: ThirdPersonStatus’ part were omitted, it would be necessary to work out what kind of object it is on the fly, and that can slow down your game.

First off thank you for the quick reply. :smile:

Okay so…

…the reason it couldn’t be:

var playerStatus : col.GetComponent(ThirdPersonStatus);

…is that col.GetComponent(…) is not a Type, correct? So you’re telling playerStatus that it is of the Type “ThirdPersonStatus” and in turn is the value returned by the GetComponent of the COLLIDER, in this case the ThirdPersonStatus script. See that much I got for the most part except what I thought was a redundancy.

…and the reason we’re using the collider to get the component is to derive the value from the object that touched the pickup(i.e. the Player)? In other words, “get the ThirdPersonStatus script from the object that just collided with you”. Is that the gist?

See this is the conundrum…I understand the significance of GetComponent(), hence why I had the ThirdPersonStatus.js open side by side with the Pickup.js, and nowhere is playerStatus calling functions from ThirdPersonStatus from within the OnTriggerEvent() function. This is exactly what is after line var playerStatus :

     if (used || playerStatus == null)
		return;
	
	if (!ApplyPickup (playerStatus))
		return;

	used = true;

This above is what prompted me to post this question. I know that the ApplyPickup function is calling functions, as per your example, from ThirdPersonStatus.js, but that’s a separate function from OnTriggerEvent(), or so I’m assuming.

So at that moment, prior to moving ahead in the code, what Type does playerStatus think it is? I’m assuming it doesn’t know that ThirdPersonStatus is a script yet correct? So is playerStatus a string?

As I said there is a great deal more that I understand than don’t, such as what GetComponent() does, but there are a few combinations (like the above) that throw me for a loop (see what I did there? har) :smile:

Again thanks a bunch Carter!

Yes, that’s correct. Again, you don’t have to say ‘: ThirdPersonStatus’ here, but because GetComponent returns a generic Component reference, it’s more efficient to tell the compiler exactly which type you expect to be returned as this will avoid the need to work it out at runtime (slowly).

Yes, precisely.

By specifying the type every time you use GetComponent and the type of each parameter in a function signature, you help the compiler to check that you never put the wrong kind of reference in a variable. Even if you do nothing but pass the variable to someone else, it’s still better to specify which type it is so that everything gets checked at compile time.

No, it’s a ThirdPersonStatus reference. The compiler knows this when it sees the type name following the colon in the script and works out which script it relates to immediately.

No problem! :slight_smile:

Oh thank goodness, you just boosted my confidence big time!

Now, I wasn’t going to ask but what the heck while we’re here:

if (!ApplyPickup(playerStatus);

Is this simply asking if ApplyPickup(playerStatus) not True? I see that at the end of the ApplyPickup function that we’re returning True to the function, so is that what the If statement here is looking for? If so, is the function False until we return True?

(First year programming questions for sure, so I’m greatly appreciative of your time and patience :slight_smile: )

Yes, pretty much. As it happens, ApplyPickup always returns true so the test is redundant as it stands. Presumably the author planned to have pickups which return false to skip the remainder of OnTriggerEnter.

I don’t know what happens if you try to have a function return true in some cases and nothing at all in others. It might not be allowed, in which case there wouldn’t be a sense in which returning nothing could be treated as ‘false’. I would check, but it’s probably best if I leave it as an exercise for the reader. :wink:

Perfect.

Just a note, not to you Neil but UT and whomever, but this exchange we just had would be terribly invaluable either in the tutorial or the script comments. I completely understand there’s an expectation that if you’re going to venture into these waters that you have SOME coding knowledge beforehand. Consider that:

A) With a line by line analysis (within reason), understanding for completely new programmers to Unity would be increased significantly.

B) Even if users come onboard with some knowledge, it’s entirely possible more advanced concepts are perhaps still out of reach.

I fall into the A) category, so it’s most likely that my ignorance is more the weakest link than necessitating more descriptive code explanations, but I’m thinking it couldn’t hurt, and would avoid new users from creating more threads like this.

Either way thank you so much Neil! :smile:

I do. :wink: It has a default value, so if you don’t specify, it returns the default; “False” for booleans. (Well, assuming the type of the function is specified…if not, it returns void by default.)

–Eric

You know I can’t find a good answer as to why or when you’d return void; from a quick google people seem to be at odds as to if you even should.

If any of my functions are supposed to return something, I always specify the return type anyway. I guess it might be useful if you somehow accidentally tried to get a value from function that’s not supposed to return anything (and therefore doesn’t have a return type specified), so you’d get an error message instead of a default value.

–Eric

A void return value literally means that no value will ever be returned. If a function’s return type is void, the compiler will emit an error if you try to assign its result to a variable - the bizarrely-worded BCE0022: Cannot convert ‘void’ to ‘void’.

I was curious about Eric’s assertion about return type behaviour so I did some tests. It looks like the Javascript compiler is smart enough to statically set the function’s return type to the most general type that can hold all of the types returned in the function. If you just use ‘return’ on its own or fall out of the end of the function, it uses the default value for whatever the determined return type ends up being. So, if you only return true or false, the return type will be boolean. If you return true in one place and 0 in another, the return type will be promoted to int instead of boolean, and true will be turned into 1. If you return, say, a string in one place and false in another, the return type gets promoted to System.Object (which can hold anything).

This kind of detail isn’t terribly important in practice because you either a) are comfortable with dynamic typing and are doing it deliberately or b) have no idea what you’re doing, in which case dynamic and implicit typing will generally do the right thing for you automatically.

I agree with Eric that the right thing to do is to explicitly specify the return type of every function:

function Something() : YourReturnType {...}

That way there can be no confusion and the compiler will force you to return the correct type in every case.