Jump to content
Sign in to follow this  
nomoregames

ANSWERED Rutinas concatenadas

Recommended Posts

Hola a todos, tengo el siguiente script

    void LateUpdate()
    {
        if (Input.GetMouseButtonUp(0))
        {
            InitialPosition = mouse.transform.position;
            StartCoroutine(Punch());
            StopCoroutine(Punch());

        }
    }

    IEnumerator Punch()
    {
        while (PunchController.transform.position != mouse.transform.position)
        {
            PunchController.transform.position = Vector3.MoveTowards(PunchController.transform.position, mouse.transform.position,1f);
            print("hola");
            
            yield return null;
        }
        InitialPosition = mouse.transform.position;

    }

(lo de print hola era para que me apareciera en el inspector si se ejecutaba o no)

Como podéis ver, en este script lo que hago es que cuando dejo de presionar el ratón, se ejecuta una corrutina en la que  el PunchController se mueve hacia el mouse hasta que los dos estén en la misma posición...

Como hago que cuando se acabe de ejecutar el while el PunchController ejecute otra corrutina para moverse de nuevo hacia su InitialPosition

Share this post


Link to post
Share on other sites
void LateUpdate()
    {
        if (Input.GetMouseButtonUp(0))
        {
            InitialPosition = mouse.transform.position;
            StartCoroutine(Punch(mouse.transform.position));
            StopCoroutine(Punch());

        }
    }

    IEnumerator Punch(Vector3 position)
    {
        while (PunchController.transform.position != position)
        {
            PunchController.transform.position = Vector3.MoveTowards(PunchController.transform.position, position,1f);
            print("hola");
            
            yield return null;
        }
        StartCoroutine(Punch(InitialPosition));

    }

Pasale un parámetro a la corrutina que sea la posición, y esta la cambias cuantas veces desees, siendo en un principio mouse.position y al final initialPosition.

Edited by leocub58

Share this post


Link to post
Share on other sites

Pero ese StopCoroutine inmediatamente después del StartCoroutine... por suerte no funciona como se espera.

Tal cómo está escrito y entiendo. Va a entrar en la coroutine, saldrá por el yield, se ejecutará el StopCoroutine (que por motivos que explicaré después no va a parar la coroutine), se moverá a la posición position y luego ejecutará la misma coroutine con un parámetro InitialPosition que entiendo es local a la class.

El StopCoroutine no va a funcionar ya que el valor IEnumerator devuelto por la función Punch es diferente. Se genera cada vez que la coroutine es llamada, por tanto será diferente y no se corresponderá con la de la StartCoroutine. Para parar una coroutine hay que guardar el valor del IEnumerator de StartCoroutine en una variable y utilizar ésta para el StopCoroutine.

No lo haría de este modo ya que realizará el movimiento completo siempre y luego volverá a la posición inicial. Si le das un click rápido hará toda la secuencia. Bien si quieres una Coroutine aunque haría intervalos de movimiento cortos utilizando un Translate o cualquier tipo de acción con un Time.deltaTime y la variable de posición la actualizará externamente. De ese modo si dejan de hacer click cambio el valor de la variable y esté donde esté en la posición volverá a la inicial. Si hacen click cuando está volviendo a la posición inicial, volverá a la posición de punch. Creo que es mucho más "responsive".

 

Edited by iRobb

Share this post


Link to post
Share on other sites

Buenas tardes, he echo lo siguiente, haciendo caso a  leocub58 y funciona

 void LateUpdate()
    {
     
        if (Input.GetMouseButtonUp(0))
        {
            InitialPosition = PunchController.transform.position;

            StartCoroutine(Punch());
            

        }
    }

    IEnumerator Punch()
    {
        while (PunchController.transform.position != mouse.transform.position)
        {
            PunchController.transform.position = Vector3.MoveTowards(PunchController.transform.position, mouse.transform.position,1f);
           
            
            yield return null;
        }
        print("finish");
        StopCoroutine(Punch());
        StartCoroutine(ReturnPosition());
	}

 

Y ,iRobb no he entendido nada :60_sweat:, como aplicarías lo que dices a mi script? Para entenderlo mejor

 

Share this post


Link to post
Share on other sites

La implementación de una corrutina para esta situación no tiene mucho sentido, deberias utilizar simplemente comparaciones dentro de la función Update.

private int m_state { get; set; } = 0;

private void Update()
{
    if (Input.GetMouseButtonUp(0) && m_state == 0)
        m_state = 1;
        
    if (Input.GetMouseButtonDown(0) && m_state == 1)
        m_state = 2;        
        
    if (m_state == 1)
    {
        if (PunchController.transform.position != mouse.transform.position)
        {
            PunchController.transform.position = Vector3.MoveTowards(PunchController.transform.position, mouse.transform.position,1f);
        }
        else
        {
            m_state = 2;
        }
    }    
    
    if (m_state == 2)
    {
        ReturnPosition();
        m_state = 0;
    }
}

Lo que te comentaba @iRobb es que la función StartCoroutine retorna un objeto Coroutine el cual se debería utilizar para detener dicha coroutine, tambien se puede almacenar el objeto IEnumerator como una variable para iniciar y detener la corrutina siempre con la misma referencia.

Ejemplo almacenando el enumerador dentro de una variable para ser utilizado de forma regular.

private IEnumerator m_corrutine { get; set; }

private void Start()
{
    m_corrutine = IEShot();
}

private void Update()
{   
    if (Input.GetMouseButtonDown(0))
        StartCoroutine(m_corrutine);
        
    if (Input.GetMouseButtonUp(0))        
        StopCoroutine(m_corrutine);  
}

private IEnumerator IEShot()
{
    yield return new WaitForSeconds(2);
}

 

Share this post


Link to post
Share on other sites
Sign in to follow this  

×
×
  • Create New...