[RESOLU][C# -- DB]NullReferenceException. Appel d'une fonction appartenant à un autre script

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

[RESOLU][C# -- DB]NullReferenceException. Appel d'une fonction appartenant à un autre script

Message par Murdeau » 21 Août 2020 13:19

Bonjour,

J'ai cette erreur :
NullReferenceException: Object reference not set to an instance of an object
ScriptDuJeu.Start () (at Assets/4Lecon01Aaa/AaaLecture/script/ScriptDuJeu.cs:48)

Lorsque le programme doit appeler une fonction qui se trouve dans le script ScriptTrophees, il m'affiche l'erreur ci dessus.
Voici mon script ScriptDuJeu allégé

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.IO;

public class ScriptDuJeu : MonoBehaviour
{
    public float espacement = 3.8f;
    [SerializeField] Transform cadreRire, cadreCri, cadreQuestion, buttonTrophees;  //pour récupérer transform de CadreRires, ... dans Hierarchy
    [SerializeField] GameObject textes;
    [SerializeField] Animator animTrophee;
    [SerializeField] List<int> NbresOrdonnes = new List<int>();  //Contiendra les nombres dans l'ordre de 0 à x
    [SerializeField] List<int> Tirage = new List<int>(); //Contiendra un classement aléatoire après tirage au sort
    [SerializeField] List<int> ResulTirPhraseMot = new List<int>(); //Contiendra le classement des mots/phrases après tirage au sort
    public List<int> ResulTirCadre = new List<int>(); //Contiendra le classement des cadres après tirage au sort
    public string[] ordreImages = new string[3];
    public bool affichageSuivant;
    private clicImage recupClicImage;               //pour récupérer le script clicImage
    private ScriptAccueil recupScriptAccueil;     //pour récupérer le script ScriptAccueil 
    private ScriptTrophees recupScriptTrophees;     //pour récupérer le script ScriptTrophees

    [SerializeField] Vector2 pos;
    public string quelTagQuestion;

    private void Awake()
    {
        animTrophee = GameObject.Find("/Canvas/PanelBasEcran/PanelRondsReussite").GetComponent<Animator>();
        recupScriptAccueil = FindObjectOfType<ScriptAccueil>();                 //recupScriptAccueil contient toutes les méthodes et variables du script ScriptAccueil
        recupClicImage = FindObjectOfType<clicImage>();                         //recupClicImage contient toutes les méthodes et variables du script clicImage
        recupScriptTrophees = FindObjectOfType<ScriptTrophees>();             //recupScriptTrophees contient toutes les méthodes et variables du script ScriptTrophees
        cadreRire = GameObject.Find("CadreRires").GetComponent<Transform>();
        cadreCri = GameObject.Find("CadreCris").GetComponent<Transform>();
        cadreQuestion = GameObject.Find("CadreQuestions").GetComponent<Transform>();
        textes = GameObject.Find("/Canvas/ImageFondTexte").gameObject;
    }
   
    void Start()
    {
        affichageSuivant = true;
        ordrePhraseMot(ResulTirPhraseMot);      //choix de l'odre d'affichage des mots ou des phrases
        StartCoroutine(boucleSuivante());       //utiliser une coroutine pour attendre entre chaque phrase/mot
        Debug.Log("nbcarottes = "+ recupClicImage.nbCarottes);
    }


    //choix de l'ordre d'affichage
    private void ordrePhraseMot(List<int> ResulTir)
    {
        ...
    }

    IEnumerator boucleSuivante()
    {
        //k corespnd au n° de la phrase qui est affichée
        for (int k = 0; k < 6; k++)
        {
            affichageSuivant = false;
            textes.transform.gameObject.SetActive(true);
            textes.transform.GetChild(ResulTirPhraseMot[k]).gameObject.SetActive(true);         //Afficher la phrase n°k
            quelTagQuestion = textes.transform.GetChild(ResulTirPhraseMot[k]).gameObject.tag;   //récupérer le tag de la phrase n°k
            ordreCadre(ResulTirCadre);                  //choix de l'odre d'affichage des cadres
            affichageCadres(k);                         //afficher les 3 cadres
            yield return new WaitUntil(vraiFaux);       //attendre que affichageSuivant soit vrai
            textes.transform.GetChild(ResulTirPhraseMot[k]).gameObject.SetActive(false);        //cacher la phrase
            desactiveImages();                          //cacher les images
        }
        if (recupClicImage.nbCarottes > 3)
        {
            Debug.Log("nbcarottes > 3");
            StartCoroutine(gagneTrophee4());        //utiliser une coroutine pour attendre la fin de l'animation
            recupScriptTrophees.RemplirTableau(14);     //LIGNE QUI POSE PROBLÈME
            recupScriptTrophees.SaveTrophees();		//LIGNE QUI POSE AUSSI PROBLÈME
        }
        else
        {
            yield return new WaitForSeconds(3f);    //attendre 3secondes
            recupScriptAccueil.Retour();             //revenir au menu précédent
        }
    }

    IEnumerator gagneTrophee4()
    {
        animTrophee.SetTrigger("Trophee4");         //jouer l'animation "Trophee4App"
        GetComponent<AudioSource>().Play();         //jouer le son gagnant
        yield return new WaitForSeconds(5f);        //attendre 3secondes
        animTrophee.SetTrigger("TropheeRepos");     //jouer l'animation "TropheeRepos"
        if (recupClicImage.nbCarottes == 6)
        {
            Debug.Log("nbcarottes = 6");
            StartCoroutine(gagneTrophees6());
            recupScriptTrophees.RemplirTableau(16);     //LIGNE QUI POSE PROBLÈME MAIS LE PROGRAMME S'ARRÊTE AVANT
            recupScriptTrophees.SaveTrophees();		//LIGNE QUI POSE AUSSI PROBLÈME
        }
        else
        {
            recupScriptAccueil.Retour();             //revenir au menu précédent
        }
    }
    IEnumerator gagneTrophees6()
    {
            animTrophee.SetTrigger("Trophee6");    //jouer l'animation "Trophee6App"
            GetComponent<AudioSource>().Play();                 //jouer le son gagnant
            yield return new WaitForSeconds(5f);    //attendre 3secondes
            animTrophee.SetTrigger("TropheeRepos");    //jouer l'animation "TropheeRepos"
            recupScriptAccueil.Retour();             //revenir au menu précédent
    }

    public bool vraiFaux()
    {
       ...
    }
    private void ordreCadre(List<int> ResulTir)
    {
        ....
    }
    //affichage des cadres. affichageCadres(n° de la phrase/mot affichée
    private void affichageCadres(int i)
    {
       ...
    }

    //donner aux cadres leur position. positionCadres(nom du cadre à placer, n° de la ligne à lire dans ResulTirCadre[], n° de la phrase/mot affichée)
    private void positionCadres(Transform cadre, int i, int j)
    {
        ...
    }

    //Remplie la liste Tirage
    private void TirageAuSort(int j)
    {
      ...
    }

    private void desactiveImages()
    {
        ...
    }

}
Les deux lignes qui posent problèmes (voir commentaire en Majuscules dans le script) ont été changées de place dans le programme, ont été interverties... Mais j'ai toujours le même message d'erreur.
Voici le script ScriptTrophees

Code : Tout sélectionner

using UnityEngine;
using UnityEngine.UI;
using System.IO;

/// <summary>
/// script attaché à 
/// </summary>
public class ScriptTrophees : MonoBehaviour
{
    [SerializeField] Image trophee1A, trophee1A6;  //pour récupérer transform des trophées dans sceneTrophees dans Hierarchy
    private string saveSeparator = "%VA%";
    public string[] data = new string[580];


    private void Awake()
    {
        if (File.Exists(Application.dataPath+"/dataTrophees.txt"))
        {
            Debug.Log("dataTrophees existe");
            LoadTrophees();
        }
           
        trophee1A = GameObject.Find("ImageLecon1A").GetComponent<Image>();       //récupère ImageLecon1A de Hierarchy
        trophee1A6 = GameObject.Find("ImageLecon1A6").GetComponent<Image>();       //récupère ImageLecon1A6 de Hierarchy
    }

    private void Start()
    {
        for (int i = 10; i < 15; i++)
        {
            if (data[i] == "1")
            {
                trophee1A.transform.GetChild(i-10).gameObject.SetActive(true);     //active le trophée 1A4
            }
        }
        if (data[16] == "1")
        {
            trophee1A6.transform.GetChild(0).gameObject.SetActive(true);     //active le trophée 1A6
        }
    }
    private void LoadTrophees()
    {
        string saveString = File.ReadAllText(Application.dataPath + "/dataTrophees.txt");
        data = saveString.Split(new[] { saveSeparator }, System.StringSplitOptions.None);
    }

    public void SaveTrophees()
    {
        Debug.Log("SaveTrophees");
        string saveString = string.Join(saveSeparator, data);
        File.WriteAllText(Application.dataPath + "/dataTrophees.txt", saveString);
    }

    public void RemplirTableau(int v)
    {
        Debug.Log("data["+ v +"]");
        data[v] = "1";
    }
}

Je n'arrive pas à comprendre ce qui cloche. quelqu'un a une idée? Merci.

Ps: ScriptTrophees est attaché à un gameObject d'une autre scène, cela pourrait-il poser problème?
Dernière édition par Murdeau le 22 Août 2020 10:26, édité 1 fois.

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

Re: [C# -- DB]NullReferenceException. Appel d'une fonction appartenant à un autre script

Message par boubouk50 » 21 Août 2020 13:45

Salut,
je vais me cantonner qu'à l'erreur:
NullReferenceException: Object reference not set to an instance of an object
ScriptDuJeu.Start () (at Assets/4Lecon01Aaa/AaaLecture/script/ScriptDuJeu.cs:48)


Decryptage: Dans la fonction Start () de la classe ScriptDuJeu, à la ligne 48, tu as une référence (une variable donc) qui est nulle et tu essaies d'atteindre quelque chose depuis celle-ci.

Quelle est donc cette ligne?
Il pourrait s'agir de recupClicImage qui n'est pas trouvé par ton Find (donc reste null), tu ne peux donc pas accéder à nbCarottes.
"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

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

Re: [C# -- DB]NullReferenceException. Appel d'une fonction appartenant à un autre script

Message par Murdeau » 22 Août 2020 10:25

Bonjour et merci pour ton aide.
boubouk50 a écrit :
21 Août 2020 13:45
Il pourrait s'agir de recupClicImage qui n'est pas trouvé par ton Find (donc reste null), tu ne peux donc pas accéder à nbCarottes.
Non, il ne s'agit pas de recupClicImage mais de recupScriptTrophees qui n'est pas trouvé.
Mais j'ai trouvé pourquoi. Comme indiqué dans mon Post Scriptum, c'est parce que je n'ai pas assigné le script ScriptTrophees à un gameObject de la scène mais à un gameObject d'une autre scène.
Une fois assigné à n'importe quel gamObject de ma scene, mon jeu fonctionne.

Un grand merci pour m'avoir aidé aussi rapidement.

Répondre

Revenir vers « Scripting »