probleme de destruction d'asset

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Répondre
DraGDarK
Messages : 5
Inscription : 10 Fév 2021 12:48

probleme de destruction d'asset

Message par DraGDarK » 11 Fév 2021 12:27

Bonjour. je suis lycéen et je commence a utiliser Unity. Je travail sur un projet de shoot'em up. Mais j'ai un problème dans un de mes script. Ce script est celui du joueur(du vaisseaux). Je voudrai crée une attaque spécial qui se recharge au bout de 5 secondes. Cette partie là fonctionne. Mais je voudrais qu'un symbole s'affiche sur l'écran lorsque l'attaque spécial est entièrement chargé. Et que se symbole se détruise lorsque l'attaque spécial est décharger. Le Game Object représentant le symbole, se nomme <bouttonM>. Mon script crée un clone du bouttonM, mais lorsque je veux qu'il soit détruit, cela détruit le Game Object est non son clone qui a été crée pour la partie du joueur. Je voudrai savoir si vous pourriez m'aider? S'il vous plaît.

Code : Tout sélectionner

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

public class player : MonoBehaviour {
	
	float axeX;
	float axeY;
	float vitesse;
	public GameObject tir;
	public GameObject acide;
	public GameObject explosion; //Modèle d'explosion à faire apparaître
	static public int Argent;
	public Text texteArgent;
	public int jump = (2);
	public GameObject wings;
	static public int hasWings;
    public GameObject attaqueSpeciale;
    public float decompte = 0;
    public GameObject bouttonM;
    public bool boutonM;
    public bool boutonMM = true;
    public bool boutonabc = true;
    private Object tempbouttonM;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (decompte > 0)
        {
            boutonM = true;
            decompte -= Time.deltaTime;
        }

        Debug.Log(Argent);
		texteArgent.text=":"+Argent;
		
		if (hasWings==0)
		{
		wings.GetComponent<SpriteRenderer>().enabled=false;
		}
		else
		{
	    wings.GetComponent<SpriteRenderer>().enabled=true;
	    }

        if (decompte <= 0)
        {
            boutonabc = true;
        }

        if (decompte <= 0)
        {
            if (boutonMM == true)
            {
                GameObject tempbouttonM = Instantiate(bouttonM, this.transform.position + new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0));
                boutonMM = false;
            }
        }

        if (boutonabc == false)
        {
            Destroy(bouttonM);
        }


        vitesse = 9;
        axeX = Input.GetAxis("Horizontal")*vitesse;
	    axeY = Input.GetAxis("Vertical")*vitesse;
		
		this.GetComponent<Rigidbody2D>().velocity = new Vector2(axeX,axeY);  
		 
		 if (Input.GetKeyDown("m"))   // Enlevé le KeyDown pour tirer en rafale
		{
            if (decompte <= 0)
            {
                decompte = 5;
                boutonM = false;
                boutonabc = false;
                GameObject tempattaqueSpeciale = Instantiate(attaqueSpeciale, this.transform.position, Quaternion.identity);
                tempattaqueSpeciale.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 20);   // Rajouter un cosinius pour faire un tire trod cool mais encore mieux en rafales.
			    Destroy(tempattaqueSpeciale, 6);
            }
        }

        if (Input.GetKeyDown("space"))   // Enlevé le KeyDown pour tirer en rafale
        {
            GameObject tempTir = Instantiate(tir, this.transform.position, Quaternion.identity);
            tempTir.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 20);   // Rajouter un cosinius pour faire un tire trod cool mais encore mieux en rafales.
            Destroy(tempTir, 3);
        }
    }		
    void OnTriggerEnter2D (Collider2D from)
	{
		 if (from.gameObject.tag=="Acide") //Si ce n'est pas un alien qui a touché
		{
	    GameObject tempExplosion=Instantiate (explosion, this.transform.position, Quaternion.identity); //Apparition d'une explosion
	    Destroy(tempExplosion, 0.3f); 	//Disparition programmée de l'explosion
		Destroy (this.gameObject);		//Disparition de l'objet
		Destroy (from.gameObject); 
		}		//Disparition du tir ayant touché l'objet 		
	}
}

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

Re: probleme de destruction d'asset

Message par jmhoubre » 11 Fév 2021 12:54

Le programme faiit ce que tu lui demandes. Destroy(bouttonM) détruit le modéle. Si tu veux détruire le clone, tu devrais utiliser Destroy (tempbouttonM ).

Un conseil : tu devrais faire un effort sur le nommage de tes variables. Quelques points à éviter :
  • mélanger l'anglais et le français. Il est d'usage d'utiliser l'anglais, mais si tu comptes travailler tout seul toute ta vie et ne jamais aller sur des forums étrangers, le français peut convenir.
  • ne pas avoir de convention de nommage. La doc de Microsoft a un article assez complet sur le nommage. Quelques règles à respecter :
    • camelCase pour les variables (donc argent et pas Argent)
    • PascalCase pour les classes, les fonctions, les propriétés....
  • des noms trop proches comme boutonM et boutonMM, ou boutonM et bouttonM
  • un nom de variable peu compréhensible : boutonM, boutonMM et boutonabc ne donnent pas d'indication sur leur utilité. S'il faut un commentaire pour préciser à quoi sert la variable, c'est que le nom de la variable n'est pas bon. Ne pas hésiter à avoir 10 ou 15 lettres dans un nom de variables, l'autocomplétion n'a pas été inventée pour rien.
Un autre conseil est de limiter une classe à une chose. Ton script pourrait par exemple être divisé en PlayerStats, PlayerMove et PlayerAttack.

DraGDarK
Messages : 5
Inscription : 10 Fév 2021 12:48

Re: probleme de destruction d'asset

Message par DraGDarK » 11 Fév 2021 21:18

Merci beaucoup de m'avoir répondu. Mais lorsque je remplace la ligne:

Destroy(bouttonM)

par:

Destroy(tempbouttonM)

La console me dit que le GameObject tempbouttonM n'existe pas alors que je l'ai crée quelque ligne avant.
J’espère vraiment que quelqu'un m’aidera. En tout cas vraiment merci d'avoir répondu si rapidement.

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

Re: probleme de destruction d'asset

Message par jmhoubre » 11 Fév 2021 21:54

Oui, il faut remonter la déclaration de cet objet au bon endroit, soit au début de la méthode Update, soit au début de la classe, car il est déclaré dans un if, la variable tempbouttonM est donc locale à ce if, et par conséquent inconnue dans le bloc if de destruction (un bloc, c'est le code entre deux accolades { bloc }).

Code : Tout sélectionner

if (decompte <= 0)
{
	// Bloc de déclaration.
        if (boutonMM == true)
        {
        	GameObject tempbouttonM = Instantiate(bouttonM, this.transform.position + new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0));
                boutonMM = false;
        }
}

// Bloc de destruction.
if (boutonabc == false)
{
	Destroy(tempbouttonM );
}

A remplacer par :

Code : Tout sélectionner

private void Update ()
{
	// On déclare ici.
	GameObject tempbouttonM;

	if (decompte <= 0)
	{
		// Bloc de déclaration.
	        if (boutonMM == true)
        	{
        		// Supprimer GameObject !
        		tempbouttonM = Instantiate(bouttonM, this.transform.position + new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0));
                	boutonMM = false;
        	}
	}

	// Bloc de destruction.
	if (boutonabc == false)
	{
		Destroy(tempbouttonM );
	}
}

DraGDarK
Messages : 5
Inscription : 10 Fév 2021 12:48

Re: probleme de destruction d'asset

Message par DraGDarK » 12 Fév 2021 12:37

Encore merci de m'avoir répondu. Mais le script ne marche pas. j'ai noté la même chose. Mais la console me renvoi <Assets \ script \ player.cs (52,21): erreur CS0165: Utilisation de la variable locale non attribuée 'tempbouttonM'>.
je remet le script que j'ai modifié.

Code : Tout sélectionner

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

public class player : MonoBehaviour {
	
	float axeX;
	float axeY;
	float vitesse;
	public GameObject tir;
	public GameObject acide;
	public GameObject explosion; //Modèle d'explosion à faire apparaître
	static public int argent;
	public Text texteArgent;
	public int jump = (2);
	public GameObject wings;
	static public int hasWings;
    public GameObject attaqueSpeciale;
    public float decompte = 0;
    public GameObject bouttonM;
    public bool boutonM;
    public bool boutonMM = true;
    public bool boutonABC = true;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    private void Update ()
    {
        //On déclare ici.
        GameObject tempbouttonM;

        if (decompte <= 0)
        {
            //Bloc de déclaration.
            if (boutonMM == true)
            {
                tempbouttonM = Instantiate(bouttonM, this.transform.position + new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0));
                boutonMM = false;
            }
        }

        // Bloc de destruction.
        if (boutonABC == false)
        {
            Destroy(tempbouttonM );
        }

        if (decompte > 0)
        {
            boutonM = true;
            decompte -= Time.deltaTime;
        }

        Debug.Log(argent);
		texteArgent.text=":"+argent;
		
		if (hasWings==0)
		{
		wings.GetComponent<SpriteRenderer>().enabled=false;
		}
		else
		{
	    wings.GetComponent<SpriteRenderer>().enabled=true;
	    }

        if (decompte <= 0)
        {
            boutonABC = true;
        }

        vitesse = 9;
        axeX = Input.GetAxis("Horizontal")*vitesse;
	    axeY = Input.GetAxis("Vertical")*vitesse;
		
		this.GetComponent<Rigidbody2D>().velocity = new Vector2(axeX,axeY);  
		 
