Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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
0
Question by PandawanFr · May 07, 2015 at 03:35 AM · c#pausewaitforsecondswait

Pause a script completely

Hello,

I have a small modding system and want to make a wait option in it. First, let me explain how the modding system works. I get the lines from a txt file, separate them into words, then test for a certain word using an if statement and do the action.

My problem is that I made it so that when I have a keyword wait, it will set a bool to false and will let other lines pass. This bool is also set automatically to true before a wait, it will go to false only when using wait, and after a WaitForSeconds, it will go back to true and let the commands/lines pass. The thing is that when it's waiting with WaitForSeconds, the script lets the next lines pass, and the next line sees that the bool is set to false, so it will not activate, so I lose that line.

Here is the bit of the code: bool ready;

 void Start () {
 ready = true;
 }
 
 (...)
 if (param[0] == "wait") { //The first word of the line/command 
 ready = false;
 StartCoroutine(float.Parse(param[1]));
 }
 if (ready == true) {
 (...)
 }
 
 IEnumerator Wait (float amount) {
 yield return new WaitForSeconds(amount);
 ready = true;
 }

Note this code may be wrong because I had to make it again (I removed the original part as it wasn't working.)

Thank you!

Comment
Add comment
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

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Catlard · May 07, 2015 at 05:22 AM

I believe the problem is your perception of how coroutines (and the command StartCoroutine) works. Basically, Startcoroutines happen, and then it runs the code immediately afterward, in a seperate thread. If you want the stuff in a coroutine to happen first, and for the game to "wait" for that to be over, you need to use

 print("a!");
 yield return StartCoroutine(yourWaitingFunctionName);
 print("b!");

This will only print b after your coroutine is over. HOWEVER, this said, you cannot yield return like this unless you're already in a coroutine. So your calling function must also be an ienumerator. Does that make sense?

Comment
Add comment · Show 8 · 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 PandawanFr · May 07, 2015 at 08:12 PM 0
Share

I understand but I want to keep my basic code to be in the normal method, I don't want to move it in the coroutine as this wait system is only called if the user wants it to happen. But I still want the other stuff to happen if there is no param wait.

Here is an example:

 if (param[0] == "wait") { //The first word of the line/command 
  ready = false;
  StartCoroutine(float.Parse(param[1]));
  }
  if (ready == true) {
 if (param[0] == test) {
 Debug.Log("Test");
 }
 }


The thing is that I still want the test to happen if param[0] has test. So basically it's kind of a command system but with multiple commands. I have the command test and the command wait.

If I do wait and then test, it would wait before doing test. But If I do test, it would immediately do test.

I hope you understand what I mean

avatar image Catlard · May 08, 2015 at 01:25 AM 0
Share

I think you're saying you don't want to yield return coroutine in the middle of the function -- so that means you should set a flag wherever it happens, and then at the end of the function yield return the coroutine (if the flag is true? Like this:

     public IEnumerator CheckForPause(string[] parameters) {
         bool isShouldPause = DoSomeChecks (parameters);
         if (isShouldPause) {
             yield return StartCoroutine ("Wait");
         } else {
             yield return 0; //we have to wait at least once in a coroutine -- this waits one frame.
         }
     }
 
     public bool DoSomeChecks(string[] parameters) {
         bool isShouldPauseLater = false;
         foreach (string s in parameters) {
             if(s=="wait") {
                 isShouldPauseLater = true;
             }
         }
         return isShouldPauseLater;
     }

avatar image PandawanFr · May 08, 2015 at 11:11 PM 0
Share

Thing is that I don't know if it'll work because I am sending each line separately as an array from another script.

Basically I have a script Load$$anonymous$$od.cs which basically takes a txt file, parses it into lines and puts them in an array. Then in this script (the $$anonymous$$od script) I separate each line using a while loop and then send each separately to the method which I showed previously. This method will get the line, separate it into words and put them in the array param[].

I then check if param[0] which is the first word is equal to wait or test, and then I do my thing. So I don't really know if your code would work.

Also If it works, which function should I call? And from where?

avatar image Catlard · May 09, 2015 at 01:01 AM 0
Share

I'm not sure exactly what you're saying, but I think you're saying that you can't do any waiting until after all the mod information has been received by all the objects in your scene. So, you have three phases: before the commands have been received, the reception of all the commands, and then the time after the commands are received (which is also when you, personally, want to wait). If this is true, then you can just use a flag like isShouldPauseLater in the code above. Write your code so that nothing is affected by this flag until you've reached the third phase. Then allow your objects to wait -- perhaps you'll need to also send some information, like "pause time amount", to each object that your code pauses.

I should be clear -- none of the code that I wrote is meant to fit directly into your code. It's just an example of how some things work -- how I often do these sorts of things -- so you can use those ideas in your code.

avatar image PandawanFr · May 09, 2015 at 01:07 AM 0
Share

Could i possibly (ins$$anonymous$$d of making all that) disable the object that has the mod script?

So that when there is Wait(), it would first send to another script, in that other script, disable the normal script, do a waitforseconds, then re-enable it? Or would I loose all the params?

Show more comments
avatar image
0

Answer by Bunny83 · May 08, 2015 at 01:40 AM

I think you haven't understood what a coroutine actually is or how it works ^^. If you don't yield in a coroutine it will run through your code like a normal function. However you have the option to wait for certain things conditionally. Example:

 IEnumerator Start()
 {
     // Do your loading
     while (not done with the file)
     {
         // parse your params from the current "command"
         // [...]
         
         if (param[0] == "wait") {
             yield return new WaitForSeconds(float.Parse(param[1]));
         }
         else if(param[0] == "someOtherAwesomeCommand"){
             Debug.Log("Execute someOtherAwesomeCommand");
         }
         // [...]
     }
 }


If there's no "wait" command in the file it will just rush through your file without any delay and will finish even before the first Update is called. However if a wait command is encountered it will stop executing for the given time and then continue with the next command.

Comment
Add comment · Show 5 · 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 PandawanFr · May 08, 2015 at 11:05 PM 0
Share

That would not work.

Let's say my script is called $$anonymous$$od.cs ok, so I use another script called Load$$anonymous$$od.cs that basically sends each line separately to $$anonymous$$od.cs like that $$anonymous$$od(line[1]);

So when there is wait, I basically want it to stop the script completely. Which I'm not sure will work, but it won't with yours because when there is wait, it will just stop the instance of that script as there is nothing else to do. There is only wait in that line.

So it'll send the next line and not care about the wait.

avatar image Bunny83 · May 09, 2015 at 12:18 AM 0
Share

@$$anonymous$$ig35700:
What doesn't work is your approach. It's absolutely impossible with your setup. period. If you iterate through all lines in your Load$$anonymous$$od script with an ordinary loop you can't "wait" in that loop.

Well you could use `System.Threading.Thread.Sleep()` but it will freeze your whole application for the time specified. Unity only runs in a single thread (at least the whole scripting environment). So while an ordinary method is executing nothing (absolutely nothing) can happen in between until the method is finished. Only coroutines allow you to cooperatively have chunks of code see$$anonymous$$gly run in parallel.

If you have your loop in Start without a coroutine that means the game doesn't even start before your Start method is done. No visuals will be rendered and no Update will run.

What's the point of having another script loading the lines of the file? The parsing of the file should be handled in one place.

avatar image PandawanFr · May 09, 2015 at 12:24 AM 0
Share

Hey, no need to be so mad...

The thing is that I am parsing in the $$anonymous$$od.cs and Sending the lines to parse in Load$$anonymous$$od.cs

Now, Catlard may be on something, so let's not say that something is impossible or anything, NOTHING IS I$$anonymous$$POSSIBL$$anonymous$$

avatar image Bunny83 · May 09, 2015 at 04:23 AM 0
Share

@$$anonymous$$ig35700:
At which point i appear "mad"? o.O
I just made sure that with your current setup (at least the way you presented it) it's impossible. Sure nothing is impossible but you have to change something. The best "start" to solve your problem is to actually post the code where and how you actually process the text file. You only posted fragments of code which could be inside anything. If you don't process it either in a coroutine or in Update you can't "wait".

avatar image PandawanFr · May 09, 2015 at 02:43 PM 0
Share

O$$anonymous$$, I'll post the file in another comment

avatar image
0

Answer by PandawanFr · May 11, 2015 at 08:16 AM

Ok, for clarification, here's my LoadMod.cs

 using UnityEngine;
 using System.Collections;
 using System.Xml;
 using System;
 using System.IO;
 
 public class LoadMod : MonoBehaviour {
     //This script loads all mods that are found in A Game/mods
 
     string path; //Path to app
     public string[] files;
     ModParser parser;
 
     void Start () {
         parser = this.GetComponent<ModParser>();
         //Setup mods folder in app
         path = Application.dataPath;
 
         //If there is no mods directory, make one
         if (!Directory.Exists(path+"/mods")) {
             Directory.CreateDirectory(path+"/mods");
             
         }
         Load();
     } 
 
     public void Load() {
 
         //Set all mods files in one array
         files = Directory.GetFiles(path + "/mods", "*.txt");
         Debug.Log ("Mods Installed:");
 
         for (int i = 0; i < files.Length; i++){
             string file = files[i];
             GetComponent<ModParser>().x = files.Length;
             //Debug.Log (file); //Debugs all mods
 
             string[] lines = System.IO.File.ReadAllLines(file);
             parser.Parse(lines);
         }
             
     }
 }

Then there is ModParser.cs (which I renamed, it used to be Mod.cs). It's a simplified version as there are more if statements for param[0] but they would make this post too big

 using UnityEngine;
 using System.Collections;
 using UnityStandardAssets.Characters.FirstPerson;
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine.UI;
 
 public class ModParser : MonoBehaviour
 {
     //This script takes the strings (mods) from LoadMod and translates them into a Unity based system.
     //This is basically the odding system itself, LoadMod is just to load the mods, this script makes all the processing and modding
 
     public int x = 0; // Used for information
     bool ready;
 
     //This will translate the string into the unity system
     public void Parse (string[] modLines)
     {
 
         int i = 0;
         lineNumber = 1;
         while (i < modLines.Length) {//Makes each line a unique string
             Use (modLines [i]);
             lineNumber++;
             i++;
         }
     }
 
     public void Use (string modLine){
 
         string[] param = modLine.Split (" " [0]);
 
      if (param[0] == "wait") {
           ready = false;
           StartCoroutine(Wait(float.Parse(param[1])));
      }
 
      if (param [0] == "display" && ready == true) { //Display text in chat or title
 
          if (param [1] == "chat") {
                 string finalOutput = "";
                 int i = 0;
                 while (i < param.Length) {
                     if (i != 0 && i != 1) {
                         finalOutput = finalOutput + " " + param [i];
                     }
                     i++;
                 }
                 GameObject.FindGameObjectWithTag ("Player").GetComponent<Commands> ().output = finalOutput; //Commands is basically the Chat script, output is the text that appears in the chat
             }else {
                 Error (1);
             }
                }
         else {
             Error (1);//This will send an error from another method
         }
 
     }
 
 
      IEnumerator Wait (float time) {
           yield return new WaitForSeconds(time);
           ready = true;
      }
 }
 

Comment
Add comment · Show 2 · 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 PandawanFr · May 09, 2015 at 04:23 PM 0
Share

The problem is that after a wait, it will see that ready is still equal to false, so it will not activate and go to the next line. If when going to the next line it's still not done (still not ready = true) then it will go to the next...

avatar image PandawanFr · May 16, 2015 at 03:48 AM 0
Share

Because no one seems to want to help, I'm just going to remove this thread.

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.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Make enemy wait before attacking player 2 Answers

Problem getting AI to wait 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Cant Make C# Use waitforseconds Command 3 Answers


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