• 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 gdennis · Dec 29, 2014 at 03:09 PM · transformcoroutinelerpstaticienumerator

Static Coroutine being called endlessly

So I needed a StartCoroutine in a static method, however since this is not possible I stumbled across a StaticCoroutine script (found here: http://benbeagley.com/2013/10/14/calling-a-static-ienumerator-in-unity/, original credits to user @whydoidoit).

The function I need to call makes the character turn towards another character he just walked to. It is being called like this in my static IEnumerator method:

 public static IEnumerator doWalkingAction() {
         if (subject._noun == "player") {
             setWalkerScript(playerObj);
             if (npcNames.Contains(direct._noun.ToLower())) {
                 startMovingToNPC(direct._noun.ToLower());
                 bool walkingNotDone = true;
                 while (walkingNotDone) {
                     if (playerObj.GetComponent<AgentWalker>().arrivedOrNot()) {
                         npcObj = GameObject.Find(direct._noun.ToLower());
                         StaticCoroutine.DoCoroutine(turnToFaceSmoothly(playerObj.transform, npcObj.transform));
                         playerObj.GetComponent<Animation>().animation.Play("idle");
                         Destroy(playerObj.GetComponent("AgentWalker"));
                         walkingNotDone = false;
                     } else {
                         yield return new WaitForSeconds(0.5f);
                     }
                 }
                 yield return null;
             }
         } else {
             
         }
     }


And the code of 'turnToFaceSmoothly' looks like this:

 public static IEnumerator turnToFaceSmoothly (Transform targetThatWalks, Transform targetToLookAt) {
 while (Vector3.Dot (targetThatWalks.forward, (targetToLookAt.position - targetThatWalks.position).normalized) < 0.95f) {
     Vector3 dir = targetToLookAt.position - targetThatWalks.position;
     targetThatWalks.rotation = Quaternion.Slerp(targetThatWalks.rotation, Quaternion.LookRotation(dir), 5f * Time.smoothDeltaTime);
     targetThatWalks.eulerAngles = new Vector3(0f, targetThatWalks.eulerAngles.y, 0f);
 
     yield return null;
     }
 }


When running my game, I noticed that this turnToFaceSmoothly method gets called non-stop, giving of course a very undesirable result!

Why does it do this? Thank you in advance for anyone who can help

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 Xtro · Dec 29, 2014 at 04:28 PM 2
Share

Where do you start the coroutine? I mean, where do you call the StaticCoroutine.DoCoroutine method? Please copy/paste the entire block instead of 1 line.

avatar image gdennis · Dec 29, 2014 at 05:00 PM 0
Share

@Xtro thank you for commenting! I edited my question including the complete method with the method call!

2 Replies

· Add your reply
  • Sort: 
avatar image

Answer by Xtro · Dec 29, 2014 at 05:07 PM

You are starting the coroutine in another coroutine named doWalkingAction. Maybe, doWalkingAction is being started multiple times. Pls make sure it's not started constantly like in an update event. Please copy/paste where you start doWalkingAction coroutine.

Comment

People who like this

0 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 gdennis · Dec 29, 2014 at 05:13 PM 0
Share

@Xtro I am starting this coroutine in a coroutine yes! Is this a problem? I am quite confident that doWalkingAction is not started multiple times since my Start() calls a method, which calls a method, which calls ... -> eventually we get in this method where the doWalkingAction gets called, it is here:

 public IEnumerator animateExpr(GameMove gm) {
         passive = gm._interpr._passive;
         if (passive) {
             
         } else {
             subject = gm._interpr._subject;
             verb = gm._interpr._predicate._verb;
             direct = gm._interpr._predicate._direct;
             indirect = gm._interpr._predicate._indirect;
         }
 
         //Animation part
         StoryFlowAction.setInterpretations (passive, subject, verb, direct, indirect, npcNames, textSynonyms, mailSynonyms);
         switch (verb) {
             case "goes-to":
             case "walks-to":
                 yield return StartCoroutine (StoryFlowAction.doWalkingAction());
                 break;
             case "talks-to":
                 
                 break;
             case "says-to":
                 
                 break;
             case "says":
                 
                 break;
             case "says to":
                 yield return StartCoroutine (StoryFlowAction.doTalkingToAction());
                 break;    
             case "texts to":
 
                 yield return StartCoroutine (StoryFlowAction.doMessageNowAction("text"));
                 break;
             case "sends to":
 
                 break;
             case "emails to":
                 
                 yield return StartCoroutine (StoryFlowAction.doMessageNowAction("email"));
                 break;
             case "gives to":
                 
                 yield return StartCoroutine (StoryFlowAction.doGiveTo());
                 break;
             case "picks-up":
             case "grabs":
                 
                 yield return StartCoroutine (StoryFlowAction.doPickupNowAction());
                 break;
             case "receives from":
                 
                 
                 yield return StartCoroutine (StoryFlowAction.doMessageReceivedFromAction());
                 break;
         }
         yield return null;
     }


A lot of Debug's in between my code also shows me that it definitely not called multiple times!

avatar image Xtro · Dec 29, 2014 at 05:19 PM 0
Share

Coroutine in coroutine is not a problem. I see that you set walkingNotDone to false so your while loop should break. With this info, I can't see any problem :(

avatar image gdennis · Dec 29, 2014 at 05:25 PM 0
Share

@Xtro , thank you nontheless for looking at the problem!

Do you think it might be a problem with the StartCoroutine script? It is literally a copy and paste from http://benbeagley.com/2013/10/14/calling-a-static-ienumerator-in-unity/. Maybe it has something to do with how this one handles stuff? Yield return null?

avatar image Xtro · Dec 29, 2014 at 05:32 PM 0
Share

This 3rd party script is fine. It's just starting your static coroutine on its own gameobject because coroutines can only live on gameobjects.

If your project is small, I can look at it if you send me a zip file. If the project is big, maybe you can create an empty project and copy the required scripts in it to see if it has the same behavior.

P.S. : If you decide to send me the project, 1) enable meta files in editor settings. 2) only zip the "assets" and "project settings" folders, Not anything else. This is how you share with others If you didn't do it before.

