Comment figer un timer et récupérer le dernier temps enregistré

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
PatateDuDimanche
Messages : 5
Inscription : 15 Déc 2020 15:51

Comment figer un timer et récupérer le dernier temps enregistré

Message par PatateDuDimanche » 15 Déc 2020 18:14

Coucou les gens, j'ai passé la journée la dessus et je sais OH combien c'est des soucis de débutant mais j'espère que vous serez indulgent ; j'ai fouillé dans pleins de forums et essayé pleins de techniques différentes mais je suis débutant donc je bloque...

En soit le problème est basique :pleur4: je souhaite faire arrêter un timer lorsque le joueur à dégommer tout les ennemis du niveau. J'aimerais afficher ce timer en tant que score sur le panneau de fin.

Code : Tout sélectionner

using System.Collections;
using UnityEngine.UI;
using UnityEngine;

public class Timer : MonoBehaviour
{
    public Text counterText;
    public int seconds, minutes;
    
    void Start()
    {
        counterText = GetComponent<Text>() as Text;
    }

    // Update is called once per frame
    void Update()
    {
        minutes = (int)(Time.time/60f);
        seconds = (int)(Time.time%60f);
        counterText.text = minutes.ToString("00")+":"+seconds.ToString("00");
    }
}
j'importe donc les variables dans mon script GameOver

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameOver : MonoBehaviour
{
	public int nbEnemy = 0;
	private Text txtEnemy;
	private GameObject [] EnemyTab;
	public Timer Timer;
	public int Figsec, Figmin;

	void Start()
	{
		txtEnemy = GameObject.Find("txtEnemy").GetComponent<Text>();
				 // compte ennemis
		EnemyTab = GameObject.FindGameObjectsWithTag("Enemy");

		foreach ( GameObject Enn in EnemyTab )
		{
			nbEnemy +=1;
		}

		txtEnemy.text="Enemy : "+ nbEnemy;
			
	}

	void Update()
	{
		nbEnemy = 0;

		EnemyTab = GameObject.FindGameObjectsWithTag("Enemy");
		foreach ( GameObject Enn in EnemyTab )
		{
			nbEnemy +=1;
		}

		txtEnemy.text="Enemy : "+ nbEnemy;
	
		if(nbEnemy == 0)
		{
			Figsec = Timer.seconds;
			Figmin = Timer.minutes;
			Debug.Log("Perfect !"+ Figmin);
		}
	}
}
Ce deuxième code ne fonctionne pas... je sais que le problème viens de Figsec et Figmin et en soit c'est juste incorrecte mais je suis perdu, je ne sais pas comment faire ça pour figer mon timer et récupérer les derniers temps de mes variables minutes et seconds.

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

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par jmhoubre » 15 Déc 2020 21:18

Bonjour,

1ère remarque : le code ci-dessous peut être amélioré.

Code : Tout sélectionner

foreach ( GameObject Enn in EnemyTab )
		{
			nbEnemy +=1;
		}
En effet, enemyTab est un tableau, dont la taille est enemyTab.Length.

2ème remarque, faire un Find dans une boucle Update n'est pas une pratique recommandée : Find est coûteux. L'idéal est de compter les ennemis détruits et de mettre à jour nbEnemy. Pour cela, il y a plusieurs façons de procéder :
- le méthode la plus efficace à mon avis est d'utiliser un event, mais c'est une technique qui dépasse un peu le niveau débutant.
- la seconde technique est de mettre un petit script sur tes ennemis. Ce script aura 2 méthodes : Awake () qui incrémentera nbEnemy, et OnDestroy (), qui décrémentera nbEnemy. Ce script référencera également le script GameOver afin d'accéder à nbEnemy.

3ème remarque : une convention largement utilisée précise que les noms des variables commencent par une minuscule. Donc Timer timer...

4ème remarque : ton timer met à jour sa valeur toutes les frames alors que sa valeur ne change que toutes les secondes. Tu peux le modifier comme ceci à peu de frais :

Code : Tout sélectionner

void Update()
    {
    	counter += 1; // A déclarer en int comme membre de la classe.
    	if (counter % 20 != 0) // N'entre dans la boucle qu'une fois sur 20.
    	{
        	minutes = (int)(Time.time/60f);
	        seconds = (int)(Time.time%60f);
        	counterText.text = minutes.ToString("00")+":"+seconds.ToString("00");
        }
    }


Pour le timer, la logique voudrait que ce soit ce script qui gère la condition nbEnemy == 0.

Sinon, je ne vois pas ce qui ne fonctionne pas. Erreur de compilation ? A l'exécution ? Que dit la console ? Le timer s'affiche-t-il ? A quels objets as-tu affecté tes scripts ?

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

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par jmhoubre » 15 Déc 2020 22:23

