简体   繁体   English

启动协程统一给出空引用异常

[英]starting Coroutine gives null reference exception in unity

I am trying to access a Coroutine from my GameController.cs script, the Coroutine is located in my DatabaseManager.cs script. 我试图从我的GameController.cs脚本访问协GameController.cs ,协程位于我的DatabaseManager.cs脚本中。 I am trying to access the Coroutine like this: 我正在尝试像这样访问协程:

 DatabaseManager d1 = new DatabaseManager();
 d1.uploadData();

This is giving me a null reference exception. 这给了我一个空引用异常。 I know that everything works like it should in the coroutine I am trying to access because these scripts are the exact same from another project I made, the only difference is in the other project I called the coroutine through an animation event which worked fine, but trying to call it through code in this project is giving me that issue. 我知道一切都在我尝试访问的协程中正常运行,因为这些脚本与我创建的另一个项目完全相同,唯一的区别是在另一个项目中我通过动画事件调用了协程,但效果很好,但是试图通过该项目中的代码调用它给了我这个问题。

The Database manager script is attached to the Player game object 数据库管理器脚本已附加到Player游戏对象

DatabaseManager script DatabaseManager脚本

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using UnityEngine.UI;
using CompanionLibrary; //include my library to utilise its functions
//use neccessary libraries.




    //This class handles sending game data to the database.
    public class DatabaseManager : MonoBehaviour
    {


        //declare variables to hold data values.
        static string username;
        string password;
        int score =0;
        int kills=0;  //initialise variables to 0 
        int bulletsFired=0;
        int bulletsHit=0;
        int bulletsMissed=0;
        int timePlayed = 0;
        int scorePerMin=0;
        StatGeneration companion = new StatGeneration();
        //On awake function to check if sign in or logged in booleans are set.
        public void Awake()
        {


        if (ButtonManagers.signedUp == true) //if signedUp boolean is true....
            {
                username = ButtonManagers.signUpUsername; //assign the username to equal the signUpUsername value.
                password = ButtonManagers.signUpPassword; //assign the password to equal the signUpPassword value.
            Debug.Log("Username: " + username);
            Debug.Log("Password: " + password);
        }

            //if loggedIn boolean is true....
            if (ButtonManagers.loggedIn == true)
            {
                username = ButtonManagers.loginUsername;//assign the username to equal the loggedInUsername value.
                password = ButtonManagers.loginPassword;//assign the password to equal the loggedInPassword value.
            }
        }

        //the function uploadData gets called in an AnimationEvent when the user dies.
        public void uploadData()
        {
        //As this gets called when the game ends, make sure the players stats are stored.
        kills = DestroyByContact.kills;
        score = GameController.score;
        bulletsFired = PlayerController.bulletsFired;
        bulletsHit = DestroyByContact.bulletsHit;
        bulletsMissed = DestroyByContact.bulletsMissed;
        timePlayed = TimeManager.time;
        scorePerMin = companion.TPS_scorePerMinTime(timePlayed);
        StartCoroutine(SendPlayerData()); //Start the Coroutine Upload.
    }


    IEnumerator SendPlayerData()
        {
            if (ButtonManagers.loggedIn==false)
            {
                //instantiate my library
                Debug.Log("Time in seconds: " + timePlayed);
                Debug.Log(companion.TPS_hitAccuracy(bulletsHit, bulletsFired) + "percent bullet accuracy");
                Debug.Log("Score per minute" + companion.TPS_scorePerMin(score,scorePerMin));


                Debug.Log("Username: " + username);
                Debug.Log("Password: " + password);
                Debug.Log("Kills: " + kills.ToString());
                Debug.Log("score: " + score.ToString());
                Debug.Log("bulletsFired: " + bulletsFired.ToString());
                Debug.Log("bulletsHit: " + bulletsHit.ToString());
                Debug.Log("bulletsMissed: " + bulletsMissed.ToString());
                WWWForm form = new WWWForm();
                form.AddField("database", "2DS_STATS");
                form.AddField("username", username);
                form.AddField("password", password);
                form.AddField("kills", kills);
                form.AddField("bulletsFired", bulletsFired);
                form.AddField("bulletsHit", bulletsHit);
                form.AddField("bulletsMissed", bulletsMissed);
                form.AddField("score",score);
                form.AddField("hitAccuracy", companion.TPS_hitAccuracy(bulletsHit, bulletsFired));
                form.AddField("scorePerMinute", companion.TPS_scorePerMin(score, scorePerMin));
                form.AddField("timePlayed", companion.UNI_TimePlayed(timePlayed));
                UnityWebRequest www = UnityWebRequest.Post("http://u530535384.hostingerapp.com/insertGameData.php", form);
                yield return www.SendWebRequest();

                if (www.isNetworkError || www.isHttpError)
                {
                    Debug.Log(www.error);
                }
                else
                {
                    Debug.Log("Form upload complete!");
                    Debug.Log(www.downloadHandler.text);
                }
            }
            else
            {

                Debug.Log(companion.TPS_hitAccuracy(bulletsHit, bulletsFired) + "percent bullet accuracy");
                Debug.Log("Time in seconds: " + timePlayed);
                Debug.Log("Username: " + username);
                Debug.Log("Password: " + password);
                Debug.Log("Kills: " + kills.ToString());
                Debug.Log("score: " + score.ToString());
                Debug.Log("bulletsFired: " + bulletsFired.ToString());
                Debug.Log("bulletsHit: " + bulletsHit.ToString());
                Debug.Log("bulletsMissed: " + bulletsMissed.ToString());
                WWWForm form = new WWWForm();
                form.AddField("database", "2DS_STATS");
                form.AddField("username", username);
                form.AddField("password", password);
                form.AddField("kills", kills);
                form.AddField("bulletsFired", bulletsFired);
                form.AddField("bulletsHit", bulletsHit);
                form.AddField("bulletsMissed", bulletsMissed);
                form.AddField("score", score);
                form.AddField("hitAccuracy", companion.TPS_hitAccuracy(bulletsHit, bulletsFired));
                form.AddField("scorePerMinute", companion.TPS_scorePerMin(score, scorePerMin));
                form.AddField("timePlayed", companion.UNI_TimePlayed(timePlayed));
                UnityWebRequest www = UnityWebRequest.Post("http://u530535384.hostingerapp.com/updateUserStats.php", form);
                yield return www.SendWebRequest();

                if (www.isNetworkError || www.isHttpError)
                {
                    Debug.Log(www.error);
                }
                else
                {
                    Debug.Log("Form upload complete!");
                    Debug.Log(www.downloadHandler.text);
                }
            }
        }
    }

