Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Hacer una iteracion simple

Iniciado por enelmenu, Octubre 31, 2017, 02:25:27 AM

Tema anterior - Siguiente tema
Que me conviene, para hacer una iteracion simple, en cuanto al rendimiento, yo se que no cambia mucho, pero cual seria el mas optimizado y por que?
 
OPCION 1:

 
 

   void Update()
        {
            if (_enabled)
            {
                if (flagEnabled)
                    StartCoroutine(Material_On());
            }
        }
        IEnumerator Material_On()
        {
            colorCurrentObtained = false;
            emissionCurrentObtained = false;
            StopAllCoroutines();
            StartCoroutine(GetColorCurrent());
            StartCoroutine(GetEmissionCurrent());
            if (colorCurrentObtained && emissionCurrentObtained)
            {
                StartCoroutine(ColorActivated());
                StartCoroutine(EmissionActivated());
            }
            flagDisabled = true;
            yield return (flagEnabled = false);
        }

 
OPCION 2:

 
 

void Update()
        {
            if (_enabled)
            {
                Material_On();
            }
        }
        void Material_On()
        {
   if (flagEnabled)
   {
              colorCurrentObtained = false;
              emissionCurrentObtained = false;
              StopAllCoroutines();
              StartCoroutine(GetColorCurrent());
              StartCoroutine(GetEmissionCurrent());
              if (colorCurrentObtained && emissionCurrentObtained)
              {
                  StartCoroutine(ColorActivated());
                  StartCoroutine(EmissionActivated());
              }
              flagDisabled = true;
              flagEnabled = false;
   }
        }

 
??

Octubre 31, 2017, 03:28:01 AM #1 Ultima modificación: Octubre 31, 2017, 03:29:14 AM por lightbug
Hola, querés decir "corrutina vs función", o "meterte a la funcion/corrutina y evaluar vs evaluar antes de meterte" ? (lo digo por el flagenabled, se te escapó quizas?)
 
Te conviene evaluar antes de meterte, ir a una función implica hacer un salto + guardar algunas variables y usar un stack, etc, cuando comparar es solo ..bueno..comparar (cuac).
 
La parte de las corrutinas, si ponés muchisimas vas a notar diferencia vs hacerlo con funciones en Update (hay test por si estás interesado), este es el precio de las corruinas, ahora, para muchos es mucho mas intuitivo hacer cosas desde las corrutinas e incluso tiene cosas muy útiles (algo que no estás usando)
 
1 - Podrías dispararlas en Start si es que vas a estar usando el Update por siempre (como en tu ejemplo):
 

void Start()
{
StartCoroutine(Material_On);
}
IEnumerator Material_On()
        {
      while(true){
         ....
         ....
         ....
         yield return null;   //pasa el cuadro
      }
        }

 
 
 
2 - Leyendo el "if( colorCurrentObtained && ...)" supongo que te metes en las dos, pero no las estás "yieldiando", es decir, las dos se disparan y terminas revisando una bool para ver si terminaron, osea, estás usando corrutinas sin las ventajas de las corrutinas. Si querés hacer todo secuencial en vez de llamar a una corrutina usa esto (ejemplo):
 

private IEnumerator Corrutina1()
       {
          yield return StartCoroutine( Corrutina2());   
      //en vez de -->  StartCoroutine( Corrutina2());
       }

 
Esto te asegura que el curso de la corrutina se detiene hasta que no termine (yield return) de la corrutina 2, entonces en tu código no tendrías que realizar ese "if( colorCurrentObtained && ...)"
 
 
 
Entonces te podría quedar algo asi, no se si está bien:
 

void Start()
{
StartCoroutine(Material_On);
}
IEnumerator Material_On()
        {
      while(true){
         //forma linda de las corrutinas, si podes usar while's usalos, aca se puede
         while(!_enabled || !flagEnabled){
            yield return null;
         }
                  
         StopAllCoroutines();
               yield return StartCoroutine(GetColorCurrent());
               yield return StartCoroutine(GetEmissionCurrent());
               StartCoroutine(ColorActivated());
                  StartCoroutine(EmissionActivated());
                     
               flagDisabled = true;   //y esto?
               flagEnabled = false;    
         //creo que pasa el cuadro, aunque "yieldiés" un int, bool, o lo que sea
         //distinto a las clases que yield reconoce
   
         yield return null;   //yield de while (true)
      }
      yield return null;   //Ojo no se si este va
   }
   }

 
 
 
PD: que feo que lo presentó el editor de código jajaj, aca el pastebin:
 
Código
 
 

Para demostrar un poco el tema de las corrutinas (de forma exagerada) aca un pequeño test de 2100 cubos moviendose senoidalmente hacia arriba, en dos versiones:
 
