• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by AndrewGrayGames · Feb 13, 2013 at 02:46 AM · c#wwwjson

WWW data acquisition from remote server failing

I've started using LitJSON for my processing needs, and (quickly) built a Net Access layer to acquire data from a remote source. My Net Access Layer looks like this:

NET Access Layer

 using UnityEngine;
 using System;
 using System.Collections;
 using LitJson;

 [Serializable]
 public class ServerConnector : IDisposable
 {
 #region Variables / Properties
 
 public string Address { get; private set; }
 public bool AssetAcquired { get; private set; }
 private WWW _payload;
 
 #endregion Variables / Properties
 
 #region Constructor
 
 public ServerConnector(string address)
 {
     if(string.IsNullOrEmpty(address))
         throw new ArgumentNullException("address");
     
     Address = address;
     DownloadPayload();
 }
 
 #endregion Constructor
 
 #region Static Methods
 
 public static T UnpackJSONFromSource< T >(string address)
 {
     if(string.IsNullOrEmpty(address))
         throw new ArgumentNullException("address");
     
     T result = default(T);
     using(ServerConnector connector = new ServerConnector(address))
     {
         if(connector.AssetAcquired)
         {
             result = connector.UnpackJSON< T >();
         }
     }
     
     return result;
 }
 
 #endregion Static Methods
  
 #region Methods
 
 public void Dispose()
 {
     if(_payload != null)
         _payload = null;
 }
         
 public string GetTextData()
 {
     return _payload.text;
 }
 
 public T UnpackJSON< T >()
 {
     Debug.Log("Payload: " + _payload);
     T result = JsonMapper.ToObject< T >(_payload.text);
     return result;
 }
 
 private IEnumerator DownloadPayload()
 {    
     _payload = new WWW(Address);
     yield return _payload;
     
     if(_payload == null)
     {
         Debug.LogError("Failed to get the payload.");
         AssetAcquired = false;
         return true;
     }

     if(_payload.error != null)
     {
         Debug.LogError("Error occurred during download from " + Address + ": " + _payload.error);
         AssetAcquired = false;
     }
     else
     {
         AssetAcquired = true;
     }
 }
 
 #endregion Methods
 }

Naturally, to test that this is working correctly, I created a single game object in a scene, with the following behavior:

Test Behavior

 using UnityEngine;
 using System.Collections;

 public class NetLayerTest : MonoBehaviour 
 {    
 #region Variables / Properties
 
 private ServerConnector _connector;
 private string _secretMessage = "The secret message was not found or acquired.";
 
 #endregion Variables / Properties

 void Start () {
     _connector = new ServerConnector("http://andrewrgray.webs.com/dataz/test-data.json");
     
     Debug.Log("Address for download: " + _connector.Address);
     if(_connector.AssetAcquired)
         _secretMessage = _connector.UnpackJSON();
     
     Debug.Log(_secretMessage);
 }
  }

However, I notice whenever I start up in my test scene that I always get the Debug messages, "Failed to get the payload.", and "The secret message was not found or acquired." Long story short, my usage of WWW isn't getting any results!

I've made sure that the URL pointing to this JSON resource is correct (in fact, here it is), and that my usage of the WWW class in the Net Access layer is correct. I'm running my project in the editor, so I doubt that any interference from building as a webplayer is occurring (though, to rule that I out, I changed to a PC Any CPU build to be sure.)

Obviously, I am doing something totally wrong. The question is: what?

A note: This is my first time using WWW, so I made sure to consult the documentation first, and it did not yield enough information for me to discover the cause of the problem.

Comment

People who like this

0 Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Dave-Carlile · Feb 13, 2013 at 02:58 AM 1
Share

Have you tried just making a basic function using WWW to grab the raw resource? Does that work? If so, start adding back the other functionality.

avatar image AndrewGrayGames · Feb 13, 2013 at 03:09 AM 0
Share

Commented out the existing body of Start(), changed it to an IEnumerator, then created just a basic body where I'm doing pretty much what ServerConnection.DownloadPayload() is doing; successful result. So, WWW is working. My usage in this utility class is off, though.

2 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by AndrewGrayGames · Feb 13, 2013 at 04:32 AM

iwaldrop set me on the correct path; my problem was that as the MonoBehaviour wasn't working with the coroutines, nothing was working as intended. As such, I altered my setup as below:

