A NullReferenceException happens when you try to access a reference variable that isn’t referencing any object. If a reference variable isn’t referencing an object, then it’ll be treated as null. The run-time will tell you that you are trying to access an object, when the variable is null by issuing a NullReferenceException.
Reference variables in c# and JavaScript are similar in concept to pointers in C and C++. Reference types default to null to indicate that they are not referencing any object. Hence, if you try and access the object that is being referenced and there isn’t one, you will get a NullReferenceException.
When you get a NullReferenceException in your code it means that you have forgotten to set a variable before using it. The error message will look something like:
NullReferenceException: Object reference not set to an instance of an object
at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10
This error message says that a NullReferenceException happened on line 10 of the script file Example.cs. Also, the message says that the exception happened inside the Start() function. This makes the Null Reference Exception easy to find and fix. In this example, the code is:
//c# example
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
// Use this for initialization
void Start () {
__GameObject__The fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject's functionality is defined by the Components attached to it. [More info](class-GameObject.html)<span class="tooltipGlossaryLink">See in [Glossary](Glossary.html#GameObject)</span> go = GameObject.Find("wibble");
Debug.Log(go.name);
}
}
The code simply looks for a game object called “wibble”. In this example there is no game object with that name, so the Find() function returns null. On the next line (line 9) we use the go variable and try and print out the name of the game object it references. Because we are accessing a game object that doesn’t exist the run-time gives us a NullReferenceException
Null Checks
Although it can be frustrating when this happens it just means the script needs to be more careful. The solution in this simple example is to change the code like this:
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
void Start () {
GameObject go = GameObject.Find("wibble");
if (go) {
Debug.Log(go.name);
} else {
Debug.Log("No game object called wibble found");
}
}
}
Now, before we try and do anything with the go variable, we check to see that it is not null. If it is null, then we display a message.
Try/Catch Blocks
Another cause for NullReferenceException is to use a variable that should be initialised in the InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary. If you forget to do this, then the variable will be null. A different way to deal with NullReferenceException is to use try/catch block. For example, this code:
using UnityEngine;
using System;
using System.Collections;
public class Example2 : MonoBehaviour {
public Light myLight; // set in the inspector
void Start () {
try {
myLight.color = Color.yellow;
}
catch (NullReferenceException ex) {
Debug.Log("myLight was not set in the inspector");
}
}
}
In this code example, the variable called myLight is a Light which should be set in the Inspector window. If this variable is not set, then it will default to null. Attempting to change the color of the light in the try block causes a NullReferenceException which is picked up by the catch block. The catch block displays a message which might be more helpful to artists and game designers, and reminds them to set the light in the inspector.
Summary
-
NullReferenceExceptionhappens when your script code tries to use a variable which isn’t set (referencing) and object. - The error message that appears tells you a great deal about where in the code the problem happens.
-
NullReferenceExceptioncan be avoided by writing code that checks fornullbefore accessing an object, or uses try/catch blocks.
NullReferenceException возникает, когда вы пытаетесь получить доступ к ссылочной переменной, которая не ссылается на какой-либо объект. Если ссылочная переменная не ссылается на объект, она будет рассматриваться как null. Время выполнения сообщит вам, что вы пытаетесь получить доступ к объекту, когда переменная имеет значение null, создав исключение NullReferenceException.
Ссылочные переменные в C# и JavaScript по своей концепции аналогичны указателям в C и C++. Типы ссылок по умолчанию имеют значение null, чтобы указать, что они не ссылаются на какой-либо объект. Следовательно, если вы попытаетесь получить доступ к объекту, на который ссылаются, а его нет, вы получите NullReferenceException.
Когда вы получаете NullReferenceException в своем коде, это означает, что вы забыли установить переменную перед ее использованием. Сообщение об ошибке будет выглядеть примерно так:
NullReferenceException: Object reference not set to an instance of an object
at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10
В этом сообщении об ошибке говорится, что NullReferenceException произошло в строке 10 файла сценария Example.cs. Кроме того, в сообщении говорится, что исключение произошло внутри функции Start(). Это упрощает поиск и исправление исключения нулевой ссылки. В этом примере код такой:
//c# example
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
// Use this for initialization
void Start () {
__GameObject__The fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject's functionality is defined by the Components attached to it. [More info](class-GameObject)See in [Glossary](Glossary#GameObject) go = GameObject.Find("wibble");
Debug.Log(go.name);
}
}
Код просто ищет игровой объект под названием «wibble». В этом примере нет игрового объекта с таким именем, поэтому функция Find() возвращает null. В следующей строке (строка 9) мы используем переменную go и пытаемся вывести имя игрового объекта, на который она ссылается. Поскольку мы обращаемся к несуществующему игровому объекту, среда выполнения выдает нам NullReferenceException
Нулевые проверки
Хотя это может расстраивать, когда это происходит, это просто означает, что сценарий должен быть более осторожным. Решение в этом простом примере состоит в том, чтобы изменить код следующим образом:
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
void Start () {
GameObject go = GameObject.Find("wibble");
if (go) {
Debug.Log(go.name);
} else {
Debug.Log("No game object called wibble found");
}
}
}
Теперь, прежде чем пытаться что-то делать с переменной go, мы проверяем, не является ли она null. Если это null, мы показываем сообщение.
Попробовать/перехватить блоки
Другой причиной NullReferenceException является использование переменной, которая должна быть инициализирована в ИнспектореОкно Unity, в котором отображается информация о текущем выбранном игровом объекте, активе или настройках проекта, что позволяет просматривать и редактировать значения. Дополнительная информация
См. в Словарь. Если вы забудете это сделать, переменная будет иметь значение null. Другой способ справиться с NullReferenceException — использовать блок try/catch. Например, этот код:
using UnityEngine;
using System;
using System.Collections;
public class Example2 : MonoBehaviour {
public Light myLight; // set in the inspector
void Start () {
try {
myLight.color = Color.yellow;
}
catch (NullReferenceException ex) {
Debug.Log("myLight was not set in the inspector");
}
}
}
В этом примере кода переменная с именем myLight — это Light, которую следует установить в окне инспектора. Если эта переменная не задана, по умолчанию она будет иметь значение null. Попытка изменить цвет света в блоке try вызывает NullReferenceException, которое подхватывается блоком catch. Блок catch отображает сообщение, которое может быть более полезным для художников и геймдизайнеров, и напоминает им о необходимости установить свет в инспекторе.
Обзор
-
NullReferenceExceptionвозникает, когда ваш код скрипта пытается использовать переменную, которая не установлена (ссылка) и объект. - Отображаемое сообщение об ошибке многое говорит о том, в каком месте кода возникает проблема.
NullReferenceExceptionможно избежать, написав код, который проверяетnullперед доступом к объекту или использует блоки try/catch.
Value type vs Reference type
In many programming languages, variables have what is called a «data type». The two primary data types are value types (int, float, bool, char, struct, …) and reference type (instance of classes). While value types contains the value itself, references contains a memory address pointing to a portion of memory allocated to contain a set of values (similar to C/C++).
For example, Vector3 is a value type (a struct containing the coordinates and some functions) while components attached to your GameObject (including your custom scripts inheriting from MonoBehaviour) are reference type.
When can I have a NullReferenceException?
NullReferenceException are thrown when you try to access a reference variable that isn’t referencing any object, hence it is null (memory address is pointing to 0).
Some common places a NullReferenceException will be raised:
Manipulating a GameObject / Component that has not been specified in the inspector
// t is a reference to a Transform.
public Transform t ;
private void Awake()
{
// If you do not assign something to t
// (either from the Inspector or using GetComponent), t is null!
t.Translate();
}
Retrieving a component that isn’t attached to the GameObject and then, trying to manipulate it:
private void Awake ()
{
// Here, you try to get the Collider component attached to your gameobject
Collider collider = gameObject.GetComponent<Collider>();
// But, if you haven't any collider attached to your gameobject,
// GetComponent won't find it and will return null, and you will get the exception.
collider.enabled = false ;
}
Accessing a GameObject that doesn’t exist:
private void Start()
{
// Here, you try to get a gameobject in your scene
GameObject myGameObject = GameObject.Find("AGameObjectThatDoesntExist");
// If no object with the EXACT name "AGameObjectThatDoesntExist" exist in your scene,
// GameObject.Find will return null, and you will get the exception.
myGameObject.name = "NullReferenceException";
}
Note: Be carefull, GameObject.Find, GameObject.FindWithTag, GameObject.FindObjectOfType only return gameObjects that are enabled in the hierarchy when the function is called.
Trying to use the result of a getter that’s returning null:
var fov = Camera.main.fieldOfView;
// main is null if no enabled cameras in the scene have the "MainCamera" tag.
var selection = EventSystem.current.firstSelectedGameObject;
// current is null if there's no active EventSystem in the scene.
var target = RenderTexture.active.width;
// active is null if the game is currently rendering straight to the window, not to a texture.
Accessing an element of a non-initialized array
private GameObject[] myObjects ; // Uninitialized array
private void Start()
{
for( int i = 0 ; i < myObjects.Length ; ++i )
Debug.Log( myObjects[i].name ) ;
}
Less common, but annoying if you don’t know it about C# delegates:
delegate double MathAction(double num);
// Regular method that matches signature:
static double Double(double input)
{
return input * 2;
}
private void Awake()
{
MathAction ma ;
// Because you haven't "assigned" any method to the delegate,
// you will have a NullReferenceException
ma(1) ;
ma = Double ;
// Here, the delegate "contains" the Double method and
// won't throw an exception
ma(1) ;
}
How to fix ?
If you have understood the previous paragraphes, you know how to fix the error: make sure your variable is referencing (pointing to) an instance of a class (or containing at least one function for delegates).
Easier said than done? Yes, indeed. Here are some tips to avoid and identify the problem.
The «dirty» way : The try & catch method :
Collider collider = gameObject.GetComponent<Collider>();
try
{
collider.enabled = false ;
}
catch (System.NullReferenceException exception) {
Debug.LogError("Oops, there is no collider attached", this) ;
}
The «cleaner» way (IMHO) : The check
Collider collider = gameObject.GetComponent<Collider>();
if(collider != null)
{
// You can safely manipulate the collider here
collider.enabled = false;
}
else
{
Debug.LogError("Oops, there is no collider attached", this) ;
}
When facing an error you can’t solve, it’s always a good idea to find the cause of the problem. If you are «lazy» (or if the problem can be solved easily), use Debug.Log to show on the console information which will help you identify what could cause the problem. A more complex way is to use the Breakpoints and the Debugger of your IDE.
Using Debug.Log is quite useful to determine which function is called first for example. Especially if you have a function responsible for initializing fields. But don’t forget to remove those Debug.Log to avoid cluttering your console (and for performance reasons).
Another advice, don’t hesitate to «cut» your function calls and add Debug.Log to make some checks.
Instead of :
GameObject.Find("MyObject").GetComponent<MySuperComponent>().value = "foo" ;
Do this to check if every references are set :
GameObject myObject = GameObject.Find("MyObject") ;
Debug.Log( myObject ) ;
MySuperComponent superComponent = myObject.GetComponent<MySuperComponent>() ;
Debug.Log( superComponent ) ;
superComponent.value = "foo" ;
Even better :
GameObject myObject = GameObject.Find("MyObject") ;
if( myObject != null )
{
MySuperComponent superComponent = myObject.GetComponent<MySuperComponent>() ;
if( superComponent != null )
{
superComponent.value = "foo" ;
}
else
{
Debug.Log("No SuperComponent found onMyObject!");
}
}
else
{
Debug.Log("Can't find MyObject!", this ) ;
}
Sources:
- http://answers.unity3d.com/questions/47830/what-is-a-null-reference-exception-in-unity.html
- https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it/218510#218510
- https://support.unity3d.com/hc/en-us/articles/206369473-NullReferenceException
- https://unity3d.com/fr/learn/tutorials/topics/scripting/data-types
Есть класс SaveData
public class SaveData
{
public static SaveData current;
public Motive health;
public Motive eat;
public Motive sleep;
public SaveData()
{
health = new Motive() { name = "health", value = 100 };
eat = new Motive() { name = "eat", value = 100 };
sleep = new Motive() { name = "sleep", value = 100 };
}
А есть класс Motives
public class Motives: MonoBehaviour {
public static Motives Instance { get; set; }
public bool hudOn;
public GameObject hudback;
public TextMesh HealthText;
public TextMesh EatText;
public TextMesh SleepText;
public GameObject HealthImg;
void Start()
{
GameObject gma = GameObject.Find("DialogBox");
gma.SetActive(true);
hudOn = true;
HudBar(-0.2f, 1.22f, SaveData.current.health.value, SaveData.current.health.name);
GameObject gm = GameObject.Find("DialogBox");
gm.SetActive(false);
hudOn = false;
}
public void HudBar(float xpos, float ypos, float scale, string names)
{
GameObject gm = Instantiate(HealthImg, new Vector3(0.125f, 1.29f, 0), Quaternion.identity) as GameObject;
gm.transform.SetParent(GameObject.FindWithTag("back_hud").transform);
gm.transform.localPosition = new Vector3(xpos - xpos * (100 - scale)/100, ypos, 0);
gm.name = names;
}
И на строчке
HudBar(-0.2f, 1.22f, SaveData.current.health.value, SaveData.current.health.name);
выдает ошибку NullReferenceException: Object reference not set to an instance of an object
Motives.Start () (at Assets/Scripts/Motives.cs:40)
Но при этом, если занести SaveData.current.health.value в переменную перед вызовом метода, и подставить эту переменную в вызов, то все работает корректно. Вопрос: как правильно использовать SaveData.current.health.value?
И конечно, сам Motive
public class Motive
{
public string name;
public float value;
public Motive()
{
this.name = "";
this.value = 0;
}
}
[Решено]NullReferenceException: Object reference not set …
[Решено]NullReferenceException: Object reference not set …
Всем привет, При нажатие на кнопку открывается магазин и сразу же должны создаваться кнопки покупки или экипировки, все работало прекрасно, но в какойто момент перестало, вот ломаю голову что могло случиться, Помогите пожалуйста понять причину возникшей проблемы.
Вот ошибка. Выводит при срабатывание кейса shopbt
NullReferenceException: Object reference not set to an instance of an object
buttons.Active_but () (at Assets/Scripts/buttons.cs:98)
Вот скрипт buttons
Используется csharp
/// </summary>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class buttons : MonoBehaviour {
public GameObject bg_shop; //переменная для изменения активности фона
private GameObject main; // переменнная для изменения активности пиньяты
public GameObject rp_act; //переменнная для изменения активности веревки
private GameObject Bg_zk; //Закладки
private Image im; //Для закладок
private GameObject shop;
public GameObject scroll, zakladka, knopka;
public void Start(){
main = GameObject.Find («Main Camera»);//Поиск объекта пиньяты в скрипте расположенном в Main Camera
Bg_zk = GameObject.Find («Bg_Zakladka»);
shop = GameObject.Find («shop»);
im = Bg_zk.GetComponent<Image> ();
}
public void OnMouseUpAsButton(){ //Функция срабатывает когда убераешь палец имеено на объекте.
switch (gameObject.name) { //Свитч для активации кнопки по имени
case «shopbt»: //Активация магазина
bg_shop.SetActive (true);
//main.GetComponent<Vars> ().scroll [0].SetActive (true);
//main.GetComponent<Vars> ().zakladka [0].GetComponent<PolygonCollider2D> ().enabled = false;
scroll.SetActive (true);
zakladka.GetComponent<PolygonCollider2D> ().enabled = false;
main.GetComponent<CreatePinata> ().inst_pin.SetActive (false);
rp_act.SetActive (false);
//main.GetComponent<Vars> ().shopbut.SetActive (false);
knopka.SetActive(false);
main.GetComponent<CreatePinata> ().inst_stik.SetActive (false);
Invoke(«Active_but»,0.1f);
//shop.GetComponent<buttons_active_shop>().ActSt();
break;
/* case «shop_exit»:
shop.GetComponent<buttons_active_shop> ().Dest (0);
shop.GetComponent<buttons_active_shop> ().Dest (1);
main.GetComponent<Vars> ().scroll [0].SetActive (false);
main.GetComponent<Vars> ().scroll [1].SetActive (false);
main.GetComponent<Vars> ().scroll [2].SetActive (false);
main.GetComponent<Vars> ().zakladka [0].GetComponent<PolygonCollider2D> ().enabled = false;
main.GetComponent<Vars> ().zakladka [1].GetComponent<PolygonCollider2D> ().enabled = true;
main.GetComponent<Vars> ().zakladka [2].GetComponent<PolygonCollider2D> ().enabled = true;
im.sprite = main.GetComponent<Vars> ().pictZk [0];
bg_shop.gameObject.active = false;
main.GetComponent<CreatePinata> ().inst_pin.SetActive (true);
main.GetComponent<CreatePinata> ().inst_stik.SetActive (true);
rp_act.gameObject.active = true;
main.GetComponent<Vars> ().shopbut.SetActive (true);
main.GetComponent<CreatePinata> ().Save ();
break;
case «St_col»:
shop.GetComponent<buttons_active_shop> ().Dest (1);
main.GetComponent<Vars>().scroll[0].SetActive(true);
main.GetComponent<Vars>().scroll[1].SetActive(false);
main.GetComponent<Vars>().scroll[2].SetActive(false);
main.GetComponent<Vars>().zakladka[0].GetComponent<PolygonCollider2D>().enabled = false;
main.GetComponent<Vars>().zakladka[1].GetComponent<PolygonCollider2D>().enabled = true;
main.GetComponent<Vars>().zakladka[2].GetComponent<PolygonCollider2D>().enabled = true;
im.sprite = main.GetComponent<Vars> ().pictZk [0];
shop.GetComponent<buttons_active_shop>().ActSt();
break;
case «Pin_col»:
shop.GetComponent<buttons_active_shop>().Dest(0);
main.GetComponent<Vars>().scroll[0].SetActive(false);
main.GetComponent<Vars>().scroll[1].SetActive(true);
main.GetComponent<Vars>().scroll[2].SetActive(false);
main.GetComponent<Vars>().zakladka[0].GetComponent<PolygonCollider2D>().enabled = true;
main.GetComponent<Vars>().zakladka[1].GetComponent<PolygonCollider2D>().enabled = false;
main.GetComponent<Vars>().zakladka[2].GetComponent<PolygonCollider2D>().enabled = true;
im.sprite = main.GetComponent<Vars> ().pictZk [1];
shop.GetComponent<buttons_active_shop>().ActPn();
break;
case «Bg_col»:
shop.GetComponent<buttons_active_shop>().Dest(1);
shop.GetComponent<buttons_active_shop>().Dest(0);
main.GetComponent<Vars>().zakladka[0].GetComponent<PolygonCollider2D>().enabled = true;
main.GetComponent<Vars>().zakladka[1].GetComponent<PolygonCollider2D>().enabled = true;
main.GetComponent<Vars>().zakladka[2].GetComponent<PolygonCollider2D>().enabled = false;
main.GetComponent<Vars>().scroll[0].SetActive(false);
main.GetComponent<Vars>().scroll[1].SetActive(false);
main.GetComponent<Vars>().scroll[2].SetActive(true);
im.sprite = main.GetComponent<Vars> ().pictZk [2];
break;*/
}
}
void Active_but () {
shop.GetComponent<buttons_active_shop>().ActSt();
}
}
Последний раз редактировалось Olmer 10 янв 2018, 23:03, всего редактировалось 1 раз.
-

Olmer - UNец
- Сообщения: 46
- Зарегистрирован: 25 окт 2017, 21:54
Re: NullReferenceException: Object reference not set to an insta
samana 10 янв 2018, 22:33
Что-то, где-то не назначено, либо потеряло ссылку.
Ошибка указывает на 98 строку, смотрите там. Можете кликнуть на ошибку в консоли и во второй, нижней половине этого же окна (консоли), будет более полное описание ошибки, в виде цепочки.
-

samana - Адепт
- Сообщения: 4733
- Зарегистрирован: 21 фев 2015, 13:00
- Откуда: Днепропетровск
Re: NullReferenceException: Object reference not set to an insta
Olmer 10 янв 2018, 22:49
Вроде бы все на месте, 93 это вызов функции shop.GetComponent<buttons_active_shop>().ActSt();
В этом же скрипте этот вызов функции срабатывает при условии кейса case «St_col»: (переход по вкладкам), и тут все работает нормально и все кнопки он создает без проблем. Ссылки все на месте.
-

Olmer - UNец
- Сообщения: 46
- Зарегистрирован: 25 окт 2017, 21:54
Re: NullReferenceException: Object reference not set to an insta
Olmer 10 янв 2018, 23:02
Решил проблему, кинул ссылку переменной shop через инспектор,а не поиском (shop = GameObject.Find («shop»);) и заработало, но раньше и так работало.
-

Olmer - UNец
- Сообщения: 46
- Зарегистрирован: 25 окт 2017, 21:54
Re: [Решено]NullReferenceException: Object reference not set …
samana 10 янв 2018, 23:04
Может изменили имя с shop на Shop и забыли исправить имя в скрипте?
-

samana - Адепт
- Сообщения: 4733
- Зарегистрирован: 21 фев 2015, 13:00
- Откуда: Днепропетровск
Re: [Решено]NullReferenceException: Object reference not set …
Olmer 10 янв 2018, 23:36
samana писал(а):Может изменили имя с shop на Shop и забыли исправить имя в скрипте?
Не менял, все также, ну явно я где-то что-то намутил и не заметил вовремя.
-

Olmer - UNец
- Сообщения: 46
- Зарегистрирован: 25 окт 2017, 21:54
Вернуться в Почемучка
Кто сейчас на конференции
Сейчас этот форум просматривают: Google [Bot] и гости: 17
Сама ошибка вот такая:NullReferenceException: Object reference not set to an instance of an objectGameContoller.MoveLevelTop (Level level) (at Assets/Scripts/GameContoller.cs:107)Level.LateUpdate () (at Assets/Scripts/Level.cs:48)
107 строчка — level.Setup(new Vector3(0, lastLevel.AnchoredPosition.y + lastLevel.Size.y), colors[CurrentLevel % colors.Count], CurrentLevel);
48 строчка — OnFinishLevel?.Invoke(this);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Level : MonoBehaviour
{
public System.Action OnStartNewLevel;
public System.Action<Level> OnFinishLevel;
private RectTransform rect;
private Image image;
private bool newLevelFired;
[SerializeField] Text levelText;
public Vector3 AnchoredPosition { get { return rect.anchoredPosition3D; } set { rect.anchoredPosition3D = value;}}
public Vector2 Size { get { return rect.sizeDelta; } set { rect.sizeDelta = value; } }
public Color BackColor { get {return image.color; } set { image.color = value; } }
private void Awake() {
image = GetComponent<Image>();
rect = GetComponent<RectTransform>();
}
void Start()
{
}
// Update is called once per frame
void Update()
{
if (GameContoller.Instance.State == GameContoller.GameState.PLAY)
{
AnchoredPosition += Vector3.down * Time.deltaTime * 400;
}
}
private void LateUpdate() {
if (!newLevelFired && AnchoredPosition.y < 500)
{
OnStartNewLevel?.Invoke();
newLevelFired = true;
}
if (AnchoredPosition.y < -Size.y — 100)
{
OnFinishLevel?.Invoke(this);
}
}
public void Setup(Vector3 pos, Color color, int level)
{
newLevelFired = false;
AnchoredPosition = pos;
BackColor = color;
levelText.text = level.ToString();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class GameContoller : MonoBehaviour
{
public enum GameState { START, PLAY, LOSE, GAME_OVER};
public event System.Action<GameState> OnStateChanged;
public event System.Action<int> OnCurrentLevelChanged;
public event System.Action<int> OnScoreChanged;
public System.Action<int> OnGameOver;
private GameState state;
private int currentLevel;
private int score;
[SerializeField] private Transform levelRegion = null;
[SerializeField] private Level LevelPrefab = null;
[SerializeField] private List<Color> colors = new List<Color>();
[SerializeField] private Player player;
private List<Level> levels = new List<Level>();
private List <GameObject> ObstaclePrefabs ;
public GameState State { get => state; set { state = value; OnStateChanged?.Invoke(state);} }
public int CurrentLevel { get => currentLevel; set { currentLevel = value; OnCurrentLevelChanged?.Invoke(value); } }
public int Score { get => score; set { score = value; OnScoreChanged?.Invoke(value); } }
public static GameContoller Instance;
[SerializeField] private Transform spawnRegion;
private Level lastLevel;
private void Awake()
{
Instance = this;
}
private void Start()
{
ObstaclePrefabs = Resources.LoadAll<GameObject>(«GroupObstacles»).ToList();
for (int i=0; i<2;i++)
{
levels.Add(SpawnNewLevel1());
}
ResetLevels();
player.OnGameOver += GameOver;
}
private void GameOver()
{
State = GameState.LOSE;
StartCoroutine(DelayAction(1.5f,()=> {
State = GameState.GAME_OVER;
ResetGame();
OnGameOver.Invoke(Score);
}));
}
public void ResetGame()
{
ClearObstacle();
ResetLevels();
player.Reset();
}
private void ClearObstacle()
{
foreach (Transform child in spawnRegion.transform)
{
Destroy(child.gameObject);
}
}
private IEnumerator DelayAction(float delay, System.Action action)
{
yield return new WaitForSeconds(delay);
action();
}
private void ResetLevels()
{
levels[0].AnchoredPosition = new Vector3(0, -levels[0].Size.y / 2);
for ( int i = 1; i < levels.Count; i ++)
{
levels[i].AnchoredPosition = new Vector3(0, levels[i — 1].AnchoredPosition.y + levels[ i- 1].Size.y);
}
}
private Level SpawnNewLevel1()
{
Level level = Instantiate(LevelPrefab, Vector3.zero, Quaternion.identity, levelRegion);
level.AnchoredPosition =Vector3.zero;
level.BackColor = colors[UnityEngine.Random.Range(0, colors.Count)];
level.Size = new Vector2 (levelRegion.parent.GetComponent<RectTransform>().sizeDelta.x, levelRegion.parent.GetComponent<RectTransform>().sizeDelta.y * 2 );
level.OnFinishLevel += MoveLevelTop;
level.OnStartNewLevel += () => { CurrentLevel++; };
return level;
}
private void MoveLevelTop (Level level)
{
level.Setup(new Vector3(0, lastLevel.AnchoredPosition.y + lastLevel.Size.y), colors[CurrentLevel % colors.Count], CurrentLevel);
lastLevel = level;
SpawnObstacle(ObstaclePrefabs[UnityEngine.Random.Range(0, ObstaclePrefabs.Count )], spawnRegion);
//level.AnchoredPosition = new Vector3(0, lastLevel.AnchoredPosition.y + lastLevel.Size.y);
}
public void StartGame()
{ CurrentLevel = 1;
Score = 0;
State = GameState.PLAY;
SpawnObstacle(ObstaclePrefabs[UnityEngine.Random.Range(0, ObstaclePrefabs.Count)], spawnRegion);
StartCoroutine(ScoreCoroutine());
}
private IEnumerator ScoreCoroutine()
{
while (State == GameState.PLAY)
{
Score++;
yield return new WaitForSeconds(0.2f);
}
}
private void SpawnObstacle(GameObject gameObject, Transform spawnRegion, bool isFirst= false)
{
Instantiate(gameObject, spawnRegion.transform.position * (isFirst ? 0.5f : 1), Quaternion.identity, spawnRegion);
}
}
Хочу чтобы префаб Level спавнился, когда проходим границы Level. Мы перемещаем новый уровень вверх, пересоздавая его. Но вот скрипт не работает , вылазит вот такая ошибка, когда прохожу границы Level