InvalidProgramException: Invalid IL code - when using static function

Hello,

I have a script, from where I want to use a static function:

// RenderScript.js
static function DoRender(c:Color){
	var childrenRenderer : Renderer[];
	childrenRenderer = GetComponentsInChildren.<Renderer>();

	for (var childRenderer : Renderer in childrenRenderer) {
		childRenderer.material.color = c;
	}
}

When im trying to use it in some other script:

function OnMouseOver() {
	RenderScript.DoRender(Color.red);
}

I get the following error: “InvalidProgramException: Invalid IL code in RenderScript: DoRender (UnityEngine.Color): IL_0003: callvirt 0x2b000001”.

Anyone any idea what could be wrong?
Thank you.

PS. When I’m using the DoRender() function from the same script, where the OnMouseOver() is, it works without any problems.
I also searched the forums regarding this error, but couldn’t find anything useful so far…

I don’t know if this is causing the error, but you are calling an instance method from your static function.

// RenderScript.js
static function DoRender(c:Color){
    var childrenRenderer : Renderer[];
    childrenRenderer = GetComponentsInChildren.<Renderer>();

    for (var childRenderer : Renderer in childrenRenderer) {
        childRenderer.material.color = c;
    }
}

GetComponentsInChildren.<Renderer>() is an instance method. You can’t call it without having an object and since you are using a static method, there is no instance. You will need a different way of gathering all the renderers, maybe making a singleton and then accessing the renderers through that.

How to implement a singleton in js. You can do it with properties if you want to but it isn’t really necessary.

//Singleton.js
private static var rendererParent : GameObject;

public static function GetRendererParent () : GameObject {
      if(rendererParent == null) {
           rendererParent = GameObject.Find("Some GameObject");
      }
      return rendererParent;
}

then find the instance using GetRendererParent() and call GetComponentsInChildren() with that. Note that this will always use the same instance, thats why its a singleton. If you want to be able to change the game object, then you will need to do something different such as pass the parent into the function.

Edit:

If the parent object is varying, you probably don’t want it a singleton. Your code was close, but you want to pass the reference to the game object into the function.

//Not a Singleton
public static function DoRender (_objectName : String , c : Color) {

    var  rendererParent = GameObject.Find(_objectName);
    //Find a GameObject with the name you pass into the function.

    //gather all the renderers in its children.
    var childrenRenderer : Renderer[] = rendererParent.GetComponentsInChildren.<Renderer>();

    for (var childRenderer : Renderer in childrenRenderer) {

       childRenderer.material.color = c;

    }
}

or an overloaded method that takes the game object directly. The compiler can infer which method to use based on what arguments you pass.

//overloaded method.  Takes a GameObject and a color rather than a string and a color.
public static function DoRender (_object : GameObject , c : Color) {

    //gather all the renderers in its children.
    var childrenRenderer : Renderer[] = _object.GetComponentsInChildren.<Renderer>();

    for (var childRenderer : Renderer in childrenRenderer) {

       childRenderer.material.color = c;

    }
}