[DB]Problème gestion des points de vie.

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
effect42
Messages : 3
Inscription : 24 Nov 2021 19:54

[DB]Problème gestion des points de vie.

Message par effect42 » 25 Nov 2021 17:26

Bonjour,

Je me permet d'ouvrir un sujet car après de nombreuse recherches je ne trouve pas de solution a mon problème .

Je m'explique :
Je débute sur unity et en C# je cherche a faire un système de gestion des points de vie simple, pour le moment rien de visuel (pas de jauge ect ) que du code,
Ce que je cherche a faire n'est certainement pas la meilleurs méthode mais c'est surtout pour me faire la main.

Voila mon script :

gameManager:

Code : Tout sélectionner

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

public class gameManager : MonoBehaviour
{
    public static gameManager instance;
    
    public List<int> lifePointList = new List<int>();

    public int lifePointJaune= 150;
    public int lifePointRouge= 200;

    public int lifePoint;
    public int dmg = 50;
    
    public void Awake()
    {
        if (instance != null)
        {
            Debug.LogWarning("Il y a plus d'une inscance de GameManager dans la scene");
            return;
        }

        instance = this;
    }

    public void Start()
    {
        lifePointList.Add(lifePointJaune);
        lifePointList.Add(lifePointRouge);
    }

    public void cliqueAttaque()
    {
       lifePoint -= dmg;
       Debug.Log("attaque");
    }
}


le scripte de l'ennemie :

Code : Tout sélectionner

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

public class jaune : MonoBehaviour
{
    public int lifePoint;

    public void Start()
    {
        lifePoint = gameManager.instance.lifePointList[0];
    }

    public void Update()
    {

        if (lifePoint <= 0)
        {
            Destroy(this);
        }
    }

    void OnMouseDown()
    {
        gameManager.instance.cliqueAttaque();
        
    }

    
}

Je cherche a faire en sorte que la variable "lifePoint" du script "gameManager" de la fonction "cliqueAttaque" soit "vide",
c'est a dire qu'elle soit définit seulement dans le deuxième script "jaune",

en gros je voudrai crée une fonction que je pourrait réutiliser dans tout les scripts de mes ennemis (1 scripts par ennemis) et que la valeur lifePoint de cliqueAttaque soit celle du script sur laquelle elle est appliqué ,

donc pas de GetComponent<jaune>.lifePoint par exemple puisque je ne veux pas définir dans la fonction cliqueAttaque de quelle lifePoint il est question.

Je ne sais pas si ma question est claire si vous avez une solution ou un moyen d'optimiser je prend aussi.

merci d'avance.

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

Re: [DB]Problème gestion des points de vie.

Message par jmhoubre » 26 Nov 2021 01:15

Bonsoir,

généralement, que ce soit pour un joueur ou un ennemi, on écrit un script Health qui gère la santé. Il est attaché au joueur et à chaque ennemi, ou mieux, à leur prefab.

Toujours généralement, ce script Health contient une fonction du genre :

Code : Tout sélectionner

public void TakeDamages(int amount)
{
	currentHealth -= amount; // En supposant que currentHealth soit le total des points de vie du porteur du script.
	if (currentHealth <= 0)
	{
		Die(); // Cette fonction contient la gestion du décès du porteur du script : son, musique, destruction de l'objet, etc...
	}
}
Quel est le but de ta liste lifePoint ? De lifePointJaune et de lifePointRouge ?

Si ta fonction Clique Attaque est modifiée comme ceci :

Code : Tout sélectionner

public int cliqueAttaque (int life)
{
	life -= dmg;
	Debug.Log("attaque");
	return life;
}
et que tu l'appelles ainsi :

Code : Tout sélectionner

	void OnMouseDown ()
	{
        	lifePoint = gameManager.instance.cliqueAttaque (lifePoint);        
	}
je pense que cela devrait résoudre ton problème (si je l'ai bien compris). Mais cette façon de faire est assez peu conventionnelle (une classe doit faire les traitements de sa responsabilité : ici tu demandes à GameManager de gérer les données de la classe jaune (qui devrait se nommer Jaune, avec une majuscule).

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6186
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB]Problème gestion des points de vie.