		 if (Input.GetKeyDown("m"))   // Enlevé le KeyDown pour tirer en rafale
		{
            if (decompte <= 0)
            {
                decompte = 5;
                boutonM = false;
                boutonABC = false;
                GameObject tempattaqueSpeciale = Instantiate(attaqueSpeciale, this.transform.position, Quaternion.identity);
                tempattaqueSpeciale.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 20);   // Rajouter un cosinius pour faire un tire trod cool mais encore mieux en rafales.
			    Destroy(tempattaqueSpeciale, 6);
            }
        }

        if (Input.GetKeyDown("space"))   // Enlevé le KeyDown pour tirer en rafale
        {
            GameObject tempTir = Instantiate(tir, this.transform.position, Quaternion.identity);
            tempTir.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 20);   // Rajouter un cosinius pour faire un tire trod cool mais encore mieux en rafales.
            Destroy(tempTir, 3);
        }
    }

    void OnTriggerEnter2D (Collider2D from)
	{
		 if (from.gameObject.tag=="Acide") //Si ce n'est pas un alien qui a touché
		{
	    GameObject tempExplosion=Instantiate (explosion, this.transform.position, Quaternion.identity); //Apparition d'une explosion
	    Destroy(tempExplosion, 0.3f); 	//Disparition programmée de l'explosion
		Destroy (this.gameObject);		//Disparition de l'objet
		Destroy (from.gameObject); 
		}		//Disparition du tir ayant touché l'objet 		
	}
}


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

Re: probleme de destruction d'asset

Message par jmhoubre » 12 Fév 2021 21:09

Le C# demande que les variables locales soient initialisées :

Code : Tout sélectionner

GameObject tempbouttonM = null;

DraGDarK
Messages : 5
Inscription : 10 Fév 2021 12:48

Re: probleme de destruction d'asset

Message par DraGDarK » 13 Fév 2021 12:55

Bonjour. j'ai crée un script avec uniquement le code pour l'attaque spécial. Mais si je mets la variable en public, la console me dit <Assets\script\SuperAttaque.cs(42,21): error CS0165: Use of unassigned local variable 'TempbouttonM'>. Si je la mets en private, la console me dit <Assets\script\SuperAttaque.cs(42,21): error CS0165: Use of unassigned local variable 'TempbouttonM'>. Et si je ne mets ni public ni private, la console me met<Assets\script\SuperAttaque.cs(15,16): warning CS0414: The field 'SuperAttaque.TempbouttonM' is assigned but its value is never used>. Je n'y arrive pas du tout. Si vous pourriez me ré-expliquer s'il vous plaît.

Code : Tout sélectionner

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

public class SuperAttaque : MonoBehaviour
{
    public GameObject attaqueSpeciale;
    public float decompte = 0;
    public GameObject bouttonM;
    public bool boutonM;
    public bool boutonMM = true;
    public bool boutonABC = true;
    GameObject TempbouttonM = null;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        //On déclare ici.
        GameObject TempbouttonM;

        if (decompte <= 0)
        {
            //Bloc de déclaration.
            if (boutonMM == true)
            {
                TempbouttonM = Instantiate(bouttonM, this.transform.position + new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0));
                boutonMM = false;
            }
        }

        // Bloc de destruction.
        if (boutonABC == false)
        {
            Destroy(TempbouttonM);
        }

        if (decompte > 0)
        {
            boutonM = true;
            decompte -= Time.deltaTime;
        }

        if (decompte <= 0)
        {
            boutonABC = true;
        }

        if (Input.GetKeyDown("m"))   // Enlevé le KeyDown pour tirer en rafale
        {
            if (decompte <= 0)
            {
                decompte = 5;
                boutonM = false;
                boutonABC = false;
                GameObject tempattaqueSpeciale = Instantiate(attaqueSpeciale, this.transform.position, Quaternion.identity);
                tempattaqueSpeciale.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 20);   // Rajouter un cosinius pour faire un tire trod cool mais encore mieux en rafales.
                Destroy(tempattaqueSpeciale, 6);
            }
        }
    }
}


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

Re: probleme de destruction d'asset

Message par Max » 13 Fév 2021 13:21

Bonjour,

tu déclares deux fois cette donnée. TempbouttonM est déclarée en global et en local (dans Update).
D’où le soucis.
La locale est prioritaire, et dans ton code tu peux très bien rentrer dans ta condition if (boutonABC == false) sans jamais être passer par l'ensemble de conditions amenant à l'instanciation. Et tu te retrouveras avec un beau NullReference lors du Destroy(TempbouttonM);, d’où l'erreur signalée.
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

DraGDarK
Messages : 5
Inscription : 10 Fév 2021 12:48

Re: probleme de destruction d'asset

Message par DraGDarK » 13 Fév 2021 22:30

Merci beaucoup pour vôtre aide. La console ne me met plus de message d'erreur. Mais l'asset ne se détruit pas. Et je ne comprend pas le problème, est ce que vous pourriez m'aider encore un peu?

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

Re: probleme de destruction d'asset

Message par Max » 14 Fév 2021 11:17

apparemment, la destruction de TempbouttonM est liée à cette condition: if (boutonABC == false).
Si cela ne se produit jamais, c'est que cette condition ne se vérifie jamais. A toi de voir pourquoi.
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

Répondre

Revenir vers « Scripting »