GRRR!!! Ok, something so simple shouldn’t be so annoying.
Pretty much, I’m wanting to get some basic information from a page (Eventually to get data from a sql database, but for now, just reading an echo in php) and from what I’ve gotten from the scripting reference files is this:
function getData(url)
{
var stream:WWW = WWW(url);
yield stream;
var tmpStr:String = stream.data;
return tmpStr;
}
or
function getData(url)
{
var stream:WWW = WWW(url);
yield stream;
return stream.data;
}
but it keeps giving me the “Generators cannot return values” error on the return line. I’ve seen many other examples where it returns values in a similar fashion, so what am I doing wrong? This should return a string right?
You can’t make coroutines return values like that. You can do this:
function Blah (a : int) : int {
return a*2;
}
Note that the return type is an int. You can leave that off in Javascript, but that’s still what it does. On the other hand:
function Foo () : IEnumerator {
yield WaitForSeconds(1.0);
}
A coroutine actually returns IEnumerator, whether you specify it or not. So you can’t return a value of another type. If you use “yield” in a function, that automatically makes it a coroutine.
The thing is, when you call a function that returns a value, it has to do that immediately. If you did:
function Awake () {
var stuff = GetData("http://somesite.com");
// Do something with 'stuff'
}
then GetData would have to return the string right away so the rest of the function can execute. But it can’t, because you don’t know if or when the download will actually be done. So, it’s not possible to use coroutines like that.
–Eric
So, in other words, there’s no way to get a string from a remote web page. T-T The only other thing I can think of is to use ajax and Application.ExternalCall
T_T But I’m still not sure that would work. Thanks for the information though.
Er, no, you just can’t return a string from a coroutine.
That hardly prevents you from getting it other ways. (e.g., wait for the coroutine to finish and get the string from a global variable, use some kind of callback thing, etc.)
–Eric
OK! I got ya, and figured it out.
var loadedData:Array = new String[10];
var lastUpdate:float = 0;
function Awake () {
DontDestroyOnLoad (this);
refreshInformation("http://127.0.0.1/unity.php",0);
}
function Update()
{
if(lastUpdate >= 5)
{
refreshInformation("http://127.0.0.1/unity.php",0);
//refreshInformation("http://127.0.0.1/unity1.php",1);
//refreshInformation("http://127.0.0.1/unity2.php",2);
//etc
lastUpdate = 0;
}
gameList = loadedData[0];
//otherValue = loadedData[1]
//otherValue = loadedData[2]
//etc
lastUpdate += Time.deltaTime;
}
And this would allow me to have ten values to be able to be updated. (scalable to what I program it to do of course.) Thanks for the help!
Well, the problem with that is you’re not waiting until the download is done, so you have no idea if the variable has any data or not. Something more like
var url : String;
private var downloadData : String;
function Start () {
yield GetWWWData(url);
print (downloadData);
}
function GetWWWData (url : String) {
var www = new WWW(url);
yield www;
downloadData = [url]www.data;[/url]
}
–Eric
I would normally use callbacks / delegates instead to react upon receiving the download directly