Creating a basic snake game.
Trying to get a gameobject to spawn within the limits of a grid, with a sprite. However, when attmpting to call the function that spawns the object, I am getting a NULL REFERENCE error. However, I am confident I have clearly created a reference to the object?
Snake.cs script (Error occurs at line: 'levelGrid.SnakeMoved(gridPosition)')
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Snake : MonoBehaviour
{
private Vector2Int gridMoveDirection;
private Vector2Int gridPosition;
private float gridMoveTimer;
private float gridMoveTimerMax;
private LevelGrid levelGrid;
public void Setup(LevelGrid levelGrid)
{
this.levelGrid = levelGrid;
}
private void Awake ()
{
gridPosition = new Vector2Int(10, 10);
gridMoveTimerMax = .5f;
gridMoveTimer = gridMoveTimerMax;
gridMoveDirection = new Vector2Int(1, 0);
}
// Update is called once per frame
private void Update()
{
HandleInput();
HandleGridMovement();
}
private void HandleInput()
{
if (Input.GetKeyDown(KeyCode.UpArrow) && gridMoveDirection.y != -1)
{
gridMoveDirection.x = 0;
gridMoveDirection.y = +1;
}
if (Input.GetKeyDown(KeyCode.DownArrow) && gridMoveDirection.y != +1)
{
gridMoveDirection.x = 0;
gridMoveDirection.y = -1;
}
if (Input.GetKeyDown(KeyCode.LeftArrow) && gridMoveDirection.x != +1)
{
gridMoveDirection.x = -1;
gridMoveDirection.y = 0;
}
if (Input.GetKeyDown(KeyCode.RightArrow) && gridMoveDirection.x != -1)
{
gridMoveDirection.x = +1;
gridMoveDirection.y = 0;
}
}
/* Explanation: HandleGridMovement()
* gridMoveTimer += Time.deltaTime causes the variable of gridMove to incrediment in REAL TIME.
* gridMoveMaxTime is initalized as the starting value of gridMoveTimer, every 0.5 seconds the if statement will take place
* the if statement transform both the position of the head of the snake, alongside rotating it accordingly.
*/
private void HandleGridMovement()
{
gridMoveTimer += Time.deltaTime;
if (gridMoveTimer >= gridMoveTimerMax)
{
gridMoveTimer -= gridMoveTimerMax;
gridPosition += gridMoveDirection;
transform.position = new Vector3(gridPosition.x, gridPosition.y);
transform.eulerAngles = new Vector3(0, 0, GetAngleFromVector(gridMoveDirection) - 90);//eurlerAngles r just the rotation angles.
levelGrid.SnakeMoved(gridPosition);
}
}
private float GetAngleFromVector(Vector2Int dir)
{
float n = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
if (n < 0) n += 360;
return n;
}
}
LevelGrid.cs Script: (script that is not working)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelGrid
{
private Vector2Int foodGridPosition;
private GameObject foodGameObject;
private int width;
private int height;
private Snake snake;
public LevelGrid(int width, int height)
{
this.width = width;
this.height = height;
Debug.Log("here!");
SpawnFood();
}
public void Setup(Snake snake)
{
this.snake = snake;
}
private void SpawnFood()
{
foodGridPosition = new Vector2Int(4,4);
foodGameObject = new GameObject("FoodApple", typeof(SpriteRenderer));
foodGameObject.GetComponent<SpriteRenderer>().sprite = GameAssets.i.foodSprite;
foodGameObject.transform.position = new Vector3(foodGridPosition.x, foodGridPosition.y);
}
public void SnakeMoved(Vector2Int snakeGridPosition)
{
if (snakeGridPosition == foodGridPosition)
{
Object.Destroy(foodGameObject);
SpawnFood();
}
}
}
Other two scripts for clarity sake:
GameHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameHandler : MonoBehaviour
{
[SerializeField] private Snake snake;
private LevelGrid levelGrid;
private void Start()
{
Debug.Log("GameHandler Called!");
levelGrid = new LevelGrid(20, 20);
snake.Setup(levelGrid);
levelGrid.Setup(snake);
}
}
GameAssets.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameAssets : MonoBehaviour
{
public static GameAssets i;
private void Awake()
{
i = this;
}
public Sprite snakeHeadSprite;
public Sprite foodSprite;
}