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 /
This question was closed Jul 01, 2015 at 10:17 PM by meat5000 for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by ErvinGamez · Jul 01, 2015 at 01:54 AM · javascriptupdatewaitforseconds

WaitForSeconds in Update() function

Hello, I've been trying to make a script which makes the object "wander around" and stop for 5 seconds. After that, he wanders around again. But I'm getting an error saying:

"Update() can not be a coroutine."

This is my script so far:

 var NPC : GameObject;
 var Speed = 50;
 var Range = 10;
 var VectorRandom : Vector3;
  
 function Update() {
     NPC.transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime;
     if((NPC.transform.position - VectorRandom).magnitude < 3) {    
     yield WaitForSeconds(5.0);
     Start();
     }
 }
 
 function Start() {
     VectorRandom =  Vector3(Random.Range(NPC.transform.position.x - Range, NPC.transform.position.x + Range), 1, Random.Range(NPC.transform.position.z - Range, NPC.transform.position.z + Range));
     VectorRandom.y = 1;
     NPC.transform.LookAt(VectorRandom);
  }

I know this is because Update keeps looping it, so wait won't work. I've tried everything to fix it, but nothing works.

Thank you.

Comment
Add comment · Show 1
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 Carve_Online · Jul 01, 2015 at 06:50 AM 0
Share

Yeah, definitely the first thing you want to do is rename your Start function to something else.

4 Replies

  • Sort: 
avatar image
4
Best Answer

Answer by fafase · Jul 01, 2015 at 08:23 AM

 private var timer:float = 0.0f;
 public var waitingTime : float = 5.0f;
 function Update() {
      NPC.transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime;
      if((NPC.transform.position - VectorRandom).magnitude < 3) {    
          timer += Time.deltaTime;
          if(timer > waitingTime) {
                 timer = 0f;
                 Reset();
          }
      }
  }

  function Reset() {
      VectorRandom =  Vector3(Random.Range(NPC.transform.position.x - Range, NPC.transform.position.x + Range), 1, Random.Range(NPC.transform.position.z - Range, NPC.transform.position.z + Range));
      NPC.transform.LookAt(VectorRandom);
   }

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 ErvinGamez · Jul 01, 2015 at 10:15 PM 0
Share

After a bit of tweaking, this worked! Thank you!

avatar image HMahmoud · Apr 10, 2018 at 09:42 PM 0
Share

Thank you very much that helped me a lot.

 timer += Time.deltaTime;
           if(timer > waitingTime) {
                  timer = 0f;
                  DoThis();
           }

i was trying for ages to get the same effect with a very complicated code but yours is so simple.

avatar image
0

Answer by GiyomuGames · Jul 01, 2015 at 02:32 AM

