Page 1 sur 1

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

Publié : 21 Août 2020 13:19
par Murdeau
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?

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

Publié : 21 Août 2020 13:45
par boubouk50
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.

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

Publié : 22 Août 2020 10:25
par Murdeau
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.