Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved For loop in Coroutine isn't working.

Discussion in 'Scripting' started by UltraShards, Jul 31, 2020.

  1. UltraShards

    UltraShards

    Joined:
    Jul 3, 2020
    Posts:
    7
    I'm trying to move the camera up when a GUI element comes on screen and back down when it goes away. There's supposed to be a transition where the Camera moves up at a certain speed instead of teleporting, but it's not working. I found out that when the Coroutine is called, it skips over the for loop.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CameraController : MonoBehaviour
    6. {
    7.     public float defaultHeight = 16f;
    8.     public float onGUIHeight = 13f;
    9.     public float transitionTime = 1f;
    10.     public float subPositions = 10f;
    11.  
    12.     bool onGUI = false;
    13.  
    14.     int i = 0;
    15.  
    16.     void Start()
    17.     {
    18.         // Sets the position to the default value.
    19.         transform.position = new Vector3(transform.position.x, defaultHeight, transform.position.z);
    20.     }
    21.  
    22.     void Update()
    23.     {
    24.         if (Input.GetKeyDown("space"))
    25.         {
    26.             if (onGUI == true)
    27.             {
    28.                 onGUI = false;
    29.                 StartCoroutine(ExitGUI());
    30.             } else if (onGUI == false)
    31.             {
    32.                 onGUI = true;
    33.                 StartCoroutine(EnterGUI());
    34.             }
    35.         }
    36.     }
    37.  
    38.     public IEnumerator EnterGUI()
    39.     {
    40.         for (i = 0; i > subPositions; i++)
    41.         {
    42.             transform.position = new Vector3(transform.position.x, onGUIHeight * ((i + 1) / subPositions), transform.position.z);
    43.             yield return new WaitForSeconds(transitionTime / subPositions);
    44.         }
    45.  
    46.         transform.position = new Vector3(transform.position.x, onGUIHeight, transform.position.z);
    47.     }
    48.  
    49.     public IEnumerator ExitGUI()
    50.     {
    51.         for (i = 0; i > subPositions; i++)
    52.         {
    53.             transform.position = new Vector3(transform.position.x, defaultHeight * ((subPositions - i) / subPositions), transform.position.z);
    54.             yield return new WaitForSeconds(transitionTime / subPositions);
    55.         }
    56.  
    57.         transform.position = new Vector3(transform.position.x, defaultHeight, transform.position.z);
    58.     }
    59. }
    60.  
    The camera teleports to the location instead of moving at a constant speed. I'm not sure why this happens or what I can do about it. Thanks for your help in advance :)
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,192
    The issue is your for loop.
    Since you are doing i++, but you are checking if i > subPositions, but you're starting at 0.

    It should be i < subPositions

    Remember the second part of a for loop is similar to a while statement. So you're essentially telling it, while i > subPositions, do the code inside. Which it is never true.
     
    Yanne065 likes this.
  3. UltraShards

    UltraShards

    Joined:
    Jul 3, 2020
    Posts:
    7
    Ohhhhhhh... thanks a lot! I thought that it only exited the loop if the condition was met not stayed inside.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    It may also be worth noting that you could get a smoother motion if you updated every frame, rather than using a fixed number of subPositions. That might look something like:
    Code (CSharp):
    1.     public IEnumerator EnterGUI()
    2.     {
    3.         float timeSoFar = 0;
    4.         while (timeSoFar < transitionTime)
    5.         {
    6.             float desiredHeight = Mathf.Lerp(defaultHeight, onGUIHeight, timeSoFar / transitionTime);
    7.             transform.position = new Vector3(transform.position.x, desiredHeight, transform.position.z);
    8.             yield return null;  // waits until the next frame, however long that is
    9.             timeSoFar += Time.deltaTime;
    10.         }
    11.         transform.position = new Vector3(transform.position.x, onGUIHeight, transform.position.z);
    12.     }
    Of course, if you are intentionally making it less smooth (e.g. to simulate a machine with a ratchet or something), then you can ignore this.
     
    PraetorBlue likes this.