- Home /
Another yield and www question
Hi there!
I'm kind of noob with unity, but I manage to make already a couple of good stuff with it.
Nowadays, and after reading tons of questions about yield, I couldn't get the right answers for my problem.
I want to make a query to a web server from my code. To be able to do that, I'm creating the WWW object with the url that I want to use, and wait for it with yield. When I do that in the Start function, everything goes cool and smooth, but here comes the problem. I don't want to call it from the start function.
I want to have a class called serverConnection, and into there retrieving the data form the webpage. At the moment I reached this stage, but I no longer know what to do.
using UnityEngine;
using System.Collections;
public class serverConnection
{
public string query()
{
string url = "http://www.google.com";
StartCoroutine(queryServer(url));
}
IEnumerator queryServer(string url)
{
WWW server = new WWW(url);
yield return www;
Debug.Log(www.text);
}
}
As you can see, I try to manage to split the code because I read that I should use the StartCoroutine call.
My original idea was to create something like this:
public class serverConnection
{
public string query(string url)
{
WWW www = new WWW(url);
return www.text;
}
}
I don't know if I explain myself there... I was trying to create an "envelope" around the interaction with the server, and to retrieve only the "web content" inside the string return value.
The main problem of that, is that I'm forced to wait for the WWW object to be completely downloaded, and I found no other solution than yield (or busy waiting, but I really don't want to go through that ugly way :S)
Does somebody have some ideas?
The question is what do you want if the download is not finished yet? Showing the progress?
That sound good. I'm actually downloading a list of elements, and I want to display them on the GUI. That's why I wanted to wait for the download and then show the list of the downloaded elements. In order to do that, I'm forced to do as whydoidoit told me. But I need to wait always to the coroutine, and that's the main problem here for me.
Answer by Flashito · May 14, 2013 at 02:20 PM
I was just asking if someone knew another solution. Yours is really cool one, and I learned about the System.Action
. But for the case that I need, I require that all those operations to be synchronized with the "main" couroutine. I have done a solution that I'm not proud of, but it works, and it fits with the requirements of my programm. It's:
string queryServer(string url){
WWW www = new WWW(url);
while(!www.isDone){
//This line is for not having the processor always checking, so we give a bit time to the internet
Thread.sleep(100);
}
return www.text;
}
Thanks a lot for your suggestions and help :), and again really cool the System.Action
. I'll keep that on mind.
Answer by whydoidoit · May 13, 2013 at 04:35 PM
You can't return it, but you can pass an action to be executed when the code is ready.
public void RunQuery(string url, System.Action<string> onComplete)
{
StartCoroutine(DoQuery(url, onComplete));
}
IEnumerator DoQuery(string url, System.Action<string>onComplete)
{
var www = new WWW(url);
yield return www;
if(string.IsNullOrEmpty(www.error)) onComplete(www.text);
}
Then you can call it like this:
var query = "search?q=whydoidoit";
RunQuery("http://www.google.com/" + query, result=>{
Debug.Log(query + ": " + result);
//Actually do something useful
});
$$anonymous$$eep in $$anonymous$$d that StartCoroutine is a function of $$anonymous$$onoBehaviour. So you need a $$anonymous$$onoBehaviour instance to call StartCoroutine on that instance.
That sound cool, and actually works!! thanks for that tip. However the problem is that RunQuery will not be waiting for DoQuery to finish, and if you put a yield return StartRoutine();
then I must put as a return value the IEnumerator and we are at the beginning of the topic again.
Am I missing something?
But again thanks for the really fast reply
Well up to you, you could just run the whole thing as a coroutine for sure, or you could chain calls in side the result function of RunQuery.
RunQuery(someUrl, result=> {
RunQuery(anotherUrl + result, secondResult=>{
//Further update
});
});
Of it might just be nicer to do a straight coroutine.
But after all that chain, I'm still having to wait for the "last coroutine" to ends. $$anonymous$$y issue here is exactly that, that I can't wait for a coroutine or a yield without having a function returning IEnumerator that forces me to do it on Start os OnGUI. $$anonymous$$y intentions are something like this:
queryServer{
//Doing some stuff
//ask server for some information
//wait for the server information
//process that information
}
And all that then call it from another funtion, but always "linear" ins$$anonymous$$d of 2 routines at the same time... Is that even possible in unity? Or anytime I want to ask for a server information must I have to wait for the information in a coroutine "unsynchronize"(I'm not sure that word actually exists)
guys, what's up with the "progress" and "isDone" properties in WWW ?
I've never tried 'em ....
http://docs.unity3d.com/Documentation/ScriptReference/WWW-progress.html
http://docs.unity3d.com/Documentation/ScriptReference/WWW-isDone.html
Your answer
Follow this Question
Related Questions
yield www loading local file blocks UI 0 Answers
yield return www - What is www referring to? 2 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers