Ошибка в unity2d на Csharp, слишком сложно для меня [дубликат]

157
26 декабря 2019, 23:50
This question already has answers here:
Что такое NullReferenceException, и как мне исправить код? (2 ответа)
Закрыт 9 месяцев назад.

Unity2D выдает ошибку:

llReferenceException: Object reference not set to an instance of an object Game.updateCosts () (at Assets/Scripts/Game.cs:92) Game.Start () (at Assets/Scripts/Game.cs:51)

Сам visual studio не выдает никаких ошибок. К сожалению, я абсолютный новичок в этом деле и не могу разобраться в этом сам.

 using UnityEngine;
    using UnityEngine.UI;
    using System.Collections.Generic;
    using System.Collections;
    using System;
    public class Game : MonoBehaviour
    {
        [Header("Текст, отвечающий за отображение денег")]
        public Text scoreText;
        [Header("Магазин")]
        public List<Item> shopItems = new List<Item>();
        [Header("Текст на кнопках товаров")]
        public Text[] shopItemsText;
        [Header("Кнопки товаров")]
        public Button[] shopBttns;
        [Header("Панелька магазина")]
        public GameObject ClickBonusShop,TimeBonusShop,BonusesForCrystalShop;

        private int score; //Игровая валюта
        private int scoreIncrease = 1; //Бонус при клике
        private Save sv = new Save();
        private void Awake()
        {
            if (PlayerPrefs.HasKey("SV"))
            {
                int totalBonusPS = 0;
                sv = JsonUtility.FromJson<Save>(PlayerPrefs.GetString("SV"));
                score = sv.score;
                for (int i = 0; i < shopItems.Count; i++)
                {
                    shopItems[i].levelOfItem = sv.levelOfItem[i];
                    shopItems[i].bonusCounter = sv.bonusCounter[i];
                    if (shopItems[i].needCostMultiplier) shopItems[i].cost *= (int)Mathf.Pow(shopItems[i].costMultiplier, shopItems[i].levelOfItem);
                    if (shopItems[i].bonusIncrease != 0 && shopItems[i].levelOfItem != 0) scoreIncrease += (int)Mathf.Pow(shopItems[i].bonusIncrease, shopItems[i].levelOfItem);
                    totalBonusPS += shopItems[i].bonusPerSec * shopItems[i].bonusCounter;
                }
                DateTime dt = new DateTime(sv.date[0], sv.date[1], sv.date[2], sv.date[3], sv.date[4], sv.date[5]);
                TimeSpan ts = DateTime.Now - dt;
                int offlineBonus = (int)ts.TotalSeconds * totalBonusPS;
                score += offlineBonus;
                print("Time without GachiBass: " + ts.Days + "Д. " + ts.Hours + "Ч. " + ts.Minutes + "М. " + ts.Seconds + "S.");
                print("Your BoysBand earned: " + offlineBonus + "$");
            }
        }
        private void Start()
        {
            updateCosts(); //Обновить текст с ценами
            StartCoroutine(BonusPerSec()); //Запустить просчёт бонуса в секунду
        }
        private void Update()
        {
            scoreText.text = score + "$"; //Отображаем деньги
        }
        public void BuyBttn(int index) //Метод при нажатии на кнопку покупки товара (индекс товара)
        {
            int cost = shopItems[index].cost * shopItems[shopItems[index].itemIndex].bonusCounter; //Рассчитываем цену в зависимости от кол-ва рабочих (к примеру)
            if (shopItems[index].itsBonus && score >= cost) //Если товар нажатой кнопки - это бонус, и денег >= цены(е)
            {
                if (cost > 0) // Если цена больше чем 0, то:
                {
                    score -= cost; // Вычитаем цену из денег
                    StartCoroutine(BonusTimer(shopItems[index].timeOfBonus, index)); //Запускаем бонусный таймер
                }
                else print("It`s all, my leather friend"); // Иначе выводим в консоль текст.
            }
            else if (score >= shopItems[index].cost) // Иначе, если товар нажатой кнопки - это не бонус, и денег >= цена
            {
                if (shopItems[index].itsItemPerSec) shopItems[index].bonusCounter++; // Если нанимаем рабочего (к примеру), то прибавляем кол-во рабочих
                else scoreIncrease += shopItems[index].bonusIncrease; // Иначе бонусу при клике добавляем бонус товара
                score -= shopItems[index].cost; // Вычитаем цену из денег
                if (shopItems[index].needCostMultiplier) shopItems[index].cost *= shopItems[index].costMultiplier; // Если товару нужно умножить цену, то умножаем на множитель
                shopItems[index].levelOfItem++; // Поднимаем уровень предмета на 1
            }
            else print("Fisting is threehundred buks"); // Иначе если 2 проверки равны false, то выводим в консоль текст.
            updateCosts(); //Обновить текст с ценами
        }
        private void updateCosts() // Метод для обновления текста с ценами
        {
            for (int i = 0; i < shopItems.Count; i++) // Цикл выполняется, пока переменная i < кол-ва товаров
            {
                if (shopItems[i].itsBonus) // Если товар является бонусом, то:
                {
                    int cost = shopItems[i].cost * shopItems[shopItems[i].itemIndex].bonusCounter; // Рассчитываем цену в зависимости от кол-ва рабочих (к примеру)
                    shopItemsText[i].text = shopItems[i].name + "\n" + cost; // Обновляем текст кнопки с рассчитанной ценой
                }
                else shopItemsText[i].text = shopItems[i].name + "\n" + shopItems[i].cost; // Иначе если товар не является бонусом, то обновляем текст кнопки с обычной ценой
            }
        }
        IEnumerator BonusPerSec() // Бонус в секунду
        {
            while (true) // Бесконечный цикл
            {
                for (int i = 0; i < shopItems.Count; i++) score += (shopItems[i].bonusCounter * shopItems[i].bonusPerSec); // Добавляем к игровой валюте бонус рабочих (к примеру)
                yield return new WaitForSeconds(1); // Делаем задержку в 1 секунду
            }
        }
        IEnumerator BonusTimer(float time, int index) // Бонусный таймер (длительность бонуса (в сек.),индекс товара)
        {
            shopBttns[index].interactable = false; // Выключаем кликабельность кнопки бонуса
            shopItems[shopItems[index].itemIndex].bonusPerSec *= 2; // Удваиваем бонус рабочих в секунду (к примеру)
            yield return new WaitForSeconds(time); // Делаем задержку на столько секунд, сколько указали в параметре
            shopItems[shopItems[index].itemIndex].bonusPerSec /= 2; // Возвращаем бонус в нормальное состояние
            shopBttns[index].interactable = true; // Включаем кликабельность кнопки бонуса
        }
    #if UNITY_ANDROID && !UNITY_EDITOR
        private void OnApplicationPause(bool pause)
        {
            if (pause)
            {
                sv.score = score;
                sv.levelOfItem = new int[shopItems.Count];
                sv.bonusCounter = new int[shopItems.Count];
                for (int i = 0; i < shopItems.Count; i++)
                {
                    sv.levelOfItem[i] = shopItems[i].levelOfItem;
                    sv.bonusCounter[i] = shopItems[i].bonusCounter;
                }
                sv.date[0] = DateTime.Now.Year; sv.date[1] = DateTime.Now.Month; sv.date[2] = DateTime.Now.Day; sv.date[3] = DateTime.Now.Hour; sv.date[4] = DateTime.Now.Minute; sv.date[5] = DateTime.Now.Second;
                PlayerPrefs.SetString("SV", JsonUtility.ToJson(sv));
            }
        }
    #else
        private void OnApplicationQuit()
        {
            sv.score = score;
            sv.levelOfItem = new int[shopItems.Count];
            sv.bonusCounter = new int[shopItems.Count];
            for (int i = 0; i < shopItems.Count; i++)
            {
                sv.levelOfItem[i] = shopItems[i].levelOfItem;
                sv.bonusCounter[i] = shopItems[i].bonusCounter;
            }
            sv.date[0] = DateTime.Now.Year; sv.date[1] = DateTime.Now.Month; sv.date[2] = DateTime.Now.Day; sv.date[3] = DateTime.Now.Hour; sv.date[4] = DateTime.Now.Minute; sv.date[5] = DateTime.Now.Second;
            PlayerPrefs.SetString("SV", JsonUtility.ToJson(sv));
        }
    #endif
        public void OnClick() 
        {
            Sound.instance.MakeClickOnButton();
            score += scoreIncrease; // К игровой валюте прибавляем бонус при клике
        }
        public void ClickBonus()
        {
            Sound.instance.MakeShopButton();
            ClickBonusShop.SetActive(true);
            TimeBonusShop.SetActive(false);
            BonusesForCrystalShop.SetActive(false);
        }
        public void BonusesForCrystals()
        {
            Sound.instance.MakeShopButton();
            ClickBonusShop.SetActive(false);
            TimeBonusShop.SetActive(false);
            BonusesForCrystalShop.SetActive(true);
        }
        public void TimeBonus()
        {
            Sound.instance.MakeShopButton();
            ClickBonusShop.SetActive(false);
            TimeBonusShop.SetActive(true);
            BonusesForCrystalShop.SetActive(false);
        }
    }
    [Serializable]
    public class Item // Класс товара
    {
        [Tooltip("Название используется на кнопках")]
        public string name;
        [Tooltip("Цена товара")]
        public int cost;
        [Tooltip("Бонус, который добавляется к бонусу при клике")]
        public int bonusIncrease;
        [HideInInspector]
        public int levelOfItem; // Уровень товара
        [Space]
        [Tooltip("Нужен ли множитель для цены?")]
        public bool needCostMultiplier;
        [Tooltip("Множитель для цены")]
        public int costMultiplier;
        [Space]
        [Tooltip("Этот товар даёт бонус в секунду?")]
        public bool itsItemPerSec;
        [Tooltip("Бонус, который даётся в секунду")]
        public int bonusPerSec;
        [HideInInspector]
        public int bonusCounter; // Кол-во рабочих (к примеру)
        [Space]
        [Tooltip("Это временный бонус?")]
        public bool itsBonus;
        [Tooltip("Множитель товара, который управляется бонусом (Умножается переменная bonusPerSec)")]
        public int itemMultiplier;
        [Tooltip("Индекс товара, который будет управляться бонусом (Умножается переменная bonusPerSec этого товара)")]
        public int itemIndex;
        [Tooltip("Длительность бонуса")]
        public float timeOfBonus;
    }
    [Serializable]
    public class Save
    {
        public int score;
        public int[] levelOfItem;
        public int[] bonusCounter;
        public int[] date = new int[6];
    }
