Using yield WaitForSeconds - c#

I might be asking something that's extremely obvious and I have overlooked something, but I'm trying to create a pause before it does something.
I have seen this being used in many places online -
yield WaitForSeconds(2);
However I get a syntax error of,
"Error CS1528: Expected ; or = (cannot specify constructor arguments
in declaration) (CS1528) (Assembly-CSharp)
Which confuses me as im not really sure what yield as a keyword really means or does, and im under the assumption that WaitForSeconds is a class of its on with the "2" being in the constructor (not in a declaration) any help would be appreciated. thanks!

What you want is t use an IEnumerator.
IEnumerator Example()
{
print(Time.time);
yield return new WaitForSeconds(5);
print(Time.time);
}
Then you will ask: How do I call this?
void Start()
{
print("Starting " + Time.time);
StartCoroutine(WaitAndPrint(2.0F));
print("Before WaitAndPrint Finishes " + Time.time);
}
IEnumerator WaitAndPrint(float waitTime)
{
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint " + Time.time);
}
I just read the link Jon Skeet posted on the comments, I too recommend it, it has pretty valuable information.

You are using the Javascript code for Unity, and try it in the C# language, that´s why you get the error message.
If you click on the C# language selector on a page like http://docs.unity3d.com/ScriptReference/WaitForSeconds.html
you will get the following example code for C#:
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
IEnumerator Example() {
print(Time.time);
yield return new WaitForSeconds(5);
print(Time.time);
}
}

Related

Unity StartCoroutine MoveNext and mapper?

I have just jumped to Unity and I am doing some experiments to retrive data from an API
Below you can see the test code could you please help me to understand if i am the right way or not please?, because probably i am missing the mapper isn't it ?
Thanks in advance.
void Start()
{
comments= StartCoroutine(this.GetComments("https://jsonplaceholder.typicode.com/comments"));
Debug.Log(comments);
}
private IEnumerator Comments GetComments(string url) {
List<Comments> returnComments = new List<Comments>();
UnityWebRequest comments = UnityWebRequest.Get(url)
comments.SendWebRequest();
while (comments.MoveNext())
{
var comment = comments.Current;
returnItems.Add(comment);
}
return returnComments;
}
Yield the SendWebRequest function.
yield return webRequest.SendWebRequest();
Access the data through the download handler.
var dataString = webRequest.downloadHandler.text;
Full sample code in the docs UnityWebRequest.Get

How to launch coroutine in Editor with the "Editor coroutine" package?

I'm trying to build a tool in the Unity Editor with an EditorWindow on his own. This tool will need to access a MySQL DB through PHP files so I need to use coroutines. I looked for a solution and fall upon a preview package "Editor Coroutine" and installed it. I don't see how it works and the documentation doesn't say anything (or anything i've understanded) about how to use it. Do you know any way to make this thing work properly ?
I've tried to simply do a "StartCoroutine()", to call it from an Editor class or to create an object (GameObject) to call it, but none of this work :/.
Be aware that the accepted answer's while loop completely blocks the Editor until the download is done. For a simple text that might be fine but for larger files this might become an issue.
There is however EditorApplication.update you can subscripe to in order to call a method every frame in the Editor. So for an EditorWindow you could do something like
private IEnumerator currentDownload;
private void ProcessDownload()
{
if(currentDownload!=null) currentDownload.MoveNext();
}
private IEnumerator UpdateVersion(string message)
{
string post_url = NetworkManager.baseUrl + "VersionUpdate.php";
WWWForm form = new WWWForm();
form.AddField("Message", message);
form.AddField("Version", Application.version);
UnityWebRequest www = UnityWebRequest.Post(post_url, form);
www.chunkedTransfer = false;
yield return www.SendWebRequest();
if(www.error == null){
Debug.Log(www.downloadHandler.text);
} else {
Debug.Log("error!: " + www.error);
}
}
and use it like
// makes sure the callback is added only once
EditorApplication.update -= ProcessDownload;
EditorApplication.update += ProcessDownload;
currentDownload = UpdateVersion("whatever string");
I faced the same problem. I ended up with the following code, which executes the webrequest in a non-coroutine method.
private void UpdateVersion(string message)
{
string post_url = NetworkManager.baseUrl + "VersionUpdate.php";
WWWForm form = new WWWForm();
form.AddField("Message", message);
form.AddField("Version", Application.version);
UnityWebRequest www = UnityWebRequest.Post(post_url, form);
www.chunkedTransfer = false;
www.SendWebRequest();
while (!www.isDone)
{
// do nothing
}
if(www.error == null){
Debug.Log(www.downloadHandler.text);
} else {
Debug.Log("error!: " + www.error);
}
}

Asynchronous coroutine handling in unity

I have used a coroutine to do a backend service call to retrieve the player categories in my category.cs file:
public override void OnEnter(Page p)
{
backend = globalScriptObject.GetComponent<IBackendController>();
items.Clear ();
StartCoroutine (backend.GetPlayerProfile ( profile =>{
this.maxSelectableItems = Mathf.CeilToInt(profile.level/10+1);
if(this.maxSelectableItems == 7) maxSelectableItems = int.MaxValue;
DisableSelections();
}));
GetPlayerProfile (In a different class which has been called using instance backend of that class)
public IEnumerator GetPlayerProfile(System.Action<Profile> callback){
yield return GetPlayerProfile (callback, false);
}
Issue:
Since i am using an external service call,sometimes the player profile is uploaded with a delay.
I need to make sure that the startcoroutine is finished with result before the rest of the lines of code is executed.
I tried creating the following class after searching from the internet which can make sure the couroutine call is finished before the rest of the lines are executed:
{
StartCoroutine(FinishFirst(5.0f, DoLast));
}
IEnumerator FinishFirst(float waitTime, Action doLast) {
print("in FinishFirst");
yield return new WaitForSeconds(waitTime);
print("leave FinishFirst");
doLast();
}
void DoLast() {
print("do after everything is finished");
print("done");
}
But how can i use the above in my source code is what i would need suggestions from the community.
Also can i do something like yield return waitForSec(Float) in the GetPlayerProfile method?
Thanks !!
Try using WaitUntil.
https://docs.unity3d.com/ScriptReference/WaitUntil.html
Something like this:
IEnumerator GetProfile(){
var profile = null;
yield GetPlayerProfile((p) => {profile = p});
yield WaitUntil(p != null);
this.maxSelectableItems = Mathf.CeilToInt(profile.level/10+1);
if(this.maxSelectableItems == 7) maxSelectableItems = int.MaxValue;
DisableSelections();
}
And then...
StartCoroutine(GetProfile);

StartCoroutine (with WWW) does not work on Android but it does on the editor - Unity

I am working on an application for my web service. I work with LitJson, I finished the application but at the moment of exporting it to test it in my android does not work related to WWW IEnumerators.
For example, a button that starts the session, only the function that calls the IEnumerator works, but the IEnumerator itself does not work, and I have checked it by placing an alert message that it creates for the application.
This is the function that the button calls:
public void LogIn() {
UserName = GameObject.Find("inputUsuario").transform.GetChild(2).gameObject.GetComponent < Text > ().text;
Password = GameObject.Find("inputPassword").transform.GetChild(2).gameObject.GetComponent < Text > ().text;
Debug.Log("Username:" + UserName + "And Password:" + Password);
StartCoroutine(LogInWWW());
}
And this is the IEnumerator:
public IEnumerator LogInWWW() {
WWW www = new WWW(UrlLogin + "?userName=" + UserName + "&password=" + Password);
yield return www;
print(www.text);
if (www.error == null) {
ProcessjsonLogin(www.text);
} else {
Debug.Log("ERROR: " + www.error);
}
}
I must add that there is no error in the debug console on Android.
Also I must clarify that to the URL I have added the prefix "http://" since it is a solution that give in the questions that I have seen.
Well guys, sometimes the errors are rare but in short, I managed to get to the error thanks to "trial and error", the problem was that I tried to get the value of UserName and Password using GetChild, like the following code:
`Password = GameObject.Find("inputPassword").transform.GetChild(2).gameObject.GetComponent<Text>().text;`
For some reason on Android the object does not exist, I learned this because I was testing until part of the code I got the problem. Then I decided to change the code to find the text in a more specific way, changing the text object by inputUserTextObj, the same with the Password object and changing the code by:
UserName = GameObject.Find("inputUsuarioTextObj").gameObject.GetComponent<Text>().text;
Password = GameObject.Find("inputPasswordTextObj").gameObject.GetComponent<Text>().text;
As I said, I knew that the problem was not the IEnumerator, but it seems too strange that Debugging did not show me any error since it was a typical error of "GameObject is Null" and I could even swear to them by my life that Debug the application and I never showed the said error
But hey, thank you very much for your time guys, really feel the support and forgive me for taking your time.
When you instantiate a new WWW(strung Url) it implicitly starts the request as well but it is not sync operation, it is async so you have to check www.isDone before you can use www.text. I think it works on Unity Editor properly because it just has a faster connection.
public IEnumerator Request(){
using (var testRequest = new WWW(#"URL")) {
var totalWaited = 0;
var timeOuted = false;
while (testRequest.isDone == false) {
yield return new WaitForSeconds(1);
totalWaited++;
if (totalWaited > timeOutInSeconds) {
timeOuted = true;
}
}
if (timeOuted) { Debug.LogError("TimeOut"); yield break; }
yield return testRequest.text;
}

GetComponent isn't working with Unity 5.2

I'm trying to follow along to this tutorial http://wiki.unity3d.com/index.php?title=Server_Side_Highscores
But it hasn't been updated to Unity 5.2 and I can't get the GetComponent to work no matter what I try.
IEnumerator GetScores()
{
GameObject text = new GameObject ("Loading Scores");
text.GetComponent<GUIText>();
WWW hs_get = new WWW(highscoreURL);
yield return hs_get;
if (hs_get.error != null)
{
print("There was an error getting the high score: " + hs_get.error);
}
else
{
GetComponent<GUIText>(hs_get.text); //Line of code not working
// this is a GUIText that will display the scores in game.
}
}
The error is: Assets/HSController.cs(46,25): error CS0308: The non-generic method `UnityEngine.Component.GetComponent(System.Type)' cannot be used with the type arguments
I can't seem to get GetComponent working any help would be greatly appreciated
Have you tried
text.text = hs_get.text;
I'm not entirely sure what your code is supposed to do, but I don't know why you're using GetComponent. If you don't want to reuse the "text" variable, then you could maybe try something like
hsText = GetComponent <GUIText> ();
hsText.text = hs_get.text;
I don't know if I'm addressing the problem but I hope this helps!

Categories