2
\$\begingroup\$

I am using Unity 3d to create a real time multiplayer game. I have a database set up that keeps track of player statistics and what in app purchases they have purchased. I have written a Database class that is used to access my database via php scripts. It all works pretty well, but I run into problems when I try to get values from the database and it doesn't return quick enough. My assumption is that I need to use a coroutine in order keep letting it run so that I can eventually get the value. How exactly would I do that though?

This is the code I currently have:

public string GetValue(string id, string valid)
{
    string hash = Md5Sum(string.Format("{0}{1}{2}", id, valid, secretKey));
    string url = string.Format("{0}id={1}&vid={2}&hash={3}", getValue, id, valid, hash);
    WWW www = new WWW(url);
    while (!www.isDone) { }
    return www.text;
}

I figured that by adding the while loop in the middle it would always return a value but it doesn't seem to work that way. Should this be in a coroutine? And if so how would I get my value back from it compared to how I currently do it where it just returns the string value I wanted.

\$\endgroup\$
2
\$\begingroup\$

Yes, you can use a coroutine for this. It's essentially making it asynchronous.

The documentation for the WWW class actually has an example for this:

public class ExampleClass : MonoBehaviour {
    public string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";
    IEnumerator Start() {
        WWW www = new WWW(url);
        yield return www;
        Renderer renderer = GetComponent<Renderer>();
        renderer.material.mainTexture = www.texture;
    }
} 

In this example the call is made via the Start() method of the script. Likely a good place to be loading data from your database. However, you could also convert this to a method call, similar to your existing code, by passing in a callback:

 public string GetValue(string id, string valid)
 {
     string hash = Md5Sum(string.Format("{0}{1}{2}", id, valid, secretKey));
     string url = string.Format("{0}id={1}&vid={2}&hash={3}", getValue, id, valid, hash);
     StartCoroutine(QueryDB(url, (myReturnValue) => {
         if(myReturnValue) { ... }
     });

 }

 IEnumerator QueryDB(string url, System.Action<string> callback)
 {
     WWW www = new WWW(url);
     yield return www;
     callback(www.text);
 }

This creates a method on the fly to take the action you're interested in when the coroutine finishes (that's the if(myReturnValue) { ... } part).

\$\endgroup\$
1
  • \$\begingroup\$ All untested code... Please don't expect copy/paste to work. Edit the answer if you had to make changes. \$\endgroup\$
    – House
    Apr 6 '16 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.