Answer 1

Ошибка в методе:

private void updateCosts() // Метод для обновления текста с ценами
{
    for (int i = 0; i < shopItems.Count; i++) // Цикл выполняется, пока переменная i < кол-ва товаров
    {
        if (shopItems[i].itsBonus) // Если товар является бонусом, то:
        {
            int cost = shopItems[i].cost * shopItems[shopItems[i].itemIndex].bonusCounter; // Рассчитываем цену в зависимости от кол-ва рабочих (к примеру)
            shopItemsText[i].text = shopItems[i].name + "\n" + cost; // Обновляем текст кнопки с рассчитанной ценой
        }
        else shopItemsText[i].text = shopItems[i].name + "\n" + shopItems[i].cost; // Иначе если товар не является бонусом, то обновляем текст кнопки с обычной ценой
    }
}

на строке:

else shopItemsText[i].text = shopItems[i].name + "\n" + shopItems[i].cost;

Запускайте отладку и проверяйте значение элемента shopItemsText[i] на каждой итерации. На одной из них он у вас null, в результате невозможно рассчитать выражение.

READ ALSO
Формирование документа и его печать в C#

Формирование документа и его печать в C#

У меня есть программа на C# в Visual Studio, в ней в качестве результатов работы выводятся данные в DataGridViewНеобходимо реализовать формирование документа...

151
Спарсить таблицу Html Agility pack c#

Спарсить таблицу Html Agility pack c#

Есть вот такая таблица

148
Организация запроса к MS SQL Server (EF 6) используя LINQ

Организация запроса к MS SQL Server (EF 6) используя LINQ

при проектировании собственного проекта на языке С # технологии WPF и запроса к данным на Entity Framework 6 встал вопрос как реализовать один запросУ...

104