Ошибка в Unity NullReferenceException: Object reference not set to an instance of an object
Сама ошибка вот такая: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
9 комментариев