You a need separate function and probably a boolean or something. Sorry I don't have Unity nor Visual Studio now, also I code in C#, but the idea would be:

 bool wanderingAround;
 
 function WanderAround {
       while (true)
       {
           wanderingAround = true;
           yield WaitForSeconds(5.0); // assuming you want it to wander for 5 seconds
           wanderingAround = false;
           yield WaitForSeconds(5.0);
       }

Then you just do "yield StartCoroutine("WanderAround");" in your Start function and use the boolean "wanderingAround" in your Update function to know whether the object is supposed to be wandering or not.

By the way calling your Start function in Update is really not normal. Start is called automatically when the object is instantiated and should never be called directly. You should probably follow a couple tutorials before moving further.

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 meat5000 ♦ · Jul 01, 2015 at 07:11 AM 0
Share

should never be called directly

It is perfectly acceptable to manually invoke Start() and there are times when you need to.

For example when you disable and re-enable a gameobject, Start will not run on re-enable so will often need to be invoked manually.

But yes, perfor$$anonymous$$g this action in Update() is highly unusual.

avatar image GiyomuGames · Jul 01, 2015 at 07:15 AM 0
Share

True! I simplified it to avoid confusing him/her for now. S/he seems to just be starting so s/he should remember that calling Start in the Update method = bad idea.

avatar image ErvinGamez · Jul 01, 2015 at 07:21 AM 0
Share

I know this won't work, because I need the if statement to keep checking. If it does it every 5 seconds, it just won't work, it'll only work if it does it every tick.

avatar image GiyomuGames · Jul 01, 2015 at 07:30 AM 0
Share

I yeah I missed that point. I think below is the skeleton of what you are trying to do: (not sure if it compiles, I don't know much about Javascript)

 var NPC : GameObject;
  var Speed = 50;
  var Range = 10;
  var VectorRandom : Vector3;
  var stop = false;
   
  function Update() {
      NPC.transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime;
      if((NPC.transform.position - VectorRandom).magnitude < 3) {    
            StartCoroutine("Stop");
      }
 
      if (!stop)
            $$anonymous$$ove();
      
  }
 
  function Stop() {
      stop = true;
      yield WaitForSeconds(5.0);
      stop = false;
 }
 
  
  function $$anonymous$$ove() {
      VectorRandom =  Vector3(Random.Range(NPC.transform.position.x - Range, NPC.transform.position.x + Range), 1, Random.Range(NPC.transform.position.z - Range, NPC.transform.position.z + Range));
      VectorRandom.y = 1;
      NPC.transform.LookAt(VectorRandom);
   }
avatar image fafase · Jul 01, 2015 at 08:47 AM 1
Share

You change the code, now it works. As it was when I posted, it would not work.

Show more comments
avatar image
0

Answer by raja1250 · Jul 01, 2015 at 07:49 AM

use a seperate coroutine for delay of 5 min and call it in update function.

IEnumerator delay() { yield return new WaitForSeconds(5); } in the update function

StartCoroutine(delay());

Comment
Add comment · 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 meat5000 ♦ · Jul 01, 2015 at 07:57 AM 0
Share

You answer looks like total nonsense simply because you havent laid it out very well :D

As a result it appears that you are proposing to put that IEnumerator function inside Update.

I read it again and I see its not the case. Just thought Id let you know.

avatar image
0

Answer by Ibzy · Jul 01, 2015 at 08:13 AM

You could create a coroutine with an infinite for loop that you call on Start() rather than checking every frame in Update():

 Start(){
     StartCoroutine(Wander());
 }
 
 IEnumerator Wander(){
     for(;;){
         VectorRandom =  Vector3(Random.Range(NPC.transform.position.x - Range, NPC.transform.position.x + Range), 1, Random.Range(NPC.transform.position.z - Range, NPC.transform.position.z + Range));
         VectorRandom.y = 1;
         NPC.transform.LookAt(VectorRandom);
         yield return new WaitForSeconds(5);
     }
 }


Edit: Didn't see the comment about having to check for the magnitude on every tick. The below will do the check on Update, but put the yield in the coroutine:

 var NPC : GameObject;
  var Speed = 50;
  var Range = 10;
  var VectorRandom : Vector3;
  var Wandering = false : Boolean;
   
  function Update() {
      NPC.transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime;
      if((NPC.transform.position - VectorRandom).magnitude < 3 && !Wandering) {    
          Wandering = true;
          StartCoroutine(Wander());
      }
  }
  
  IEnumerator Wander() {
      yield WaitForSeconds(5.0);
      VectorRandom =  Vector3(Random.Range(NPC.transform.position.x - Range, NPC.transform.position.x + Range), 1, Random.Range(NPC.transform.position.z - Range, NPC.transform.position.z + Range));
      VectorRandom.y = 1;
      NPC.transform.LookAt(VectorRandom);
      Wandering = false;
  }
Comment
Add comment · Show 7 · 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 GiyomuGames · Jul 01, 2015 at 08:35 AM 0
Share

Be careful, with this code you'll call the subroutine Wander for each update when (NPC.transform.position - VectorRandom).magnitude < 3. Therefore is will be called many times in a row whereas you only want to call it once.

avatar image Ibzy · Jul 01, 2015 at 08:42 AM 0
Share

Very good point - I have edited the code to include a bool.

avatar image GiyomuGames · Jul 01, 2015 at 08:46 AM 1
Share

Sweet :) I would personally put "Wandering = true;" at the beginning of Wander() just to make it more readable and robust.

avatar image ErvinGamez · Jul 01, 2015 at 03:19 PM 0
Share

This is close to working, but it doesn't because IEnumerator is (I think) a C# command ins$$anonymous$$d of JS.

avatar image Ibzy · Jul 01, 2015 at 03:22 PM 0
Share

For JS simply replace IEnumerator with function.

Show more comments

Follow this Question

Answers Answers and Comments

7 People are following this question.

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

Related Questions

How to make Update wait for AI Decision? 1 Answer

reload script continues adding the reload amount 1 Answer

Why isn't my flashing script working? 1 Answer

Javascript Class Update 2 Answers

Prefab Instantiation 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