- Home /
Unityscript Coroutine Not Running When Called
I have a coroutine setup in UnityScript designed to move an object from one position to another. However, when calling the coroutine from another function in the same script nothing occurs. This is the code i'm using:
function MoveDown (movObj : GameObject) {
Debug.Log("Coroutine Start");
Debug.Log(movObj.transform.position);
var elapsedTime : float = 0;
var time : float = 5;
var startPos : Vector3 = movObj.transform.position;
var endPos : Vector3 = Vector3(0,0.06,-4);
while (elapsedTime < time)
{
//Debug.Log("Moving...");
movObj.transform.position = Vector3.Lerp(startPos, endPos, Time.deltaTime);
elapsedTime += Time.deltaTime;
yield;
}
}
And I am calling it using:
MoveDown(object1go);
None of the Debug.Logs occur in the console and the object does not move. All of this code is inside of a custom class I have created and the object that i'm trying to move has been instantiated through code, if any of this is important.
What am I doing wrong that is causing it not to run properly?
By "inside a custom class" do you mean a class not inherited from $$anonymous$$onoBehaviour - to be honest I'm not 100% sure, but I'd expect that the magic StartCoroutine() call Unity Script issues may only work on methods of a $$anonymous$$onoBehaviour derivative. You could try calling StartCoroutine yourself...
StartCoroutine($$anonymous$$oveDown(object1go));
Where are you calling it? Can you show the function where $$anonymous$$oveDown is called?
This is the entire class where it is all happening:
class Unit
{
var Unit1 : Transform;
var object1 : Transform;
function InstUnit () {
object1 = GameObject.Instantiate(Unit1, Vector3(0,0.06,0),Quaternion.identity);
var object1go = object1.gameObject;
$$anonymous$$oveDown(object1go);
}
function $$anonymous$$oveDown (movObj : GameObject) {
Debug.Log("Coroutine Start");
Debug.Log(movObj.transform.position);
var elapsedTime : float = 0;
var time : float = 5;
var startPos : Vector3 = movObj.transform.position;
var endPos : Vector3 = Vector3(0,0.06,-4);
while (elapsedTime < time)
{
//Debug.Log("$$anonymous$$oving...");
movObj.transform.position = Vector3.Lerp(startPos, endPos, Time.deltaTime);
elapsedTime += Time.deltaTime;
yield;
}
}
}
Using StartCoroutine causes an error about an unknown identifier.
Yes well that covers it then - you can't start a coroutine on something that isn't a $$anonymous$$onoBehaviour - as this call is already indirect from a $$anonymous$$onoBehaviour there's nothing to know that it's a coroutine.
You would need a Behaviour subclass attached to the Unit1 prefab (one of your own scripts is good enough). Then you can do:
object1go.GetComponent($$anonymous$$onoBehaviour).StartCoroutine($$anonymous$$oveDown(object1go));
Answer by whydoidoit · Apr 20, 2013 at 07:08 PM
You can only run coroutines on MonoBehaviour (script) classes. If you create your own non-MonoBehaviour class it can have a coroutine but only if it is in the immediate call, not called as a result of a first call (as it is in your Init code).
It feels odd to me that you are building this functionality in a class rather than a normal script - which leads you to all sorts of extra effort (like remembering to put GameObject in front of Instantiate and having to start coroutines with a massive statement), but perhaps there's a good reason.
Frankly, i'm not too sure myself why i'm creating this in a class. I just wanted to see if classes would be appropriate in this situation and it doesn't look that way!
After using that line of code that you supplied in your comment, the coroutine starts which I can see thanks to the Debug.Log, however the object does not move which is unusual. Uncommenting the "$$anonymous$$oving" Debug.Log constantly repeats that message, so it is obviously something to do with the transform controls.
Oh the reason it isn't moving is that you need to be using a number moving from 0..1 in the final Lerp parameter. You need to add it up yourself.
function $$anonymous$$oveDown (movObj : GameObject) {
Debug.Log("Coroutine Start");
Debug.Log(movObj.transform.position);
var elapsedTime : float = 0;
var time : float = 5;
var startPos : Vector3 = movObj.transform.position;
var endPos : Vector3 = Vector3(0,0.06,-4);
while (elapsedTime < 1)
{
//Debug.Log("$$anonymous$$oving...");
movObj.transform.position = Vector3.Lerp(startPos, endPos, elapsedTime);
elapsedTime += Time.deltaTime/time;
yield;
}
}
Ah, of course, it seems so simple now!
Thanks for all of your help! On a side note, how would you recommend me instatiating many objects that each have the same properties and functions like I have attemped above? Classes don't seem very appropriate, as you said, so I'm not too sure. Thanks again!
Well $$anonymous$$onoBehaviours are a really good way of attaching some discrete set of functions to a game object.
Classes are normally good at representing something not visible or not always visible - like a pickup item in an adventure game or a resource instance in an RTS that has a set of properties but isn't always actually an object in the game (when it's picked up and placed in an inventory or transported it's no longer attached to a game object).
Your answer
Follow this Question
Related Questions
yield behaves oddly with anonymous functions 1 Answer
yield works, but yield WaitForSeconds does not? 1 Answer
Need to call yield TWICE ??? (ANSWERED) 3 Answers
Respawn after delay 3 Answers
Yield WaitForSeconds doesn't work, give syntax error 1 Answer