Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Help With A Coroutine

Discussion in 'Scripting' started by DRRosen3, Jan 15, 2015.

  1. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Can't figure this one out. This is what I have (inside the coroutine obviously)...

    Code (CSharp):
    1.         Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
    2.         foreach(Renderer renderer in renderers){
    3.             renderer.material.Lerp(orgMat, evolveColor, 5f * Time.deltaTime);
    4.         }
    I want to have the coroutine pause while this is taking place. I don't want it to continue on until all the renderers material's have been changed. I can't conceive for the life of me how to put this in a while loop though, considering it's not just ONE thing I'm waiting for. Any suggestions?
     
  2. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    Possibly something like this?

    Code (CSharp):
    1.     IEnumerator Example() {
    2.         Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
    3.         int size = renderers.Length;
    4.         int index = 0;
    5.  
    6.         while(index < size) {
    7.             renderers[index].material.Lerp(orgMat, evolveColor, 5f * Time.deltaTime);
    8.  
    9.             if(orgMat == evolveColor) {
    10.                 index++;
    11.             }
    12.  
    13.             yield return null;
    14.         }
    15.     }
     
  3. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Neither this. nor gameObject. are necessary. GetComponentsInChildren is a method of Component.
     
  4. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    I am neither here nor there on this but, this is not what the OP was asking for.
     
    DRRosen3 likes this.
  5. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    The only problem with this is that it's going to change them one at a time, and I need them all to Lerp simultaneously.
     
  6. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    Oh you want them ALL okay try this

    Code (CSharp):
    1.     IEnumerator Example() {
    2.         Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
    3.         bool[] completed = new bool[renderers.Length];
    4.         bool isCompleted = false;
    5.        
    6.         while(!isCompleted) {
    7.             for(int i = 0; i < renderers.Length; i++) {
    8.                 renderers[i].materials[i].Lerp(orgMat, evolveColor, 5f * Time.deltaTime);
    9.  
    10.                 if(renderers[i].material == evolveColor) {
    11.                     completed[i] = true;
    12.                 }
    13.             }
    14.  
    15.             foreach(bool checkState in completed) {
    16.                 if(checkState == false) {
    17.                     isCompleted = false;
    18.                     break;
    19.                 } else {
    20.                     isCompleted = true;
    21.                 }
    22.             }
    23.  
    24.             yield return null;
    25.         }
    26.     }
     
  7. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    Actually material.Lerp is values between 0 and 1 so..try this.

    Code (CSharp):
    1.     IEnumerator Example() {
    2.         Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
    3.         bool[] completed = new bool[renderers.Length];
    4.         float[] elapsedTimes = new float[renderers.Length];
    5.         bool isCompleted = false;
    6.         float time = 5.0f; // Total Time for it all to complete
    7.         float speed = 1.0f; // How fast we progress
    8.      
    9.         while(!isCompleted) {
    10.             for(int i = 0; i < renderers.Length; i++) {
    11.                 renderers[i].materials[i].Lerp(orgMat, evolveColor, elapsedTimes[i] / time);
    12.  
    13.                 if(renderers[i].material == evolveColor) {
    14.                     completed[i] = true;
    15.                 }
    16.  
    17.                 elapsedTimes[i]+= speed * Time.deltaTime;
    18.             }
    19.  
    20.             foreach(bool checkState in completed) {
    21.                 if(checkState == false) {
    22.                     isCompleted = false;
    23.                     break;
    24.                 } else {
    25.                     isCompleted = true;
    26.                 }
    27.             }
    28.  
    29.             yield return null;
    30.         }
    31.     }
     
  8. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    If you're not here to teach or learn as much as you can, I say GTFO. Put me on block if you disagree.

    Every piece of code you don't have to write is a step in the direction of realizing your vision.
     
  9. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    This is a VERY piss poor attitude to have. @Polymorphik was right in saying you didn't answer the OP. If you're going to respond to a thread, at LEAST answer what was asked, before giving your two cents. (We're not saying they're not wanted.)
     
  10. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    http://forum.unity3d.com/threads/unity-developer-network-rules.151494/
    Read the rules and follow them or
    .
     
  11. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Someone else responded, and I've only got so much time. You don't appreciate my time and effort to improve you, me, and everyone else who comes along? Block me. I'm not offended. I'd prefer not to have this negativity in my life.
     
  12. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    We are oft to blame in this,
    'Tis too much proved, that with devotion’s visage
    And pious action we do sugar o'er
    The devil himself.
     
    DRRosen3 likes this.
  13. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Alright...so I also looked up the "material.Lerp" documentation and I see this isn't right for what I'm trying to accomplish. What I ended up doing was writing a customer shader. Now I'm still kind of running into the same problem. Here's the new code...

    Code (CSharp):
    1.  
    2. foreach(Renderer renderer in renderersArray){
    3.             materialsArray = renderer.materials;
    4.             originalMaterialsArray = renderer.materials;
    5.             orgMatList.Add(originalMaterialsArray);
    6.             foreach(Material material in materialsArray){
    7.                 if(material.shader.name == "Toon/Basic Blender"){
    8.                     float counter = material.GetFloat("_Blend");
    9.                     while(counter != 1f){
    10.                         float increase = material.GetFloat("_Blend") + 0.01f;
    11.                         material.SetFloat("_Blend", increase);
    12.                         counter += increase;
    13.                         yield return null;
    14.                     }
    15.                 }
    16.             }
    17.         }
    18.  
    Obviously this is inside of an IEnumerator. The problem is that it's only changing ONE of the materials inside the arrays, but I want it to change ALL of them (so long as they meet the criteria). What am I over-looking?
     
  14. Random_Civilian

    Random_Civilian

    Joined:
    Nov 5, 2014
    Posts:
    55
    It looks like you are partially manipulating one material before returning to update.
    If you want to manipulate all in one frame, this pseudocode might be what you are looking for.

    Foreach(renderer){ if(matches criteria) StartCoroutine(manipulate single material)}

    EDIT: In the above post, if you want to change all materials, just move the yield outside of the foreach loop.
     
    Last edited: Jan 17, 2015
  15. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    I gave that a shot @Random_Civilian this way:

    Code (CSharp):
    1. private IEnumerator Change(){
    2.         foreach(Renderer renderer in renderersArray){
    3.             materialsArray = renderer.materials;
    4.             foreach(Material material in materialsArray){
    5.                 yield return StartCoroutine(ChangeToWhite(material));
    6.             }
    7.         }
    8.         yield return null;
    9.     }
    10.  
    11. private IEnumerator ChangeToWhite(Material mat){
    12.             if(mat.shader.name == "Toon/Basic Blender"){
    13.                 float counter = mat.GetFloat("_Blend");
    14.                 while(counter != 1f){
    15.                     float increase = mat.GetFloat("_Blend") + 0.01f;
    16.                     mat.SetFloat("_Blend", increase);
    17.                     counter += increase;
    18.                     yield return null;
    19.                 }
    20.             }
    21.     }
    Didn't work. It's still only changing the very first material in the "materialsArray" and that's it.
     
  16. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Alright, I found a work-around, but I'm SURE there's got to be a more "efficient" way.

    Code (CSharp):
    1. private Renderer[] renderersArray;
    2. private List<Material> materialsList = new List<Material>();
    3.  
    4. private IEnumerator Change(){
    5.         foreach(Renderer renderer in renderersArray){
    6.             for(int i = 0; i < renderer.materials.Length; i++){
    7.                 materialsList.Add(renderer.materials[i]);
    8.             }
    9.         }
    10.         foreach(Material material in materialsList){
    11.             StartCoroutine(ChangeToWhite(material));
    12.         }
    13.         changedForm = Instantiate(changeInto, this.transform.position, this.transform.rotation) as GameObject;
    14.         yield return null;
    15.     }
    16.  
    17.     private IEnumerator ChangeToWhite(Material mat){
    18.             if(mat.shader.name == "Toon/Basic Blender"){
    19.                 float counter = mat.GetFloat("_Blend");
    20.                 while(counter != 1f){
    21.                     float increase = mat.GetFloat("_Blend") + 0.01f;
    22.                     mat.SetFloat("_Blend", increase);
    23.                     counter += increase;
    24.                     yield return null;
    25.                 }
    26.             }
    27.     }
    Now I just have to get to not execute line 15 until all of the materials have reached their desired blend level.
     
  17. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    BUMP...
     
  18. Random_Civilian

    Random_Civilian

    Joined:
    Nov 5, 2014
    Posts:
    55
    This might be what you are looking for and simple (on phone right now so sorry for formatting). IN CO ROUTINE:

    While (matlistcount> 0)

    ENUMERATE LIST BACKWARDS, manipulate,If (criteria met) remove from list

    Yield outside of enumeration but inside while loop.
     
  19. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    I'm sure your idea might have worked @Random_Civilian and thanks for posting it. I got it solved another way.

    Code (CSharp):
    1. foreach(Material material in materialsList){
    2.         StartCoroutine(ChangeToWhite(material));
    3.         yield return new WaitForSeconds(1);
    4.     }
    5.  
    6.     private IEnumerator ChangeToWhite(Material mat){
    7.     float counter = mat.GetFloat("_Blend");
    8.     while(counter != 1f){ //the 1 here is the time to wait
    9.         float increase = mat.GetFloat("_Blend") + Time.deltaTime;
    10.         mat.SetFloat("_Blend", increase);
    11.         counter += increase;
    12.         yield return null;
    13.     }
    14. }