我正在尝试从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;
}
}
答案 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);