Noticias

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

Ejecutar función dos segundos más tarde del último clic

Iniciado por El preguntón, Julio 12, 2017, 05:32:31 PM

Tema anterior - Siguiente tema


Hola comunidad,
 


Estaba haciendo un proyecto personal y necesitaba hacer que en pulsar una tecla una o barias veces seguidas, se ejecuta una única vez  y dos segundos más tarde que el último clic una determinada función. He hecho una prueba, que es la siguiente:


using UnityEngine;
using System.Collections;
public class prueba : MonoBehaviour {
private bool _limite = false;
void Update ()
{
   if(Input.GetKeyDown(KeyCode.Space))
   {
      _limite = true;
      StartCoroutine (Espera ());
   }
}
IEnumerator Espera()
{
   yield return new WaitForSeconds (2);
   if(_limite == true)
   {
      _limite = false;
      Debug.Log ("Funciona!");
   }
}
}


 
Como podéis ver, en un principio funciona correctamente, es decir, si pulso un vez o más solo se ejecuta una sola vez el mensaje. Pero el problema es que con este código si pulso todo el rato durante más de dos segundos ya no funciona como yo quería, envía mensajes a la consola por cada uno de los clics.
 


Aun soy novato en programación, así que supongo que aparte de hacerlo mal me he complicado un poco la vida. Así que, ¿alguien tiene una idea de cómo lograr esto?.
 


Muchas gracias de antemano.


Olvidate del codigo a lo primero y pensalo asi (q es casi como lo tenes):
 


  •    Si apretas algo y estas en condiciones, (inicialmente lo estas) entras en un "modo de espera"


  •    Si estas en el modo de espera se empieza a contar e ignoras toda entrada (el flag)


  •    Si volves del modo de espera estas donde empezaste


En tu codigo se puede ver que de entrada te manejas con un flag, pero en update nunca verificas el flag, por lo tanto el "_limite" no sirve de nada asi como lo tenes. Tene en cuenta que podes iniciar varias corrutinas al mismo tiempo.
 
Se me ocurre algo asi, aunque podes verificar todo en la misma corrutina no me parece que creando varias y retornando de ellas sea lo indicado:
 

bool esperando = false;
 
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
   if(esperando == false)
   {
      esperando = true;
      StartCorroutine(Espera);
   }
}
}
IEnumerator Espera()
{
Debug.Log ("Comenzo");
    yield return new WaitForSeconds (2);
    esperando = false;
    Debug.Log ("Termino!");    
}

 
 

Julio 13, 2017, 08:29:52 AM #2 Ultima modificación: Julio 13, 2017, 08:31:42 AM por El preguntón


Wow! Eso está muy bien lightbug... Pero yo me refería después del último clic, y según el que me has pasado se ejecuta dos segundos más tarde después del primer clic y, los clics que se pulsen después durante esos dos segundos los ignora.
 


Yo buscaba que hiciese esto pero al revés, que ignorara todos los clics hasta el último el cual sería el que iniciaría la corutina. Por eso, por ejemplo, si pulsara una segunda vez un segundo y medio después del primer clic, volvería a esperar otra vez dos segundos sin aplicar la función del primer clic, porque habría pulsado otra vez dentro del margen de tiempo de la corutina.
 


¿Existe alguna forma de reiniciar la corutina mientras cuenta o algo por el estilo? A si por ejemplo, supongo que se podría lograr que cada vez que se pulsa empieza de nuevo la corutina y solo se ejecutaría la función cuando terminase el tiempo.
 
 
 
 


Julio 13, 2017, 09:14:58 AM #3 Ultima modificación: Julio 13, 2017, 09:16:02 AM por TheBullet
Cita de: El preguntón date=1499927392


      Wow! Eso está muy bien lightbug... Pero yo me refería después del último clic, y según el que me has pasado se ejecuta dos segundos más tarde después del primer clic y, los clics que se pulsen después durante esos dos segundos los ignora.
   
   


      Yo buscaba que hiciese esto pero al revés, que ignorara todos los clics hasta el último el cual sería el que iniciaría la corutina. Por eso, por ejemplo, si pulsara una segunda vez un segundo y medio después del primer clic, volvería a esperar otra vez dos segundos sin aplicar la función del primer clic, porque habría pulsado otra vez dentro del margen de tiempo de la corutina.
   
   


      ¿Existe alguna forma de reiniciar la corutina mientras cuenta o algo por el estilo? A si por ejemplo, supongo que se podría lograr que cada vez que se pulsa empieza de nuevo la corutina y solo se ejecutaría la función cuando terminase el tiempo.
   
   
       
   
   
       
   