avatar image gdennis · Dec 29, 2014 at 05:47 PM 0
Share

Thank you for your help Xtro! I will find an alternative.

avatar image

Answer by Nostrum Key · Dec 30, 2014 at 08:07 PM

Oh hey, thanks for checking out my blog. I will admit that post is a little old and honestly I try not to make static co-routines unless I really have to because, as you see here, it can get messy.

I think I can see the issue. You keep calling the static co-routine turnToFaceSmoothly while (walkingNotDone). turnToFaceSmoothly has its own contained while loop so calling it continually is going to cause issues.

Instead, try turning turnToFaceSmoothly into a static void method and turn the while loop into an if statement e.g.

 public static void turnToFaceSmoothly (Transform targetThatWalks, Transform targetToLookAt) 
 {
    if(Vector3.Dot (targetThatWalks.forward, (targetToLookAt.position - targetThatWalks.position).normalized) < 0.95f)
    {
       //code...
    }
 }

You also need a yield return (null or otherwise) contained in all your co-routine while loops that you want to run simultaneously with your other code. Simply, yield return allows the co-routine to wait until a target frame to continue running e.g. yield return null waits for the next frame. If you don't include it then the while loop will run and try to complete all in the same frame.

I hope I've been of some help. And thanks again for using my blog =D

Comment

People who like this

0 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 Xtro · Dec 30, 2014 at 08:10 PM 0
Share

He sets walkingNotDone to false in the first encounter so while loop breaks. It doesn't look like starting the coroutine repeatedly.

avatar image gdennis · Dec 30, 2014 at 10:22 PM 1
Share

Thanks guys! I kinda figured out my code probably was not the best, so I rewrote a huge portion of it and it is working fine. This part of the code remained the same and works now, so I guess somewhere else something weird happened!Thanks a lot for helping me out Xtro! @Nostrum Key nice blog :-)

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Why is this coroutine only firing once? 3 Answers

Lerp not working inside Coroutine. 1 Answer

bounce player back to position while jumping 0 Answers

Scale with coroutine and lerp 1 Answer

How to move along a group of waypoints at a certain speed? 2 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