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

时间:2019-03-13 11:38:52

标签: c# unity3d coroutine

我正在尝试从GameController.cs脚本访问协程,协程位于我的DatabaseManager.cs脚本中。我正在尝试像这样访问协程:

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

这给了我一个空引用异常。 我知道一切都在我尝试访问的协程中正常运行,因为这些脚本与我创建的另一个项目完全相同,唯一的区别是在另一个项目中我通过动画事件调用了协程,但效果很好,但是试图通过该项目中的代码调用它给了我这个问题。

数据库管理器脚本已附加到Player游戏对象上

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脚本

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;
    }
}

1 个答案:

答案 0 :(得分:4)

如果DatabaseManager是单一行为,则不应使用new关键字实例化它。 正确方法:

AddComponent<DatabaseManager>();

如果使用new关键字创建MonoBehaviour,则调用将在运行时失败。这是因为MonoBehaviour是一个组件,并且需要附加到GameObject上,这是人们讨厌统一的序列化的原因之一,因为您需要一个容器类来存储Monobehaviours字段和属性

使用方法:

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

如果您在执行此操作的游戏对象上做爱,并且在单一行为中做爱

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