I am new to Unity and I am working on a car game project. I have pretty much finished the game however I would like to implement a leader board system in order for the user to see how well they've done in the past. I have already written the code to store all of this information in PlayerPrefs however I am not able to figure out why I am getting the error
Код: Выделить всё
NullReferenceException: Object reference not set to an instance of an object
CarController.Start () (at Assets/Scripts/CarController.cs:22)
Код: Выделить всё
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using static System.Net.Mime.MediaTypeNames;
public class LeaderboardManager : MonoBehaviour
{
private const string highScoreKey = "highScores"; //Key for the player prefs reference
private const int maxScores = 10; //Constant for the maximum amount of high scores
public List highScores = new List{};
public TextMeshProUGUI leaderboardText; //Reference to the UI Text component
MergeSort mergeSort = new MergeSort();
void Start()
{
leaderboardText = GetComponentInChildren();
if (!PlayerPrefs.HasKey(highScoreKey)) //Make new blank key in playerprefs if there isn't one already
{
PlayerPrefs.SetString(highScoreKey, "");
}
else //Load scores from playerprefs
{
string json = PlayerPrefs.GetString(highScoreKey); //Get string from player prefs storage
highScores = JsonUtility.FromJson(json); //Convert string to list so merge sorts can be applied
}
}
void Update()
{
updateUI();
}
private void saveScores()
{
string json = JsonUtility.ToJson(highScores); //Save list data type to json as a string so it can be stored
PlayerPrefs.SetString(highScoreKey, json); //Sets the playerprefs string to the new json highscore value
PlayerPrefs.Save(); //Saves the playerprefs file
}
public void addScore(int score)
{
highScores.Add(score);
MergeSort.MergeSortRecursive(highScores); //Merge sorts the highscore list
highScores = highScores.Take(maxScores).ToList(); //Takes only the first 10 values of the list and discards the rest
saveScores(); //Writes scores to playerprefs file
}
public void updateUI()
{
leaderboardText.text = createUI();
}
private string createUI()
{
string text = "High Scores:\n";
try
{
for (int i = 0; i < highScores.Count; i++)
{
text += $"{i + 1}. {highScores[i]}\n";
}
}
catch { }
return text;
}
}
I am trying to call the "addScore()" function from my Carcontroller script and this is where I am getting the error.
Carcrontroller Script:
Код: Выделить всё
using UnityEngine;
using UnityEngine.UI;
public class CarController : MonoBehaviour
{
private bool isMoving = true;
private bool hasCrossedIntersection = false;
float points;
CarSpawner carspawnerscript; //Reference to the carspawner script to toggle spawning when limit reached
UIManager UIManager; //reference to the UImanager gameobject to toggle the end of game menu
PointManager PointManager; //reference to the pointmanager to increment the points when the instanciated cars pass a point
PointSaver PointSaver;
public LeaderboardManager LeaderboardManager;
void Start()
{
carspawnerscript = GameObject.FindGameObjectWithTag("GameController").GetComponent(); ////Assigns the gameobject of the carSpawner
UIManager = FindObjectOfType(); //Assigns the UImanager gameObject
PointManager = FindObjectOfType(); //Assigns the PointManager gameObject
PointSaver = FindObjectOfType();
GameObject leaderboardObject = GameObject.Find("LeaderboardObject");
LeaderboardManager = leaderboardObject.GetComponent();
}
void Update()
{
points = PointManager.points / 2;
if (isMoving)
{
MoveCar(); //Calls function to move car
}
if (transform.position.x < 0.35f) // if the position of the car has crossed the intersection
{
hasCrossedIntersection = true;
}
}
void MoveCar()
{
transform.Translate(Vector3.forward * Time.deltaTime * (1+(points/50))); //Unity's method of moving a rigidbody but adds a speed multiplier to increase difficulty as the game progresses
}
public void ToggleMovement(bool canMove)
{
isMoving = canMove; //toggles movement (public attribute)
}
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Intersection")) //Compares the collider tag to make sure the collision is with the intersection and stops the car accordingly
{ //and that the intersection has not already been crossed
if (hasCrossedIntersection == false)
{
ToggleMovement(false);
}
}
if (other.CompareTag("Car")) //compares the tag to stop the car if it collides with a car infront of it at the stop lights
{
ToggleMovement(false);
}
if (other.CompareTag("CollisionCar")) //comapre tag to check whether game-ending collision has occured
{
Invoke("endgame", 0);//Runs the subroutine delayedSpawn() after x seconds
}
if (other.CompareTag("CarLimitDetector"))//Stops spawning of cars when the queue of cars is full to aviod stacking of gameObjects
{
carspawnerscript.Spawntrue();
}
if (other.CompareTag("PointMod")) //Increments the points by 1 when the car passes a "checkpoint"
{
PointManager.IncrementPoints();
}
}
void OnTriggerExit(Collider other)
{
if (other.CompareTag("Car")) //resumes the movement of the car when there is space infront of it afer a random amount of time specified
{
Invoke("ResumeMovement", UnityEngine.Random.Range(0.05f, 0.15f));//Invoke method used to delay
}
if (other.CompareTag("Intersection"))//Resumes movement when the intersection collider not present
{
Invoke("ResumeMovement", UnityEngine.Random.Range(0.001f, 0.07f));//Invoke method used to delay
}
if (other.CompareTag("CarLimitDetector"))
{
carspawnerscript.Spawntrue();//resumes spawning when there are less cars on the road
}
}
void ResumeMovement()
{
ToggleMovement(true); //Resumes the movement of the car
}
void endgame()
{
Time.timeScale = 0; //pauses the game and shows the endgame menu
UIManager.ShowEndGameMenu();
if(PointSaver.checkhighscore(PointManager.points / 2))
{
PointSaver.savehighscore(PointManager.points / 2);
PointManager.highscore = true;
PointManager.UpdatePointsUI();
LeaderboardManager.addScore(PointManager.points/2);
}
}
}
The cars are instantiated by another script therefore I have no clue how to reference the LeaderboardManager script. Any help would be greatly appreciated.
I have tried referencing the LeaderboardManager numerous different ways and I was expecting the CarController to call the function "addScore()" in the LeaderboardManager gameObject. However as described above I got the error:
"NullReferenceException: Object reference not set to an instance of an object
CarController.Start () (at Assets/Scripts/CarController.cs:22)"
The game is carcross.co.uk for context
Источник: https://stackoverflow.com/questions/781 ... t-in-unity