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\$

1 Answer 1

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, 2016 at 16:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .