- Home /
Problem with WWW.progress
Hi Guys.
Im working on app wihich is comunicating with server database through php. Problem is when i want to make progress bar for this communication. From what i know and read all over unity forums and internet... my code is right... from first i thought problem is in content-header which i was missing... but nothing changed when i added it.
Problem is that progress variable is 0 and when its complete its jump to 1. better yet... Debug.Log indicates that progress is nothing... not even 0... so no progress at all... as if unity coudnt get how many bytes was downloaded so far and thus cant make float number like bytesDownloaded/bytesTotal ...
So where is problem ? In my server ? or some missing info from header ? or bug in unity ?
here is my C# which makes Loading bar...
using UnityEngine;
using UnityEngine.UI;
public class LoadingBar : MonoBehaviour
{
public GameObject progressRadial;
private bool inProgress;
private float progress;
[SerializeField]
private Text progressText;
[SerializeField]
private Image progressCircle;
void Start ()
{
progressRadial.SetActive (false);
progressCircle.fillAmount = 0f;
InProgress = false;
Progress = 0f;
progressText.text = "0%";
}
void Update ()
{
if (InProgress) {
progressRadial.SetActive (true);
progressText.text = (Progress * 100).ToString ("#") + "%";
progressCircle.fillAmount = Progress;
Debug.Log ("DOWNLOAD PROGRESS : " + (Progress * 100).ToString("#") + "%");
} else {
progressRadial.SetActive (false);
}
}
public bool InProgress
{
get
{
return inProgress;
}
set
{
inProgress = value;
}
}
public float Progress
{
get
{
return progress;
}
set
{
progress = value;
}
}
}
And here is one testing method which handles download from server
public IEnumerator getListUsers(Action<string> result)
{
Debug.Log("DatabaseHandler.GETLISTUSERS: START");
string hash = md5(secretKey);
WWWForm frm = new WWWForm();
frm.AddField("list_users","true");
frm.AddField("hash", hash);
WWW hs = new WWW("web adress", frm);
Debug.Log("DatabaseHandler.GETLISTUSERS: DOWNLOADING");
loadbar.InProgress = true;
int count = 1;
while (!hs.isDone)
{
loadbar.Progress = hs.progress;
Debug.Log(count + " - " + hs.bytesDownloaded);
count++;
}
yield return hs;
loadbar.InProgress = false;
Debug.Log("DatabaseHandler.GETLISTUSERS: DOWNLOAD FINISHED");
if (hs.responseHeaders.ContainsKey("CONTENT-LENGTH"))
{
Debug.Log(hs.responseHeaders["CONTENT-LENGTH"]);
}
if (!string.IsNullOrEmpty(hs.error))
{
Debug.Log("DatabaseHandler.GETLISTUSERS: ERROR" + hs.error);
}
else
{
Debug.Log("HSTEXT: " + hs.text);
result(hs.text);
}
Debug.Log("DatabaseHandler.GETLISTUSERS: STOP");
}
Sooo... my only solution so far is to make just indicator for internet activity without any loading... but this should work or not ? I tested on android also... no change.
Answer by doublemax · Jan 27, 2017 at 10:16 AM
The problem probably lies on the server side. The script that generates the database output probably doesn't set the "content-length" header, so that the receiving side (Unity in this case) does not know in advance how many bytes it will receive.
But when i set content header to some big number like 10000000... it works fine... loading bar at 0% waiting as usual... and then it closes with error warning in console that Unity ended downloading with, for example, 83834864 bytes to be downloaded yet.
Isnt that proof that my script is correct ? isnt problem with some order issues ? I mean that unity is getting info from header as last thing or something...
my server script...
<?php
require_once 'db_connection.php';
$secret$$anonymous$$ey="pass";
if (isset($_POST['list_users'])) {
$real_hash = md5($secret$$anonymous$$ey);
if ($real_hash == $_POST['hash']) {
$query = "SELECT username FRO$$anonymous$$ SS_users";
$stmt = $db_conn->prepare($query);
$stmt->execute();
$stmt_rslt = $stmt->get_result();
$count = $stmt_rslt->num_rows;
if( $count == 0 ) {
echo "NO_USERS_FOUND";
} else {
$row= $stmt_rslt->fetch_array();
$output = $row['username'];
while ($row= $stmt_rslt->fetch_array()) {
$output = $output . " " . $row['username'];
}
//$attachment_location = 'files/ass.unity3d';
//header($_SERVER["SERVER_PROTOCOL"] . " 200 O$$anonymous$$");
//header("Cache-Control: public");
//header("Content-Type: application/zip");
//header("Content-Transfer-Encoding: Binary");
//header("Content-Length:".filesize($attachment_location));
header("Content-Length:".strlen($output));
//header("Content-Disposition: attachment; filename=ass.unity3d");
//readfile($attachment_location);
echo $output;
Die();
}
}
}
The content-length header looks ok, maybe some more headers are required to make it work:
http://stackoverflow.com/a/3563714
You can also put the url in a browser window and use the debug mode to check if the headers are set correctly. Compare it with other urls where the progress display in Unity works.
I tried headers from stackoverflow... didnt help..
my response header while doing request from unity is :
HTTP/1.1 200 O$$anonymous$$ Date: Fri, 27 Jan 2017 11:10:57 G$$anonymous$$T Server: Apache/2.4.10 (Debian) Content-Length: 82345 Vary: Accept-Encoding $$anonymous$$eep-Alive: timeout=5, max=99 Connection: $$anonymous$$eep-Alive Content-Type: text/html; charset=UTF-8 Content-Language: sk
and i dont have any links to which i compare it... but funny thing when i set header to 1000... it finishes download instantlly.. .downloading only 1000 bytes.. so i think header is fine... if that progress variable calculates something like bytesDownloadedSoFar/Content-LenghtFromHeader ... i think there is missing bytesDownloadedSoFar number and thats why im getting 0 and 1...
Answer by CesarNascimento · Jan 27, 2017 at 11:36 AM
Well it makes sense that it's not showing every step of the progress. In this code
while (!hs.isDone)
{
loadbar.Progress = hs.progress;
Debug.Log(count + " - " + hs.bytesDownloaded);
count++;
}
you're not yielding or anything, so this runs to its entirety while the Update from LoadingBar doesn't.
Try yielding at the end of that while, like this
while (!hs.isDone)
{
loadbar.Progress = hs.progress;
Debug.Log(count + " - " + hs.bytesDownloaded);
count++;
yield return null;
}
Answer by Braxatoris · Jan 27, 2017 at 04:42 PM
Yes, you are right... my bad... this way progress bar doesnt work but method yes. Ofcourse i had it right way but in the end i tried everything even taking yield out of the loop...
normally I have yield return hs; in loop... i tried yield return null; too no change...
Another interesting thing is that when i make contnet lenght long number like 10000000 it shows progress bar 0% as always... but in console my debug method shows DOWNLOAD PROGRESS : % for +/- 20times... and then it ends download.
debug method is in loadingbar class
Debug.Log ("DOWNLOAD PROGRESS : " + (Progress * 100).ToString("#") + "%");
where progress is practically www.progress variable... and there is nothing not even 0.. so its empty ?