ServerConnector Class

 [Serializable]
 public class ServerConnector : IDisposable
 {
 #region Variables / Properties
  
 public string Address { get; private set; }
 public bool AssetAcquired { get; private set; }
 private WWW _payload;
  
 #endregion Variables / Properties
  
 #region Constructor
  
 public ServerConnector(string address)
 {
     if(string.IsNullOrEmpty(address))
        throw new ArgumentNullException("address");
  
     Address = address;
 }
  
 #endregion Constructor
  
 #region Methods
  
 public void Dispose()
 {
     if(_payload != null)
        _payload = null;
 }
  
 public string GetTextData()
 {
     return _payload.text;
 }
  
 public T UnpackJSON()
 {
     Debug.Log("Payload: " + _payload);
     T result = JsonMapper.ToObject(_payload.text);
     return result;
 }
  
 public IEnumerator DownloadPayload()
 {   
     _payload = new WWW(Address);
     yield return _payload;
  
     if(_payload == null)
     {
        Debug.LogError("Failed to get the payload.");
        AssetAcquired = false;
        return true;
     }
  
     if(_payload.error != null)
     {
        Debug.LogError("Error occurred during download from " + Address + ": " + _payload.error);
        AssetAcquired = false;
     }
     else
     {
        AssetAcquired = true;
     }
 }
  
 #endregion Methods
 }

Test Behavior

 public class NetLayerTest : MonoBehaviour 
 {    
 #region Variables / Properties
 
 public string URL = "http://andrewrgray.webs.com/dataz/test-data.json";
 private ServerConnector _connector;
 private string _secretMessage = "The secret message was not found or acquired.";
 
 #endregion Variables / Properties
 
 #region Methods

 IEnumerator Start () 
 {
     _connector = new ServerConnector(URL);
     yield return StartCoroutine(_connector.DownloadPayload());
     
     if(_connector.AssetAcquired)
         _secretMessage = _connector.GetTextData();
     
     Debug.Log(_secretMessage);
 }
 
 #endregion Methods
 }

While telling the utility class in the constructor who the calling MonoBehaviour is was a great idea, the problem is that the actual data access took 0.02s...longer than it took for the behavior to determine that the data had not been retrieved. It was impossible for me to get around moving the coroutine call to the actual behavior.

Once that happened, though, the rest fell into place!

Comment
iwaldrop

People who like this

1 Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image iwaldrop · Feb 13, 2013 at 04:38 AM 0
Share

Nice solution. I wouldn't say passing the calling MonoBehaviour was a good idea, it was just a hack while I was also trying to solve some of my own problems! ;)

avatar image

Answer by iwaldrop · Feb 13, 2013 at 03:00 AM

Try checking if (_payload.text == null) in your Coroutine.

"This is a test of the Net Layer Access system. If I can see this, I succeeded."

Works for me. ;)

Comment
AndrewGrayGames

People who like this

1 Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AndrewGrayGames · Feb 13, 2013 at 03:20 AM 0
Share

@iwaldrop What line did you change to if(_payload.text == null)? I've tried in a couple of places (Inside DownloadPayload(), of course), but I'm not seeing quite where that's helping...

avatar image iwaldrop · Feb 13, 2013 at 03:33 AM 0
Share

Ahh...I hadn't downloaded and tested your code, but now that I am it is apparent what's (not) happening. Since you haven't inherited from MonoBehaviour your IEnumerator won't run.

Line 25, if your class was a MonoBehaviour, should read:

 StartCoroutine(DownloadPayload());

A way to test this this is to insert

 Debug.Log (_payload.text);

on line 76. It never prints.

avatar image iwaldrop · Feb 13, 2013 at 03:40 AM 1
Share

One quick hack to make it work; replace the following code;

 public ServerConnector(string address, MonoBehaviour layerTest)
 {
     if(string.IsNullOrEmpty(address))
        throw new ArgumentNullException("address");
  
     Address = address;
     layerTest.StartCoroutine(DownloadPayload());
 }
  
 #endregion Constructor
  
 #region Static Methods
  
 public static T UnpackJSONFromSource< T >(string address)
 {
     if(string.IsNullOrEmpty(address))
        throw new ArgumentNullException("address");
  
     T result = default(T);
     using(ServerConnector connector = new ServerConnector(address, null))
     {
        if(connector.AssetAcquired)
        {
          result = connector.UnpackJSON< T >();
        }
     }
  
     return result;
 }
  

And on your NetLayerTest;

 _connector = new ServerConnector("http://andrewrgray.webs.com/dataz/test-data.json", this);

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Problem Parsing Json (JsonUtility) 1 Answer

Retreive Jsonfile and Read It 0 Answers

Integrating Watson Speech-to-Text with Unity 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges