【发布时间】:2019-08-04 01:53:40
【问题描述】:
我正在尝试从我的GameController.cs 脚本访问协程,该协程位于我的DatabaseManager.csscript 中。我正在尝试像这样访问协程:
DatabaseManager d1 = new DatabaseManager();
d1.uploadData();
这给了我一个空引用异常。 我知道在我尝试访问的协程中一切正常,因为这些脚本与我制作的另一个项目完全相同,唯一的区别是在另一个项目中我通过一个运行良好的动画事件调用协程,但是试图通过这个项目中的代码调用它给了我这个问题。
数据库管理器脚本附加到玩家游戏对象
数据库管理器脚本
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);
}
}
}
}
游戏控制器脚本
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;
}
}
【问题讨论】:
-
请发布异常堆栈跟踪
-
NullReferenceException UnityEngine.MonoBehaviour.StartCoroutine (IEnumerator routine) (at C:/buildslave/unity/build/Runtime/Export/MonoBehaviour.bindings.cs:88) DatabaseManager.uploadData () (at Assets/Scripts/DatabaseManager.cs:59) GameController+<SpawnWaves>c__Iterator0.MoveNext () (at Assets/Scripts/GameController.cs:53) UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)这就是它给我的,只是指向 startCoroutine() 函数 -
如果数据库管理器在播放器上,为什么要创建一个新的.. 除非你只使用默认选项,否则 null 是你需要设置的东西并且没有
-
我正在从游戏控制器类而不是 Player 实例化一个新的数据库管理器。将 new 关键字与 unity 一起使用是否有问题,这可能会阻止我以这种方式调用协程