#c# #unity3d
#c# #unity-игровой движок
Вопрос:
[Изображение]Я разрабатываю игру и пытаюсь создать кнопку сохранения и загрузки. Я считаю, что я правильно закодировал, но моя проблема в том, что проигрыватель, к которому я хочу получить доступ, не найден. Я подозреваю, что это как-то связано с тем, как я его кодирую.
Из-за наличия нескольких уровней я использовал код: GameObject player = GameObject.FindWithTag(«Игрок»); чтобы попытаться найти данного игрока в сцене, но я не думаю, что это работает.
Я не устанавливал player в качестве общедоступной переменной, поскольку он меняется в каждой сцене.
Например, я попытался получить доступ к текущему состоянию игроков с помощью следующих строк кода, который сохраняется в пустом игровом объекте GameController в скрипте с именем Gamecontrol.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEngine.SceneManagement;
public class GameControl : MonoBehaviour {
public static GameControl controller;
int shooterHealth;
int shooterScore;
//public GameObject player;
//public GameObject gun;
int level;
// Use this for initialization
void Awake() {
GameObject player = GameObject.FindWithTag("Player");
shooterHealth = player.GetComponent<PlayerHealth>().currentHealth;
shooterScore = player.GetComponent<Gun>().score;
level = player.GetComponent<PlayerHealth>().level;
if(controller == null) {
DontDestroyOnLoad(gameObject);
controller = this;
}
else if(controller != this) {
Destroy(gameObject);
}
}
public void SaveGame() {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath "/shooter.dat");
PlayerData data = new PlayerData();
data.shooterHealth = shooterHealth;
data.shooterScore = shooterScore;
data.level = level;
bf.Serialize(file, data);
file.Close();
}
public void LoadGame() {
if(File.Exists(Application.persistentDataPath "/shooter.dat"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath "/shooter.dat", FileMode.Open);
PlayerData data = (PlayerData)bf.Deserialize(file);
file.Close();
GameObject player = GameObject.FindWithTag("Player");
player.GetComponent<PlayerHealth>().currentHealth = data.shooterHealth;
player.GetComponent<Gun>().score = data.shooterScore;
level = player.GetComponent<PlayerHealth>().level;
SceneManager.LoadScene(level);
}
}
}
[Serializable]
class PlayerData
{
public int shooterHealth;
public int shooterScore;
public int level;
}
Ошибка, которую я получаю, это:
Исключение NullReferenceException: ссылка на объект не установлена для экземпляра объекта GameControl.Awake () (в Assets/GameControl.cs:20)
Кто-нибудь знает способ обойти это? Заранее благодарю вас 🙂
Комментарии:
1. Вы уверены, что player помечен правильно?
2. Да, я уверен, я даже пытался изменить теги на другие, и он выдает ту же ошибку: (
3. Ну, это странно. Можете ли вы поделиться полным сценарием, возможно, вы делаете что-то неправильно в других частях кода
4. Также активен ли игрок в сцене? Если нет, то вы не сможете его найти.
5. Я обновил картинку:)
Ответ №1:
Ошибка заключается в том, что shooterScore = player.GetComponent<Gun>().score;
вы пытаетесь получить доступ к компоненту Gun
, но к игровому объекту Player не подключен Gun
компонент. Возможно, вы забыли прикрепить его или у вас есть другое имя.
Возможно, вы подключаете Gun
компонент во время выполнения. В этом случае проверьте порядок выполнения скрипта, чтобы убедиться, что GameControl
скрипт выполняется после скрипта, который подключает Gun
компонент во время выполнения.
Комментарии:
1. Я только что подключил компонент Gun к проигрывателю, но, к сожалению, у меня та же ошибка, скрипт GameControl, похоже, просто не может найти объект с тегом player по какой-то странной причине..
2. Вы проверили порядок выполнения скрипта?
3. Я проверил порядок выполнения и добавил компонент Gun и playerHealth, который будет выполняться перед любыми другими сценариями, но это тоже ничего не делает? Судя по ошибке, я думаю, что это часть ‘GameObject player = …’ .. если игрок будет найден, эти команды должны выполняться
4. Исключение NullReferenceException: ссылка на объект не установлена для экземпляра объекта GameControl. Awake () (в Assets/GameControl.cs:20) — это строка, в которой находится shooterHealth
5. Возможно, у вас есть другие игровые объекты, помеченные как «Player». В этом случае вам следует использовать
FindGameObjectsWithTag("Player")
. Он возвращает список игровых объектов вместо одного игрового объекта. Затем вы перебираете возвращенные игровые объекты и находите, к какому из них подключен компонент playerHealth, и используете его.