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 Cunnah · Nov 25, 2014 at 02:11 PM · coroutine

Coroutine does nothing sometimes.

This is really odd. I have a Coroutine that Tessellates a plane for the purpose of LOD creation. Initially it was a function that worked pretty well on its own but as I added more components to my game I needed it to not hog the CPU. I set it as a Coroutine so that it would calculate a number of vertices and triangles before waiting for the next frame. It works well except every now and again it reaches a level of Tesselation and doesn't do anything until it is called again at which point it resumes working.

E.g. I have a key that cycles through LODs, it goes from low to high detail. I press it once and it goes to the next level of tessellation I press it again and it works, I press it again and nothing happens, I press it one more time and it goes to the next level of tessellation as if I hadn't pressed the key previously.

 IEnumerator Tessalate (int n){
 
         for (int i = 0; i < n; i ++) {
         
             int cycle = 0;
 
             int count = triangles.Count;
             List<TriangleIndices> tempTris = new List<TriangleIndices>();
 
             for (int u = 0; u < count; u ++){
 
                 cycle ++;
 
                 if (cycle > 50){
                     cycle = 0;
                     yield return new WaitForEndOfFrame();
                 }
 
                 int v = verts.Count;
                 TriangleIndices t = triangles[u];
 
                 Vector3 point1 = verts[t.v1];
                 Vector3 point2 = verts[t.v2];
                 Vector3 point3 = verts[t.v3];
 
                 Vector3 point1a = MeshTools.getMidPoint(point1,point2);
                 Vector3 point2a = MeshTools.getMidPoint(point2,point3);
                 Vector3 point3a = MeshTools.getMidPoint(point3,point1);
 
                 point1a = MeshTools.putOnSphere(point1a,seed);
                 point2a = MeshTools.putOnSphere(point2a,seed);
                 point3a = MeshTools.putOnSphere(point3a,seed);
 
                 TriangleIndices t1 = new TriangleIndices(t.v1,v,v+1);
 
                 verts.Add(point1a);
                 verts.Add(point3a);
 
                 v = verts.Count;
 
                 TriangleIndices t2 = new TriangleIndices(t.v2,v,v+1);
                 
                 verts.Add(point2a);
                 verts.Add(point1a);
 
                 v = verts.Count;
 
                 TriangleIndices t3 = new TriangleIndices(t.v3,v,v+1);
                 
                 verts.Add(point3a);
                 verts.Add(point2a);
                 
                 v = verts.Count;
 
                 TriangleIndices t4 = new TriangleIndices(v,v+1,v+2);
 
                 verts.Add(point1a);
                 verts.Add(point2a);
                 verts.Add(point3a);
 
                 tempTris.Add(t1);tempTris.Add(t2);tempTris.Add(t3);tempTris.Add(t4);
             }
 
             triangles = tempTris;
 
         }
 
     }

  

Where it fails in the sequence varies if I change how many cycles it must go through before yielding.

Any ideas?

Comment
Add comment · Show 3
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 Cunnah · Nov 25, 2014 at 01:48 PM 0
Share

Forgot to say at no point is the object destroyed or deactivated. The code for the key press for debug purposes is in the same script as this.

Also the cycle number is higher than I originally intended it; I altered it to see the effect on the bug.

avatar image troien · Nov 25, 2014 at 02:32 PM 0
Share

Is there a particular reason why you use 'yield return new WaitForEndOfFrame()' ins$$anonymous$$d of 'yield return null' (Wait for next frame) I don't think it has any impact on your problem, but you might give it a try...

Also I suppose that you don't get any errors? (Because errors inside a coroutine ter$$anonymous$$ates them)

And how/when/where do you call the StartCoroutine?

avatar image Cunnah · Nov 25, 2014 at 03:09 PM 0
Share

I have tried to debug the problem myself, the WaitForEndOfFrame() is there because originally it was null and I wanted to be sure that it wasn't some weirdness with that.

I think I have spotted the problem. Will post as an answer if it's true.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Cunnah · Nov 25, 2014 at 03:37 PM

Solved!

Just in case anyone else has this kind of weirdness ensure that no other functions are reliant on your Coroutine otherwise it will execute without any input from the Coroutine. For example.

     void Update(){
 
 
         if (Input.GetKeyUp(KeyCode.T)) {
 
             StartCoroutine(Tessalate(1));
             CompileMesh();
         }
     }

 

The co-routine uses a temporary list for all new vertices and doesn't update the master list until it is finished. Funnily enough trying to compile before the Coroutine is finished will just end up using the old master file!

EDIT: sorry this was more an example of what not to do and an explanation why. I have moved CompileMesh() to the end of the Coroutine the correct code looks like this;

 void Update(){
 
         if (Input.GetKeyUp(KeyCode.T) {
             
                         StartCoroutine(Tessalate(1));
             
         }
     }

 

with the CompileMesh() at the end of the Coroutine.

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 Bunny83 · Nov 25, 2014 at 06:14 PM 0
Share

Uhm, this doesn't really answer your question. It just shows your wrong code. This code should be part of your question and not part of an answer. The answer should show correct code.

StartCoroutine returns at the first yield, so your Compile$$anonymous$$esh method will be executed before the coroutine is finished. To solve this you usually do everything in one coroutine or you use a callback which is called from the coroutine when done.

btw: Some time ago i made some helpers to subdivide a mesh. It seems you're not taking care of normals / colors / uvs / ...

avatar image Cunnah · Nov 25, 2014 at 06:28 PM 0
Share

That was my point that Compile$$anonymous$$esh() is in the wrong place and executing before the Coroutine could finish. I have moved to be executed at the end of the coroutine problem solved. Compile$$anonymous$$esh deals with normals and the like, The triangleIndicies struct can store color information since I am going for a flat shaded low res look I want each triangle to be a uniform color. If I don't give it a color it defaults to grey.

There are no UV's as there are no textures everything is handled via the shader.

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Return value from coroutine to non monobehaviour 1 Answer

Sync WaitForSeconds with Particles 1 Answer

How to create a delay in a function being called in update? 2 Answers

Smoothly moving a rectTransform by script 1 Answer

Coroutine starts but doesn't run? 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