GameController Script GameController脚本

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

public class GameController : MonoBehaviour
{
    public GameObject hazard;
    public Vector3 spawnValues;
    public int hazardCount;
    public float spawnWait;
    public float startWait;
    public float waveWait;

    public Text scoreText;
    public Text restartText;
    public Text gameOverText;

    private bool gameOver;
    private bool restart;
    public static int score;

    void Start()
    {
        gameOver = false;
        gameOverText.text = "";
        score = 0;
        UpdateScore();
        StartCoroutine(SpawnWaves());
    }



    IEnumerator SpawnWaves()
    {
        yield return new WaitForSeconds(startWait);
        while (true)
        {
            for (int i = 0; i < hazardCount; i++)
            {
                Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
                Quaternion spawnRotation = Quaternion.identity;
                Instantiate(hazard, spawnPosition, spawnRotation);
                yield return new WaitForSeconds(spawnWait);
            }
            yield return new WaitForSeconds(waveWait);

            if (gameOver)
            {
                SceneManager.LoadScene("Main Menu");//load the game.
                Debug.Log("I was called");
                DatabaseManager d1 = new DatabaseManager();
                d1.uploadData();
            }
        }
    }

    public void AddScore(int newScoreValue)
    {
        score += newScoreValue;
        UpdateScore();
    }

    void UpdateScore()
    {
        scoreText.text = "Score: " + score;
    }

    public void GameOver()
    {
        gameOverText.text = "Game Over!";
        gameOver = true;
    }
}

If DatabaseManager is a monobehaviour then you should not instantiate it with the new keyword. 如果DatabaseManager是单一行为,则不应使用new关键字实例化它。 Correct way: 正确方法:

AddComponent<DatabaseManager>();

If the new keyword is used to create a MonoBehaviour, the call will fail at run time. 如果使用new关键字创建MonoBehaviour,则调用将在运行时失败。 This is because a MonoBehaviour is a component, and needs to be attached to a GameObject, this is one of the reason people hate serialization in unity, because you need a container class to store a monobehaviours fields and properties 这是因为MonoBehaviour是一个组件,并且需要附加到GameObject上,这是人们讨厌统一的序列化的原因之一,因为您需要一个容器类来存储Monobehaviours字段和属性

How to use: 如何使用:

DatabaseManager databaseManager = gameObject.AddComponent<DatabaseManager>();

If you aint on a gameobject where you do this, and you aint in a monobehaviour 如果您在执行此操作的游戏对象上作怪,并且在单一行为中作怪

var tempgameObject = new GameObject();
DatabaseManager databaseManager = tempgameObject.AddComponent<DatabaseManager>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM