Cannot use yield within a Javascript class?

I have a javascript class that will not execute a method containing a yield. Is there a workaround for this? Why doesnt it work?

The class is defined as follows:

class UIArrow extends System.Object
{
}

you can not yield in classes that don’t extend UnityEngine.Object, as it is a unity engine only feature

your extension of system.object is effectively cutting you from any unity relationship

Actually, I think you can only yield from instances of MonoBehaviour.

If you want to start a Coroutine (MyCoroutine) from non-monobehaviour objects, you can start your Coroutine by calling StartCoroutine on an existing monobehaviour somewhere in the scene:

someMonoBehaviourInTheScene.StartCoroutine(MyCoroutine());

This works for sure in C#. I have not tested if the Unity Java Script magic that makes yield functions work automatically also applies for non-monobehaviours. So it’s possible it won’t work for JS.

I tried class UIArrow extends UnityEngine.Object and it didn’t fix anything unfortunately =(

Having same issue. Is there another class we can extend that would allow yield?

Any known fix? =)

You need to extend from MonoBehaviour, which is what all Javascripts in Unity default to. If you don’t define a class within a Javascript, the script is seen as a class with the name of the script, and that class inherits from MonoBehaviour.

In C# you have to explicitly call StartCoroutine, which yield can be called inside. In Javascript, StartCoroutine gets called automatically, but in both cases, the function is getting called, whether you see it or not. That function is part of the MonoBehaviour class, so you need to extend from there.

I tried extending from MonoBehaviour as follows:

class UIArrow extends MonoBehaviour
{
}

But then I cannot ‘= New()’ to create a new instance of that class without an error saying to use AddComponent, but I could not find a way to make that work either. Am I missing something?

On another note, since a script is automatically a class of MonoBehaviour, is there any way to create instances of it? Or should I just give up on JS and start looking into C#?

Thanks guys!

Yes, monobehaviours need to be in attached to a GameObject.

For the heck of it, I tested the suggestion in my earlier post in JS and it works:

// Coroutiner.js
// this class is just used to run coroutines and needs 
// no further functionality
class Coroutiner extends MonoBehaviour
{
}

// Test.js
// a class inheriting from System.Object, using 
// coroutines:
class Test extends System.Object
{

	public static var coroutineRunner : Coroutiner = null;
	
	function Test()
	{
		if (coroutineRunner == null)
		{
			var go = new GameObject("Coroutiner");
			coroutineRunner = go.AddComponent(Coroutiner);		
		}		
	}

	function Go()
	{
		coroutineRunner.StartCoroutine(MyCoroutine());
	}
	
	function MyCoroutine()
	{
		yield;
		Debug.Log("it worked!");
	}	
}

You can now create instances of Test using new. Calling the function Go on an instance of Test will start the coroutine and prints “it worked!”.

I have been using

class myClass extends Object
{
}

var myVar : myClass;

I have been able to use yield with it with no problems of any kind… Unless I have more than 1 yield within the same function, that is. dreamora advised me once to extend the correct base and I have to admit that sounds like the easiest option… but I still love using my Invoke and InvokeRepeating calls to cause a time delay, rather than yield. Pesonal preference, only, since it works and never gives me any trouble at all…

If you are still struggling with your code, I would love to see your actual source and see what the problem is from there. Have you tried the last example from tomvds, yet?

I personally want to give his/her method a go myself. My way works, but it forces all my exposed variables to reside inside a variable in the inspector. This way it seems my variables would be in the root of the file. Thanks for that little tip tomvds…

@MrDude: I am confused at how that works for you, as that is basically where this conversation started, but does not work for me. Although, even if it did, only being able to use yield once would cause issues on some pieces.

@ALL: Knowing that a JS file is basically a class of MonoBehaviour, do you see any issue instantiating instances of it, like:

atype = Instantiate(newObject, Vector3(0,0,0), Quaternion.identity);
shootScript = atype.GetComponent("Shoot");
shootScript.DoStuff();

Any negatives to this? Performance or memory, etc? Note: this is an iPhone project.

@tomvds: I tried your example but the AddComponent always returns NULL so I get:

NullReferenceException: Object reference not set to an instance of an object

When: coroutineRunner.StartCoroutine(MyCoroutine());

Is called from Go();

You can not use System.Object extends for usage in Unity.
It expects UnityEngine.Object

I also miss the point why you could even want to avoid to use it.

You choose to use Unity for its features and simplicity, so why do you actively try to make your life a magnitude harder? Would you mind to explain this desire?

@dreamora: If you are referring to me, I do not care what extends I use. =) I am just trying to determine how to get access to yield functionality from a class that I can create instances of in JS.

Ah ok.

I was under the impression that you try to avoid it by any means as you again have System.Object in above code instead of just leaving the whole extends part out there for example or extending Object (which will automatically be Unity’s object class)