J'ai implémenté tes scripts, et chez moi ils fonctionnent. Quand le dernier ennemi meurt, la console affiche bien "Perfect !0". Mais cela dépend de la façon dont tu as attaché tes scripts.

PatateDuDimanche
Messages : 5
Inscription : 15 Déc 2020 15:51

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par PatateDuDimanche » 16 Déc 2020 12:35

Bonjour,

merci pour vos réponses, je vais m'occuper d'améliorer le code :)

Ah vrai dire, mon problème se situe plutôt dans le fait que je ne sais pas stopper le timer... je voudrais faire ça afin d'obtenir une valeur fixe qui pourra être affiché par la suite comme score.

En soit le code fonctionne (même s'il est bancal :gene: ) par contre, il me manque l'arrêt du timer pour pouvoir le terminer :gene:

PatateDuDimanche
Messages : 5
Inscription : 15 Déc 2020 15:51

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par PatateDuDimanche » 16 Déc 2020 12:53

Quand j'importe la variable nbEnemy dans le script Timer.cs, ce dernier me donne ce message d’erreur et je n'arrive pas à obtenir la valeur de la variable :

Code : Tout sélectionner

NullReferenceException: Object reference not set to an instance of an object
Timer.Start () (at Assets/Scripts/Interface/Timer.cs:15)

Code : Tout sélectionner

public GameOver GameOver;

void Start()
    {
        nbEnemy = GameOver.nbEnemy;
        counterText = GetComponent<Text>() as Text;
    }
J'aimerais arrêter le timer lorsque nbEnemy est égal à 0

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5599
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par boubouk50 » 16 Déc 2020 12:57

Tu pourrais passer par une coroutine.
C'est comme un Update (), mais c'est toi qui gère le temps.

Sinon, tel tu le fais, il te faut gérer cela dans la classe Timer avec un booléen qui permet d'arrêter l'Update (), donc la mise à jour de minute et de seconde.
Pour un timer, je ne te conseille pas d'utiliser Time.time, mais plutôt de soustraire Time.timeSinceLevelLoad que tu auras récupérer au lancement du timer avec Time.timeSinceLevelLoad en cours. Cela te donne donc le delta de temps entre 2 prises de temps.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

siriusraine
Messages : 29
Inscription : 01 Mars 2017 21:53

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par siriusraine » 13 Mai 2021 23:25

bonsoir

pour recuperer un temps donnée tu peux aussi utilisé ca

Code : Tout sélectionner

float time = 0;
bool timerEnRoute

void FixedUpdate()
		{
			if( ennemyTab.lenght >0 ) //tant quil reste des ennemies ca va augmenter time 
			{
				time = time + time.deltaTime
			}
		}

je te laisse faire la conversion de time en minute ( petit indice : %)

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5599
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par boubouk50 » 20 Mai 2021 08:48

siriusraine a écrit :
13 Mai 2021 23:25

Code : Tout sélectionner

float time = 0;
bool timerEnRoute

void FixedUpdate()
		{
			if( ennemyTab.lenght >0 ) //tant quil reste des ennemies ca va augmenter time 
			{
				time = time + time.deltaTime
			}
		}
Hop Hop Hop!!

Ce code est faux.

Le FixedUpdate () est appelé à intervalle REGULIER, donc pour avoir la notion de temps, il faut additionner le fixedDeltaTime et pas le deltaTime.

D'un point de vue opti, il vaut mieux considérer la coroutine, car un Update () (ou FixedUpdate() ou LateUpdate ()) est lourd à exécuter et l'est A CHAQUE FRAME. Sauf si tu as déjà un Update () qui traine et donc que tu peux réutiliser pour figer ton timer, il vaut mieux éviter.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

siriusraine
Messages : 29
Inscription : 01 Mars 2017 21:53

Re: Comment figer un timer et récupérer le dernier temps enregistré

Message par siriusraine » 20 Mai 2021 12:47

boubouk50 a écrit :
20 Mai 2021 08:48

Hop Hop Hop!!

Ce code est faux.

Le FixedUpdate () est appelé à intervalle REGULIER, donc pour avoir la notion de temps, il faut additionner le fixedDeltaTime et pas le deltaTime.

D'un point de vue opti, il vaut mieux considérer la coroutine, car un Update () (ou FixedUpdate() ou LateUpdate ()) est lourd à exécuter et l'est A CHAQUE FRAME. Sauf si tu as déjà un Update () qui traine et donc que tu peux réutiliser pour figer ton timer, il vaut mieux éviter.

je te remercie de me corriger

Répondre

Revenir vers « Scripting »