[résolu][DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Avatar de l’utilisateur
Murdeau
Messages : 21
Inscription : 30 Juil 2020 14:03
Localisation : Grenoble

[résolu][DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par Murdeau » 06 Avr 2022 16:31

Bonjour tout le monde, :hello:

J'ai créé un 2D object/sprite/square.
J'ai mis une image dans le Sprite Renderer.
J'ai attaché le script target à ce GameObject (appelons-le "image").
J'en ai fait un préfab.

Dans une coroutine avec un yield return new WaitUntil(VraiFaux) et VraiFaux() renvoie false
L'"image" est instanciée et elle attend que quelqu'un lui clique dessus.
Cela provoque l'appel d'un particuleSystem, une étoile semi-transparente apparaît sur l'étoile, elle grossit puis disparaît lentement. cela prend environ 2 secondes.

J'ai réussi à mettre une coroutine avec un yield return new WaitForSeconds(2).
Une fois l’animation finie, l’image est détruite.
Je fais en sorte que VraiFaux() renvoie true pour que la première coroutine affiche une nouvelle « image » gràce à une boucle.

:-/ Cela marche bien mais je me dis qu’il doit y avoir un autre moyen pour faire savoir à la coroutine qu’elle doit attendre le temps que le particuleSystem ait fini de jouer.


J’ai donc essayé une coroutine avec un while(nomParticuleSystem) {yield return null}

Ça ne marche pas, l’image est effacée dès le début de l’animation et une nouvelle image est instanciée aussitôt pendant que l’animation joue. :(

J’ai essayé aussi
var main = nomParticuleSystem.main ;
while(main.StartSize!= 0) {yield return null} :snif:

J’ai essayé aussi
var emission = nomParticuleSystem.emission ;
while(emission.enabled) {yield return null} :pleur4:

Quelqu’un a-t’il une solution ? Merci beaucoup.

Code : Tout sélectionner

  
    void ImageClic()
    {          
            StartCoroutine(AfficheEtoile());    // faire la coroutine d'animation étoile
             reinitial();        // passer à l'image suivante                                                       
    }

    // animation d'une étoile sur l'image 
    IEnumerator AfficheEtoile()
    {
        Instantiate(etoileParticle, transform.position, etoileParticle.transform.rotation); // faire apparaitre l'étoile sur l'image cliquée (l'animation est attachée à l'image)
        var emission = etoileParticle.emission;
        //        tant que le etoileParticle est actif
        while(emission.enabled)
        {
            Debug.Log("j'attends " );
            yield return null;
        }
    }

	// passer à l'image suivante
  	  void reinitial()
   	 {
   	     Destroy(gameObject);    // détruire l'image
    	    gameManager.affichageSuivant = true; // signaler au script gameManager que la variabe "affichageSuivant" est sur "true" pour que VraiFaux() retourne true
	  }
Dernière édition par Murdeau le 13 Avr 2022 11:57, édité 1 fois.

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: [DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par Max » 09 Avr 2022 15:09

Bonjour,

Au niveau de ParticleSystem, tu peux passer par IsAlive par exemple.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
Murdeau
Messages : 21
Inscription : 30 Juil 2020 14:03
Localisation : Grenoble

Re: [DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par Murdeau » 11 Avr 2022 16:36

Merci pour cette aide. :)

Mais cela ne fonctionne pas avec IsAlive(), j'ai toujours false comme réponse. :/
J'ai aussi essayé avec IsEmitting. :(

j'essaye maintenant d'utiliser startLifetime :ghee: mais ça ne fonctionne pas non plus, je n'arrive pas à trouver la bonne écriture. :0

Code : Tout sélectionner

    IEnumerator AfficheSmEt(ParticleSystem smileyEtoile)
    {
        Instantiate(smileyEtoile, transform.position, smileyEtoile.transform.rotation); // faire apparaitre le smiley ou l'étoile 
        var recup = smileyEtoile.main;
        yield return new WaitForSeconds(recup.startLifetime);                                   // attendre le temps de la durée de vie des particules
    }
je récupère l'erreur suivante: Assets\Target.cs(80,41): error CS1503: Argument 1: cannot convert from 'UnityEngine.ParticleSystem.MinMaxCurve' to 'float' :-/

quelqu'un a une idée ? Merci.

Avatar de l’utilisateur
jmhoubre
Messages : 856
Inscription : 05 Oct 2019 22:05

Re: [DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par jmhoubre » 11 Avr 2022 17:46

Peut-être lire et interpréter le message d'erreur, qui est assez explicite je trouve....

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: [DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par Max » 11 Avr 2022 18:29

Murdeau a écrit :
11 Avr 2022 16:36
Mais cela ne fonctionne pas avec IsAlive(), j'ai toujours false comme réponse. :/
il doit y avoir un soucis quelque part, car tu devrais avoir true au départ, et ce tant que tu as des particules encore actives.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
Murdeau
Messages : 21
Inscription : 30 Juil 2020 14:03
Localisation : Grenoble

Re: [DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par Murdeau » 13 Avr 2022 11:09

jmhoubre a écrit :
11 Avr 2022 17:46
Peut-être lire et interpréter le message d'erreur, qui est assez explicite je trouve....
Bonjour et merci pour cette aide.
J'ai bien compris que l'erreur vient du fait qu'il n'est pas possible de convertir recup.startLifetime en float.

Quand je vais voir le manuel, j'y trouve :

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(ParticleSystem))]
public class ExampleClass : MonoBehaviour
{
    private ParticleSystem ps;
    public float hSliderValue = 1.0F;

    void Start()
    {
        ps = GetComponent<ParticleSystem>();
    }

    void Update()
    {
        var main = ps.main;
        main.startLifetime = hSliderValue;
    }

    void OnGUI()
    {
        hSliderValue = GUI.HorizontalSlider(new Rect(25, 45, 100, 30), hSliderValue, 0.0F, 5.0F);
    }
}
il y est bien écrit que hSliderValue est float (public float hSliderValue = 1.0F;)
et comme main.startLifetime = hSliderValue donc main.startLifetime devrait être float, je ne vois pas la raison de mon erreur.

Avatar de l’utilisateur
Murdeau
Messages : 21
Inscription : 30 Juil 2020 14:03
Localisation : Grenoble

Re: [DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par Murdeau » 13 Avr 2022 11:16

Max a écrit :
11 Avr 2022 18:29
Murdeau a écrit :
11 Avr 2022 16:36
Mais cela ne fonctionne pas avec IsAlive(), j'ai toujours false comme réponse. :/
il doit y avoir un soucis quelque part, car tu devrais avoir true au départ, et ce tant que tu as des particules encore actives.
Je suis d'accord avec toi, et je dirais même plus : IL Y A un soucis quelque part :rougefaché: .
Mais où ? Mais je vais finir par trouver, je ne désespère pas... pour l'instant :cry: .

Avatar de l’utilisateur
Murdeau
Messages : 21
Inscription : 30 Juil 2020 14:03
Localisation : Grenoble

Re: [DB-AL] utiliser une coroutine pour attendre la fin d'un particuleSystem

Message par Murdeau » 13 Avr 2022 11:56

En cherchant encore et encore :0 , ce matin, après une bonne nuit et un bon petit déjeuner :pausecaffé: , je décide d'explorer à fond le message d'erreur qui parle de UnityEngine.ParticleSystem.MinMaxCurve. Je pars donc sur la page du manuel qui explique MinMaxCurve et donne cet exemple qui utilise pour une fois la lecture d'une variable :taré1: (même s'il ne s'agit pas de celle qui m'intéresse) :

Code : Tout sélectionner

[...]
    void GetValue()
    {
        print("The constant value is " + emissionModule.rateOverTime.constant);
    }

    void SetValue()
    {
        emissionModule.rateOverTime = 10.0f;
    }
et je vois que lors de la lecture, on rajoute un .constant à la variable :ghee: .
Le manuel ne peut pas être plus explicite, franchement !!!

Et voici le code qui fait que ma coroutine marche maintenant. Elle attend le temps que dure l'animation avant de passer à la suite.

Code : Tout sélectionner

    IEnumerator AfficheSmEt(ParticleSystem smileyEtoile)
    {
        Instantiate(smileyEtoile, transform.position, smileyEtoile.transform.rotation); // faire apparaitre le smiley ou l'étoile 
        var recup = smileyEtoile.main;
        yield return new WaitForSeconds(recup.startLifetime.constant);                                   // attendre le temps de la durée de vie des particules
    }
Par contre je ne sais pas encore utiliser IsAlive(),
mais je vais me contenter de cette solution qui est pas mal non plus :vivemoi: .

Merci à jmhoubre pour son soutient
et à Max pour m'avoir proposé une nouvelle voie à explorer.

Répondre

Revenir vers « Scripting »