Message par boubouk50 » 26 Nov 2021 09:35

Je pense également qu'au delà du code pur, il y a un souci de conception, d'architecture du code.

Soit tu références, dans ce cas, la référence est connue donc accessible.
Soit tu ne références pas, dans ce cas, toutes les cibles possibles sont affectées, et le détermination se fait dans leur classe. Dans ce cas, je passerai par un événement (Event) qui envoie l'information de lifePoint ou de damage et seuls les objets qui veulent l'information s'abonne à celle-ci.

Code : Tout sélectionner

public class gameManager : MonoBehaviour
{
        #region Events
        //Event
        public delegate void DamageEvent (int dmg);
        public static event DamageEvent OnDamageDone;
        #endregion
        
        ...
        
	public void cliqueAttaque()
	{
		// OnDamageDone? si un objet est abonné (onDamageDone non null)
		// .Invoke (dmg) alors on lève un événement qui envoie la donnée dmg
		OnDamageDone?.Invoke (dmg);
		Debug.Log("attaque");
	}
}

Code : Tout sélectionner

public class Jaune : MonoBehaviour
{
	...
	// S'abonner à l'événement pour recevoir des dommages
	public void RendreDommageable ()
	{
		gameManager.Instance.OnDamageDone += RecevoirDamage;
	}
	
	// Se désabonner pour ne plus recevoir de dommages
	public void RetirerDommageable ()
	{
		gameManager.Instance.OnDamageDone -= RecevoirDamage;
	}
	
	// Fonction appelée lorsqu'un événement est levé
	private void RecevoirDamage (int _dmg)
	{
		lifePoint -= _dmg;
		if (lifePoint <= 0)
		{
			// Définir ici la mort de cet ennemi -> Animation / Destruction / Xp / etc
		}
	}
}
Aussi, IMPORTANT.
Essaie de respecter une convention de nommage. Par convention, les classes/types/fonctions commencent par une majuscule et les variables par un minuscule. Cela facilite la lecture et la compréhension.
"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

effect42
Messages : 3
Inscription : 24 Nov 2021 19:54

Re: [DB]Problème gestion des points de vie.

Message par effect42 » 26 Nov 2021 13:58

Merci pour vos réponse ,

jmhoubre:

Concernant ton script health je ne suis pas sur de bien comprendre (désolé je débute) :

Code : Tout sélectionner

public void TakeDamages(int amount)
Pourrait tu m'expliqué pourquoi la variable amount ce trouve a la fin de la fonction entre les parenthèses?

dans cette exemple ou définir les variables amount (qui correspond au dégât a appliquer je suppose) et currentHealth ?
directement dans le script (health)?

- Quel est le but de ta liste lifePoint ? De lifePointJaune et de lifePointRouge ?

La list lifePoint n'a rien avoir avec ma question c'est juste un test que j'aurai du supprimer pour rendre ma question plus claire.

Ensuite concernant la modification de ma fonction clique attaque :

sa ne fonctionne pas ni les dmg ni le debug.log ne sont appliquer lors du clique j'ai du louper quelque chose :

