InvalidCastException in Javascript

The error I get is this:

InvalidCastException: Cannot cast from source type to destination type.
TestOffMeshLinkActivation.Start () (at Assets/Scripts/TestOffMeshLinkActivation.js:13)

The code:

private var m_OML1 : OffMeshLink;
private var m_OML1Renderers : Renderer[];

function Start()
{
	var list : GameObject[];
	list = GameObject.FindGameObjectsWithTag("OML1");
	m_OML1 = list[0].GetComponent(OffMeshLink);
	m_OML1Renderers = list[0].GetComponentsInChildren(Renderer);
}

The error happens on the line where it does GetComponentsInChildren. As far as I can tell, my code is exactly like the example here: http://unity3d.com/support/documentation/ScriptReference/GameObject.GetComponentsInChildren.html

I must be missing something silly, or I don’t really understand how GetComponentsInChildren is supposed to work.

The FindGameObjectsWithTag is functioning, because I’m able to use the m_OML1 object with no trouble.

**GetComponentsInChildren(Renderer)**
returns Component[]
**GetComponentsInChildren.< Renderer > ()** //without spaces, i had to enter spaces because of this HTML text decoder
returns Renderer[]

Actually the docs a̶r̶e̶n̶’̶t are wrong. For Javascript you don’t have to use the angle brackets and pass in a type. The reason the documentation version is almost right is the following line :

for (var joint : HingeJoint in hingeJoints)

That line takes each Component item from hingeJoints and implicitly casts them into the HingeJoint type.

The documentation clearly says

GetComponentsInChildren(type: Type): Component;

which means the function returns an array of Components. Javascript allows you to cast on the fly, which makes it very sloppy and prone to errors, but the documentation is correct.

Revision


Revised after all the comments on my answer.

The documentation is wrong, but not for the reasons argued. The documentation has the line var hingeJoints : HingeJoint[]; which breaks, because it tries to implicitly convert an array of components to HingeJoint. If you changed it to var hingeJoints; it would work exactly right.

I made a dummy scene to illustrate why the rest of it works. TestObject has “test.js” on it, and three children, a,b,c, with Mesh Renderers on them.

13753-testsetup.png

test.js:

#pragma strict

function Start () { 
    var renders = gameObject.GetComponentsInChildren(MeshRenderer); //Component[]
	for(var renderer:MeshRenderer in renders){ //implict cast on this line
		Debug.Log(renderer.name);
	}
}

When I click play, it prints out a, b, c to the log (so it is finding each of the renderers correctly).

The reason this works is implicit casting.
If I were to explicitly cast everything, it would look like this:

#pragma strict

function Start () { 
    var renders:Component[];
    renders = gameObject.GetComponentsInChildren(MeshRenderer);
    for(var comp:Component in renders){ //get each object as a component
        var renderer : MeshRenderer;  
        renderer= comp as MeshRenderer; //cast the component to a MeshRenderer
		Debug.Log(renderer.name);
	}
}

I’m not saying this is the right way. I’m definitely not advocating for this because it’s incredibly sloppy and implicit type casting causes lots of problems (as noted). All I am saying is that the syntax of passing a type through parentheses works and you don’t have to use the generic version.