Corrutina:
 

float m_time = 0;
Transform m_transform;
Vector3 m_initialPos;
float m_randowPhase;
void Start () {
   m_transform = transform;
   m_initialPos = m_transform.position;
   m_randowPhase = Random.Range(0, Mathf.PI);
 
   StartCoroutine (Corrutina());
   
}

IEnumerator Corrutina()
{
   while (true) {
      m_time += Time.deltaTime;
      m_transform.position = m_initialPos + Mathf.Sin (2 * m_time + m_randowPhase) * Vector3.up;
      yield return null;
   }
}

 
Update:
 

float m_time = 0;
Transform m_transform;
Vector3 m_initialPos;
float m_randowPhase;
void Start () {
   m_transform = transform;
   m_initialPos = m_transform.position;
   m_randowPhase = Random.Range(0, Mathf.PI);
   
}


void Update () {
   m_time += Time.deltaTime;
   m_transform.position = m_initialPos + Mathf.Sin (2 * m_time + m_randowPhase) * Vector3.up;
}

 
Resultados (sin vsync):
 

Noviembre 01, 2017, 05:37:19 PM #3 Ultima modificación: Noviembre 01, 2017, 05:51:35 PM por enelmenu
Cita de: lightbug date=1509416881Esto te asegura que el curso de la corrutina se detiene hasta que no termine (yield return) de la corrutina 2, entonces en tu código no tendrías que realizar ese "if( colorCurrentObtained && ...)"
   


@lightbug Me encanta! me diste muy claros ejemplos, gracias juan.

Entendi bastante bien las coroutinas podes hacer updates que te coman menos memoria con yield Waitforseconds!!
 
El unico problema que estoy teniendo es con el StopCoroutine(routine);
 
Nose por que motivo no me para una rutina instantaneamente cuando le declaro StopCoroutine :/

Pero cuando declaro StopAllCoroutines me frena bien, no entiendo :/ y el tema de poner StopAllCoroutines es que tambien me frena mi rutin con el while(true) que lo uso como update
https://ghostbin.com/paste/tyn3k
 
Es mucho mas simple de lo que parece ese codigo, solamente mira los IEnumerator, y fijate cuando uso los Stop, el problema es que la rutina IEnumerator ColorActivated() y IEnumerator EmissionActivated()

llegan a un determinado color y dsp hace otra cosa, antes de que haga la otra cosa debugea esto
Debug.Log("Finish EmissionActivated");
Debug.Log("Finish ColorActivated");

La cuestion es que si yo con el while(true) de: IEnumerator InitSequence()

Entro en el segundo while, FRENE las rutinas de Activated, ANTES de que llegen a los debug esos y no me las frena(tipo entro al segundo while y en consola me debugea igual, como que no se frenan cuando yo quiero)... a que se debe? que estaria mal?
 
PD: Cuando utilizo StopAllCoroutines ()
StopAllCoroutines();
//StopCoroutine(Material_On());
//StopCoroutine(ColorActivated());
//StopCoroutine(EmissionActivated());
 
Envez de los Stop independientes me los frena bien.... PERO tambien me frena mi InitSequence...

Que esta pasando????????
 
PD: vas aver 3 StopCoroutines mas en cada Material_ pasa que los puse para reforzar jajaja y tampoco me los frena bien :/

Cita de: enelmenu date=1509554239La cuestion es que si yo con el while(true) de: IEnumerator InitSequence()

      Entro en el segundo while, FRENE las rutinas de Activated, ANTES de que llegen a los debug esos y no me las frena(tipo entro al segundo while y en consola me debugea igual, como que no se frenan cuando yo quiero)... a que se debe? que estaria mal?
   


Se que sonará tonto pero probaste de hacer esto (por el orden):
 

StopCoroutine(EmissionActivated());
StopCoroutine(ColorActivated());                    
StopCoroutine(Material_On());

 
 
 
podrías probar de arrancar una corrutina que a su vez arranque otra que imprima algo (yield StartCoroutine (...) ) y hacer un Stop de la primera, algo como tenés acá pero para sacarte las dudas con algo simple. Probá lo de arriba del orden si es que influye o nó. Si parás la primera y sigue imprimiendo, quizas tengas que parar a la segunda (la yieldiada) y luego a la primera. Pero si empezas a yieldiar una y otra y otra empezar a nombrarlas a todas no solo se vuelve tedioso sino que de seguro sospecharás que hay algo mal.
 
Fijate que si tenés version on/off no es necesario poner dos corrutinas dsitintas, manejate más bien con un argumento, va, si querés, por ej (no se si funca):
 
https://ghostbin.com/paste/zjvkc
 
 
 
 
 
 
 
 

Etiquetas: