differences: generic GetComponent.<Script>() vs GetComponent("Script") ? explain...

Not that I know what "generics" means in this construct, but can anyone nicely, gently, kindly and clearly explain the syntax sugar of calling/accessing/getting non attached objects, attached objects and their components in Unity? In UnityScript please, first, then maybe C#

could you please rename you question title to something like "Accessing Components of NPC GameObjects" or something like that which is more descriptive towards your question. What the hell does "if .<script1>() is generics What is (script1)?" mean anyway?It looks like homemade broken code.

–

Changed the title to make more sense to anyone reading it later

–

3 Answers

3

Note - the use of the word Script below refers to your own script. Substitute in YourScriptName for Script there

GetComponent.<Script>()

finds the component of type Script, and returns a Script reference to you

GetComponent(Script)

finds the component of type Script, then returns a Component reference to you

GetComponent("Script")

finds the component with name Script, then returns a Component reference to you

The difference between name and type is a large one - errors with type will throw compile time errors, while errors in the name will throw runtime errors

The difference between it returning a Script and a Component reference to your script is that a Script reference will immediately have all of the Script functions and variables available to you, whereas with Component, it'll either need casting manually, or it'll need to dynamically call functions and variables, which again will give you runtime errors

Regarding c#:

Since c# doesn't do the whole dynamic typing thing, you have to manually cast the latter two versions, so your code looks like this for all three:

Script script = GetComponent<Script>();

Script script = GetComponent(typeof(Script)) as Script;

Script script = GetComponent("Script") as Script;

I would recommend always using the generic version whenever possible in both languages - it's the most robust version, giving you the correct compile time errors you need to solve issues

"The difference between name and type is a large one - errors with type will throw compile time errors, while errors in the name will throw runtime errors" this is incredibly useful thank you! The whole answer is to be honest, vote up!

–

no - myVarHoldingScript = GetComponent.<NameOfScript>();

–

Javascript files make an implicit class called NameOfScript behind the scenes, and put your code into that. Generic stuff always expects a class name, not a filename

–

Hah, nice to know it was of some use. JS does a lot of weird stuff in the background, e.g. putting code that's not in functions (besides declerations) into an implicit Main function, and calling coroutines implicitly (with some hilarious side effects). Most of it is documented sparsely though, if at all.

–

Currently working 2 full time jobs so don't have the time to mentor anyone, but I do spread my insanity/knowledge in the IRC channel

–

Generics can be thought of as variables, but they express a variable type, not a variable value, and they are set compile time (static typing) rather than run time (dynamic typing).

It allow you to change type of something in the context. The generic GetComponent looks like:

public T GetComponent<T>() where T : Component
{
    // It gets the type of T and calls the 
    // non-generic variant, for convenience.
    // Then it cast the result to T.
    return (T)GetComponent(typeof(T)); 
}

The code `where T : Component` is a constraint on the type T.

It says `T` must be a type that is a subclass of `Component`, so you can't call for example `GetComponent();`, because `int` isn't a subclass of `Component`.

It is quite possible to call `GetComponent(typeof(int));` but it is considered an error, and the compiler won't whine about this since it can't apply the constraint in the same manner as with the generics. For this reason the generic version provides stronger type safety (less bugs).

Consider calling `GetComponent();`. We could just swap out `T` for `BoxCollider` to see what the generic version would resolve to:

public BoxCollider GetComponent<BoxCollider>()
{
    return (BoxCollider)GetComponent(typeof(BoxCollider)); 
}

you could set the object as a prefab in a variable. this is the way we do it for absolutly everything. There is possibly a better way but I feel like that with all scripting.

var prefab : GameObject;

function Update ()
{
   if (prefab == null)
   {
      prefab = GameObject.FindWithTag("TaggedObject");
   }
}
function DoSomething()
{
    DoThis = prefab.GetComponent(Script)
    DoThis.Variable = whateveryouwant;
}

well your comment doesn't help inform me as to what confuses you so why the hell should I explain anything, your question is confusing but I still did the best to provide you with an answer have some damn courtesy and be more informative.

–

Bob I have a question about your code. So what you are doing is accessing Variable from a prefab loaded in the inspector... What is the purpose of your code? I mean I understand your lines, but a practical use wuld let me understand it perfectly. Thanx in advance

–

never said load the object in the inspector i just answered with minmal code as it wasn't an indepth question.

–