Code : Tout sélectionner

    public int cliqueAttaque(int life)
    {
       life -= dmg;
       Debug.Log("attaque");
       return life;

Code : Tout sélectionner

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

public class jaune : MonoBehaviour
{
    public int lifePoint = 150;
   

    public void Start()
   {
      

   }

    void OnMouseDown()
    {
        lifePoint = gameManager.instance.cliqueAttaque (lifePoint);
        
    }

    
}
boubouk50 :

Ta solution est complexe je ne maitrise et ne comprend pas tout ton code (notamment toute les notions "d'events") ,
je vais etudier et tester tout sa avant de te répondre.

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

Re: [DB]Problème gestion des points de vie.

Message par jmhoubre » 27 Nov 2021 12:07

Bonjour,
as-tu suivi un tuto de C# ? A mon avis, ce serait très profitable. Par exemple cette série en français est plutôt bien faite.

Ce sujet liste pas mal de vidéos destinées aux débutants, tu peux également aller le parcourir.

Pour répondre à ta question, la fonction a un paramètre entier, qui indique le nombre de points de vie ôtés. Une fonction peut avoir un ou plusieurs paramètres, ou zéro. Ne pas confondre avec la valeur de retour.

Code : Tout sélectionner

private void ZeroParametres () { } // Pas de paramètres, ne renvoie rien.
private  int ZeroParametres2 () { } // Pas de paramètres, renvoie un entier.
private int Add (int p1, int p2) // 2 paramètres, renvoie un entier.
{
	return a + b;
}
La variable qui est passée en paramètre n'a pas besoin d'être déclarée ailleurs : c'est en quelque sorte l'écriture de la fonction qui le fait. Tu peux appeler ces fonctions avec des valeurs fixes ou des variables :

Code : Tout sélectionner

private int testA = 12;
private int testB = 2;
private int testC;

private Start ()
{
	ZeroParametres ();
	testC = ZeroParametres2 ();
	testC = Add (testA, testB);
	testC = Add (54, testA);
}

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

Re: [DB]Problème gestion des points de vie.

Message par jmhoubre » 27 Nov 2021 12:38

Pour le code, je n'avais pas modifié le code de ta fonction cliqueAttaque, je ne voyais pas trop ce que tu voulais.

Voici du code retouché et testé :
Sur un empty, le script GameManager (note la majuscule : c'est une classe) :

Code : Tout sélectionner

using UnityEngine;

public class GameManager : MonoBehaviour
{
	public static GameManager instance;
	
	public int damages = 10;

	// Mise en place d'un singleton.
	public void Awake ()
	{
		if (instance != null)
		{
			Debug.LogWarning ("Il y a plus d'une instance de GameManager dans la scène.");
			return;
		}

		instance = this;
	}

	// La fonction reçoit de l'ennemi sa vie actuelle, déduit les dégâts, et renvoie la nouvelle vie.
	public int CliqueAttaque (int life)
	{
		Debug.Log ("Attaque.");
		life -= damages;
		return life;
	}
}
Un ou plusieurs cubes standarts d'Unity reçoivent le script Health :

Code : Tout sélectionner

using UnityEngine;

public class Health : MonoBehaviour
{
	public int currentHealth = 50;

	private void Start ()
	{
		Debug.Log ("Health Start.");
	}

	private void OnMouseDown ()
	{
		Debug.Log ("OnMouseDown.");
		currentHealth = GameManager.instance.CliqueAttaque (currentHealth);
		if (currentHealth <= 0)
		{
			Die ();
		}
	}

	// On matérialise la fonction Die par un changement de couleur de l'objet.
	private void Die ()
	{
		Debug.Log ("Die.");
		GetComponent<Renderer> ().material.color = Color.red;
	}
}

effect42
Messages : 3
Inscription : 24 Nov 2021 19:54

Re: [DB]Problème gestion des points de vie.

Message par effect42 » 29 Nov 2021 19:35

jmhoubre :

J'ai déjà regardé les tutos de tuto unity fr mais j'ai peu être pas tout mémoriser a 100 mais je continu de regarder des tutos.

tes exemples mon beaucoup aidée c’était exactement ce que je cherchais a faire merci :super: .

Par contre maintenant j'ai un autre problème :
J'aimerai placer la variable damage en argument comme ceci :

Code : Tout sélectionner

public int cliqueAttaque(int life,int damage)
    {
       
       Debug.Log("attaque");
       life -= damage;
       return life;
      
    }
probleme je ne sais pas comment exprimer le deuxieme argument :

Code : Tout sélectionner

public class rouge : MonoBehaviour
{
    public int lifePoint = 50;
    public int damage = 10;

    public void Start()
    {
       
    }

    private void OnMouseDown()
    {
        lifePoint = GameManager.instance.cliqueAttaque(lifePoint);
        damage = GameManager.instance.cliqueAttaque(???);
        Debug.Log(lifePoint);
        if(lifePoint <= 0)
        {
            Destroy(gameObject);
        }
    }
    
    
}
Je me demande aussi comment aller chercher la variable "damage" dans un troisième script attaché a mon personnage (et a terme a d'autre personnage jouable).


Répondre

Revenir vers « Scripting »