Esto funcionará:

 
 

    float tiempo = 0;
    bool accionActivada = false;
    void Update()
    {
        if (accionActivada == true)
            tiempo += Time.deltaTime;
        if (Input.GetKeyDown(KeyCode.Space))
        {
            tiempo = 0;
            accionActivada = true;
        }
        if (tiempo > 2 && accionActivada == true)
        {
            accionActivada = false;
            //Hacer lo que sea
        }
    }

 
 
 
Saludos


   void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StopAllCoroutines();
            StartCoroutine(Espera());
        }
    }
    IEnumerator Espera()
    {
        yield return new WaitForSeconds(2);
        Debug.Log("Funciona!");
    }

 
 

Muchas gracias The Bullet y Kalua66. ¡Ah! Y también Lightbug por la aportación.

Julio 13, 2017, 06:28:42 PM #6 Ultima modificación: Julio 13, 2017, 06:30:01 PM por kaito
Podrias crear subrutinas o subprocesos utilizando corrutinas con un bucle infinito, while(true), iniciadas desde Start():
 

using UnityEngine;
using System.Collections;
public class FuncionesConPausa : MonoBehaviour {
    public int pulsacionesA;
    public int pulsacionesB;
    public int pulsacionesC;
// Use this for initialization
void Start () {
        //Funciones con pausa utilizando corrutinas
        StartCoroutine(this.PulsarA());
        StartCoroutine(this.PulsarB());
        StartCoroutine(this.PulsarC());

}
    IEnumerator PulsarA()
    {
        while (true)
        {
            yield return null;
            if (Input.GetKey(KeyCode.A))
            {
                //Lo que pasaria al pulsar A
                this.pulsacionesA++;
                yield return new WaitForSeconds(2f);
            }
        }
    }
    IEnumerator PulsarB()
    {
        while (true)
        {
            yield return null;
            if (Input.GetKey(KeyCode.B))
            {
                //Lo que pasaria al pulsar B
                this.pulsacionesB++;
                yield return new WaitForSeconds(2f);
            }
        }
    }
    IEnumerator PulsarC()
    {
        while (true)
        {
            yield return null;
            if (Input.GetKey(KeyCode.C))
            {
                //Lo que pasaria al pulsar C
                this.pulsacionesC++;
                yield return new WaitForSeconds(2f);
            }
        }
    }
}

 
 

Julio 13, 2017, 08:43:06 PM #7 Ultima modificación: Julio 13, 2017, 08:44:17 PM por El preguntón
Cita de: kaito date=1499963322Podrias crear subrutinas o subprocesos utilizando corrutinas con un bucle infinito, while(true), iniciadas desde Start():
   
   

using UnityEngine;
using System.Collections;
public class FuncionesConPausa : MonoBehaviour {
    public int pulsacionesA;
    public int pulsacionesB;
    public int pulsacionesC;
// Use this for initialization
void Start () {
        //Funciones con pausa utilizando corrutinas
        StartCoroutine(this.PulsarA());
        StartCoroutine(this.PulsarB());
        StartCoroutine(this.PulsarC());

}
    IEnumerator PulsarA()
    {
        while (true)
        {
            yield return null;
            if (Input.GetKey(KeyCode.A))
            {
                //Lo que pasaria al pulsar A
                this.pulsacionesA++;
                yield return new WaitForSeconds(2f);
            }
        }
    }
    IEnumerator PulsarB()
    {
        while (true)
        {
            yield return null;
            if (Input.GetKey(KeyCode.B))
            {
                //Lo que pasaria al pulsar B
                this.pulsacionesB++;
                yield return new WaitForSeconds(2f);
            }
        }
    }
    IEnumerator PulsarC()
    {
        while (true)
        {
            yield return null;
            if (Input.GetKey(KeyCode.C))
            {
                //Lo que pasaria al pulsar C
                this.pulsacionesC++;
                yield return new WaitForSeconds(2f);
            }
        }
    }
}

   
       
   


Tronco, eres un FENÓMENO!


Etiquetas: