Not sure what type of object it gives you if you give it a component reference instead of a GameObject, although I vaguely recall reading a long time ago that if you gave it, say, a Rigidbody, it would instantiate the whole hierarchy and still give you a reference to the new Rigidbody on it. If that’s the case, in theory, your code should work.
You should also check that you remembered to drag something into your ‘projectile’ slot in the inspector.
It will indeed give you the reference to the component you’re casting to - similar to dropping a game object in editor on a property which has a component type.
This is an example of me using Instantiate - unmodified copy directly from project:
UnitController unit = Instantiate( unitType, pos, transform.rotation ) as UnitController;
will give you a NullReferenceException if something is null.
= (ClassName) something
will give null, if something is null. Which is nice, because then your can do you own checks for null. However, you could of course also catch the NRE (NullReferenceException) when it occurs with “as”…
Interestingly (I think at least in Java), coding with exception handling can be more efficient than with a lot of if-checks. In particular, if it really is an exception (i.e. it usually does not happen). A while back I even read an article that proposed using conversion of if () {} to try {} catch {} in a smart manner might be a way to optimize code…
Do try…catch blocks hurt runtime performance? … says it does not hurt. When the exception is not thrown, it takes exactly zero time because the try/catch is not something that’s executed but handled via protected regions (just learnt that myself ). Finally does cost, and - if an exception occurs, the “longer you wait with catching it”, the longer it takes (which is kind of logical, isn’t it?), i.e. when you surround code that might throw an exception directly with the try-catch it’s more efficient (in the case on an exception), than having some “generic-catch” somewhere “deep down the stacktrace”…
On the other hand, Performance Implications of try/catch/finally … says it does cost performance. However, the reason is that the optimizer is a little more cautious. The example given in that article doesn’t make too much sense to me, because it basically says “well, if you write a lot of unused code, the optimizer can’t optimize it away when you have try-catch”…
Well… um… sorry, I guess I’m drifting off-topic
Anyways: That was about .NET… I have no idea how this is handled in Mono or Unity
It seems we’re talking about two slightly different things:
To swipe an example from “Accelerated C# 2008”:
class BaseType {}
class DerivedType : BaseType {}
...
BaseType baseObj = new BaseObj();
DerivedType x = baseObj as DerivedType; // 'x' will equal null
DerivedType y = (DerivedType)baseObj; // will throw an exception
My comments where about the differences between the last two lines of the above example. Not what happens if ‘baseObj’ somehow equals null.
I always end up dithering back and forth between using () and ‘as’ to cast things for certain Unity functions.
Logically, ‘as’ is better if you’re dealing with an object of an unknown type and you want to be able to easily ignore it if it turns out to be of the wrong type. As has been mentioned above, the () cast will throw exceptions if you’re wrong about the type, and that’s preferable if you want a very obvious warning that something has failed, or if you want to catch the exception in a broader scope.
The question is, which type of cast is more appropriate with Instantiate, GetComponent and the like? Those functions are only supposed to return the type you specifically asked for or null, so there shouldn’t ever be a situation where the cast fails. The logic for using ‘as’ in this circumstance might be that it’s cheaper because it avoids the potential for exception handling overhead. However, the () cast might actually be preferable because if it fails, and an exception is thrown, that would indicate that either you wrote the wrong type, or that there’s a bug in Unity! In that case, you’d probably want to know about it right away, so the exception about type conversion failure would be a good thing.
Neil:
I get where you’re going at. However I consistently use “as” now in stead of a direct cast. The reason for this is I like to do my null checks myself and handle them there and then.
I do not like my code breaking down with exceptions - preferably my code continues after a custom error is yelled out in the debug window and then I can investigate how deep the error goes.
In short: I prefer to poke at a sinking ship compared to going through wreckage.
To keep this still on topic:
If my instantiate-as combo returns null I yell out an error and bail out of my spawning method.
Since the project is still running, I can verify if the game object spawning failed by looking in the hierarchy or if the game object does not contain the component I’m casting to by inspecting the spawned object.
Don’t be Angry, Ant, or I’m gonna be a hol(e) and make TSCH Ah, back to the topic, where were we?
What I was referring to was how the case is handled when the object you’re trying to cast is null. As DGuy pointed out, I misunderstood what he said (wrongly assuming that by “exception” he meant NullReferenceException when I guess he meant InvalidCastException).
So I guess what it comes down to:
If it might happen that the object you’re trying to cast is null, be sure to check for that before using AS or use (Type) if you don’t care if it’s null because you’ll be checking that later anyways.
If it might happen that the object you’re trying to cast is of a type that you cannot cast to the type you want, and you’d like to check that with “it’s not null”, it’s probably preferable to use AS.
In both cases, it’s a good idea to be aware what might fail. Personally, I hardly run into situations where objects are of an unexpected type - but I frequently run into situations where objects are null, which is why I prefer the (…) style.
Now… I’m wondering… are there cases where Instantiate returns null? Like, when the transform you put into it is null, will it throw an NRE or will it return null. Anyways, I just looked at the docs and have to say (once again ), that I find JavaScript not the most useful language for documentation purposes… It’s much easier to drop information that’s available from the code than having to guess all the funky stuff that the JavaScript compiler (any in some cases Runtime) implicitely does for you