- Home /
Performing "transform.Rotate" in it's own thread
I'm struggling to wrap my head around how to implement threading in Unity.
I have in may game a place where I check a web server to see if there are game level xml data updates and then download the new xml files. I've got all this working using the WWW class and leveraging yield. Here is a code fragment:
...
var www : WWW = new WWW (myURL);
// Wait for download to complete
yield www;
// put xml into a new string varible
var myXMLData : String = www.data;
// do stuff with myXML data
...
Again, I've got all this working just fine -- files are downloaded and processed successfully.
On the game screen, I have a sprite gameObject of a simple spiral image that I rotate on the Z axis to show the user that the code is working. I have a simple Update function to rotate the sprite continuously:
function Update() {
myWaitIconSpriteImage.transform.Rotate(0, 0, Time.deltaTime * -60);
}
My problem is during the the download in the WWW class the rotation stalls and does nothing. I am aware that is is because during the downloading and processing of the file, no other code can execute since it's all happening in the same frame.
Right. So I am trying to see about implementing the sprite rotation in its own simple thread but I'm stuck. I've read that the Unity API is not thread safe -- but I am not sure that the "Unity API" covers or not cover to see about how I can have a simple sprite rotation not freeze.
I'm coding using UnityScript/Javascript. Any thoughts on how I can do this or any other method to achieve what I'm trying to do?
Thanks, Manny
Answer by Eric5h5 · Dec 18, 2014 at 06:38 PM
You can't use most Unity API functions in threads. However, coroutines are not threads. It's not the case that WWW is blocking anything and it's not happening in the same frame; the "yield www" transfers control back to the rest of the code. So you have some other unrelated problem, but don't have enough code posted to guess what it is.
Well, I'm parsing the X$$anonymous$$L file and interrogating some attributes and writing the xml file out to storage (iOS platform), and updating some variables.
I'm aware that coroutines are not threads and that "most" Unity API are not thread safe -- but speaking more specifically, do we know if the transform.Rotate method and Time.deltaTime I'm using are?
Thanks.
Here is my entire function code:
function downloadBoardUpdate(setID : int) {
var currSetInfo : clsSetFileInfo;
currSetInfo = allSetList.Item[setID];
// Start a download of the given URL
var www : WWW = new WWW (GlobalData.urlAPI +"cmd=downloadset&set_id=" + setID);
// Wait for download to complete
while (!www.isDone) {yieldWWWWait(www);}
var dirPath : String = Application.persistentDataPath + "/Boards";
// put xml into a new string varible
var myX$$anonymous$$L : String = www.data;
if (myX$$anonymous$$L != null && !myX$$anonymous$$L.Trim.Equals("")) {
var newSetInfo : clsSetFileInfo = new clsSetFileInfo();
var reader : XmlTextReader = new XmlTextReader(new StringReader(myX$$anonymous$$L));
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element) {
if (reader.Name == "file") {
newSetInfo.setID = int.Parse(reader.GetAttribute("set_id"));
if (reader.GetAttribute("system_set") != null && reader.GetAttribute("system_set").Equals("Y"))
newSetInfo.dirName = "Default";
else
newSetInfo.dirName = reader.GetAttribute("nickname");
newSetInfo.checkSum = reader.GetAttribute("checksum");
break;
}
}
}
var sr = File.CreateText(Application.persistentDataPath + "/Boards/" + newSetInfo.dirName + "/" + newSetInfo.setID + "-" + newSetInfo.checkSum + ".xml");
sr.WriteLine(myX$$anonymous$$L);
sr.Close();
// delete old file
File.Delete(Application.persistentDataPath + "/Boards/" + currSetInfo.dirName + "/" + currSetInfo.setID + "-" + currSetInfo.checkSum + ".xml");
// update sort list collection object
allSetList.Remove(newSetInfo.setID);
allSetList.Add(newSetInfo.setID, newSetInfo);
Debug.Log("Board Set file successfully updated");
}
}
// needed to move the yield statement into its own function to allow calling functions to be able to return a value
function yieldWWWWait(www : WWW) {
yield www;
}
Thanks for looking.
Your "yieldWWWWait" function should be removed; just do
while (!www.isDone) {yield;}
Or replace that with
yield www;
However that's not actually relevant, and not what I meant, since coroutines do not block. I'm talking about the rest of the code. For example, you can clearly see that having a coroutine does not prevent Update from running:
function Awake () {
Delay();
}
function Update () {
transform.Rotate (Vector3.up * Time.deltaTime * 10);
}
function Delay () {
yield WaitForSeconds (5);
Debug.Log ("Done");
}
No Unity functions can be used in threads, except Debug.Log. You don't need to use threads though.
Got it to work by removing the function yieldWWWWait as you suggested. Either of your yield statements (above) worked fine to allow the Update function which rotates my sprite to run just fine.
Now, if only we can understand why the yield in the function, the way I had it, blocked the Update from running -- I would love to know.
Any ideas?
Thanks again.
I can't imagine how it could block anything, so I'm afraid I have no ideas about that.
Your answer
Follow this Question
Related Questions
JS file deleting multiple game objects 0 Answers
JavaScript 3 Arrays questions 1 Answer
Update call for Multiple GUIText fails 1 Answer
UnityScript set button text 1 Answer
#define directive in UnityScript 1 Answer