So I made a little editor script that helps me create templates for a dungeon generator. But when I want to use the information saved in the ScriptableObject the array seems to throw a NullReferenceException.
This class creates a grid that is editable in the game view and then uses the next class to turn the information into a new ScriptableObject.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using RoomTypes;
using TileTypes;
public class CreateRoom : MonoBehaviour {
public GameObject tile;
public TileType curTileType;
public RoomType type;
public Tile[,] grid;
public int width;
public int height;
public TileButton[,] tileButtons;
private GameObject tileParent;
public void Create()
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
grid[x, y] = new Tile( tileButtons[x, y].tileType ) ;
}
}
CreateSORoom.CreateRoom(type, grid, width, height);
}
public void CreateGrid()
{
tileButtons = new TileButton[width, height];
DeleteGrid();
FindObjectOfType<CreateRoomCamera>().SetCamera(width, height);
if (!tileParent) tileParent = new GameObject("TileParent");
grid = new Tile[width, height];
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
GameObject newTile = Instantiate(tile, tileParent.transform);
newTile.GetComponent<RectTransform>().anchoredPosition = new
Vector3(0.5f + x, 0.5f + y);
tileButtons[x, y] = newTile.GetComponent<TileButton>();
tileButtons[x, y].xCoord = x;
tileButtons[x, y].yCoord = y;
}
}
}
}
[CustomEditor(typeof(CreateRoom))]
public class CreateRoomEditor : Editor
{
public override void OnInspectorGUI()
{
CreateRoom createRoom = (CreateRoom)target;
base.OnInspectorGUI();
if (GUILayout.Button("Create Grid"))
{
createRoom.CreateGrid();
}
if (GUILayout.Button("Create Room"))
{
createRoom.Create();
}
}
}
This is the class that creates the Object.
using UnityEngine;
using UnityEditor;
using System.IO;
using RoomTypes;
using TileTypes;
public static class CreateSORoom
{
public static void CreateRoom(RoomType type, Tile[,] grid, int width, int
height)
{
Room room = ScriptableObject.CreateInstance<Room>();
string path = "Assets/LevelGeneration/RoomCreation/Rooms/";
string assetName = "";
if (type == RoomType.LeftRight) assetName = "LeftRight";
else if (type == RoomType.LeftDown) assetName = "LeftDown";
else if (type == RoomType.RightDown) assetName = "DownRight";
else if (type == RoomType.LeftUp) assetName = "LeftUp";
else if (type == RoomType.UpRight) assetName = "UpRight";
else if (type == RoomType.Start) assetName = "Start";
else if (type == RoomType.End) assetName = "End";
else if (type == RoomType.Bonus) assetName = "Bonus";
else if (type == RoomType.Empty) assetName = "Empty";
path += assetName;
if (Path.GetExtension(path) != "")
{
path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), "");
}
string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + assetName + width + "x" + height + ".asset");
room.Init(type, width, height, grid);
AssetDatabase.CreateAsset(room, assetPathAndName);
EditorUtility.SetDirty(room);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.FocusProjectWindow();
Selection.activeObject = room;
}
}
public class Room : ScriptableObject
{
public RoomType type;
public int width;
public int height;
public Tile[,] grid;
public void Init(RoomType _type, int _width, int _height, Tile[,] _grid)
{
type = _type;
width = _width;
height = _height;
grid = new Tile[width, height];
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
grid[x, y] = _grid[x, y];
}
}
}
}
The creation works fine as long as I dont exit the play mode. After exiting and entering the playmode again the array is not available but the other informations like the width and height are still saved.
Unity can't serialize 2D arrays. You need to use a 1D array [width * height] and access elements via [x + y * width].
Related
I began setting up my system by taking the Grid system supplied by Pack publishing (). This is how it's initialized:
public class Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (obj is Point)
{
Point p = obj as Point;
return this.X == p.X && this.Y == p.Y;
}
return false;
}
public override int GetHashCode()
{
unchecked
{
int hash = 6949;
hash = hash * 7907 + X.GetHashCode();
hash = hash * 7907 + Y.GetHashCode();
return hash;
}
}
public override string ToString()
{
return "P(" + this.X + ", " + this.Y + ")";
}
}
public enum CellType
{
Empty,
Road,
Structure,
SpecialStructure,
None
}
public class Grid
{
private CellType[,] _grid;
private int _width;
public int Width { get { return _width; } }
private int _height;
public int Height { get { return _height; } }
private List<Point> _roadList = new List<Point>();
private List<Point> _specialStructure = new List<Point>();
private List<Point> _houseStructure = new List<Point>();
public Grid(int width, int height)
{
_width = width;
_height = height;
_grid = new CellType[width, height];
}
public enum CellType
{
Empty,
Road,
Structure,
SpecialStructure,
None
}
public class Grid
{
private CellType[,] _grid;
private int _width;
public int Width { get { return _width; } }
private int _height;
public int Height { get { return _height; } }
private List<Point> _roadList = new List<Point>();
private List<Point> _specialStructure = new List<Point>();
private List<Point> _houseStructure = new List<Point>();
public Grid(int width, int height)
{
_width = width;
_height = height;
_grid = new CellType[width, height];
}
public void Update()
{
Console.Write("GRID IS RUNNING");
}
// Adding index operator to our Grid class so that we can use grid[][] to access specific cell from our grid.
public CellType this[int i, int j]
{
get
{
return _grid[i, j];
}
set
{
if (value == CellType.Road)
{
_roadList.Add(new Point(i, j));
}
if (value == CellType.SpecialStructure)
{
_specialStructure.Add(new Point(i, j));
}
if (value == CellType.Structure)
{
_houseStructure.Add(new Point(i, j));
}
_grid[i, j] = value;
}
}
After I initialized it, I called it from another function like this.
public int width, height;
Grid placementGrid;
private void Start()
{
placementGrid = new Grid(width, height);
Debug.Log(placementGrid.GetRandomRoadPoint());
}
It seems to initialize perfectly. But when I call the functions inside it, I'm returned a null value. I tried calling this function for example:
public Point GetRandomRoadPoint()
{
if (_roadList.Count == 0)
{
return null;
}
return _roadList[UnityEngine.Random.Range(0, _roadList.Count)];
}
I have no idea what I'm doing wrong. I'm basically trying to create a pedestrian AI system for my procedurally generated town.
I tried debugging several times, but I can't seem to find my way around it.
i'm trying to convert a string from file to 2d array. Is it possible to make the array dynamic? And how can i return the array, so i can work with it? I'm really confused.
public interface IMazeLoader
{
Maze LoadMaze(string src);
}
class MazeLoader : IMazeLoader
{
public Maze LoadMaze(string filepath)
{
var width = 5;
var height = 5;
var map = new char[width, height];
var file = new StreamReader(filepath);
string line;
var lineCount = 0;
while ((line = file.ReadLine()) != null)
{
if (lineCount < height)
{
for (int i = 0; i < width && i < line.Length; i++)
{
map[i, lineCount] = line[i];
}
}
lineCount++;
}
file.Close();
return;
}
}
Here is my Maze class :
public class Maze
{
public static readonly char CHAR_WALL = '#';
public static readonly char CHAR_START = 'S';
public static readonly char CHAR_FINISH = 'F';
public int Width { get; internal set; }
public int Height { get; internal set; }
public int StartX { get; private set;}
public int StartY { get; private set; }
public int StartAngle { get; private set; }
private char[,] _plan;
public char[,] Plan { get { return _plan; } }
public Maze(char[,] plan)
{
}
Thanks for any reply, happy Eastern btw. :)
Something like this should allow you to load any rectangular dimension map:
public class MazeLoader : IMazeLoader
{
public Maze LoadMaze(string filepath)
{
char[][] loaded =
File
.ReadLines(filepath)
.Select(x => x.ToCharArray())
.ToArray();
int[] widths =
loaded
.Select(x => x.Length)
.Distinct()
.ToArray();
if (widths.Length != 1)
{
throw new InvalidDataException("Map Data Not Rectangular");
}
else
{
var width = widths[0];
var height = loaded.Length;
var map = new char[height, width];
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
map[i, j] = loaded[i][j];
return new Maze(map);
}
}
}
Now I tested this on this input:
aaaa
aaaa
bbbb
bbbb
bbbb
And got this map:
Please note that the file orientation and the map orientation are the same. I had to flip around how you were building our your map to get that to work.
Here's my alterations to Maze itself:
public class Maze
{
public int Width => this.Plan.GetUpperBound(1) - this.Plan.GetLowerBound(1) + 1;
public int Height => this.Plan.GetUpperBound(0) - this.Plan.GetLowerBound(0) + 1;
public char[,] Plan { get; private set; }
public Maze(char[,] plan)
{
this.Plan = plan;
}
}
I have done a console game called "Labyrinth", now I want to bring it to Windows Forms, but I have some problems and exceptions and I can't understand how to make it work.
So, here is functional for printing field in console:
Base class Cell(it has children, like Wall, Door,Key,Empty, Player)
abstract class Cell
{
protected ConsoleColor foregroundColor;
protected ConsoleColor backgroundColor;
protected char symbol;
public Cell(ConsoleColor foregroundColor = ConsoleColor.White,
ConsoleColor backgroundColor = ConsoleColor.Black,
char symbol = ' ')
{
this.foregroundColor = foregroundColor;
this.backgroundColor = backgroundColor;
this.symbol = symbol;
}
public virtual void Draw()
{
Console.ForegroundColor = foregroundColor;
Console.BackgroundColor = backgroundColor;
Console.Write(symbol);
}
}
Here is class FileStorer that works with file(reads level from .txt file) and fills the array string[] field
class FileStorer
{
private string path;
public string[] Result;
public FileStorer(string path)
{
this.path = path;
Result = new string[0];
ReadFile();
}
private void Add(string item)
{
string[] newStr = new string[Result.Length + 1];
for (int i = 0; i < Result.Length; i++)
{
newStr[i] = Result[i];
}
newStr[Result.Length] = item;
Result = newStr;
}
public void ReadFile()
{
using (StreamReader sr = new StreamReader(path, System.Text.Encoding.Default))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Add(line);
}
}
}
}
Class Field
class Field
{
private bool toggle_key = false;
private Cell[,] field;
public int Width
{
get { return field.GetLength(1); }
}
public int Height
{
get { return field.GetLength(0); }
}
public Field(int width, int height)
{
field = new Cell[height, width];
}
public Cell this[int x, int y]
{
get { return field[y, x]; }
set { field[y, x] = value; }
}
public void Print()
{
Console.SetCursorPosition(0, 0);
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
this[x, y].Draw();
}
Console.WriteLine();
}
}
public bool NotOutOfField(int x, int y)
{
return x >= 0 && x < Width && y >= 0 && y < Height;
}
public void MakeEmpty(int x, int y)
{
this[x, y] = new Empty();
}
public bool CanMakeStep(int x, int y)
{
if (NotOutOfField(x, y) && this[x, y] is Empty)
return true;
if (NotOutOfField(x, y) && this[x, y] is Key && !toggle_key)
{
toggle_key = true;
Key.count--;
return true;
}
if (NotOutOfField(x, y) && this[x, y] is Door && toggle_key)
{
toggle_key = false;
Door.count--;
return true;
}
return false;
}
}
Here is class LevelLoader that fills array Cell[,] with proper classes (Door,Key etc.)
class LevelLoader
{
private string[] field;
public LevelLoader(int level)
{
field = new FileStorer($"../../Levels/{level}.txt").Result;
}
public void LoadField(out Field cellField, out Player player)
{
cellField = new Field(field[0].Length, field.Length);
player = new Player(0, 0);
for (int y = 0; y < field.Length; y++)
{
for (int x = 0; x < field[y].Length; x++)
{
switch (field[y][x])
{
case '#':
cellField[x, y] = new Wall();
break;
case ' ':
cellField[x, y] = new Empty();
break;
case 'K':
cellField[x, y] = new Key();
break;
case 'D':
cellField[x, y] = new Door();
break;
case 'P':
player = new Player(x, y);
goto case ' ';
default:
break;
}
}
}
}
}
And finally in class Level I have methods that puts characters on field and prints them
private void PutCharactersOnField()
{
for (int y = 0; y < gameField.Height; y++)
{
for (int x = 0; x < gameField.Width; x++)
{
if (!(gameField[x, y] is Wall) && !((gameField[x, y] is Key)) && !((gameField[x, y] is Door)))
{
gameField[x, y] = new Empty();
}
}
}
gameField[player.X, player.Y] = player;
}
public void PrintLevel()
{
gameField.Print();
player.Draw();
LivesMessage();
if (Door.count == 0)
{
Win();
};
}
I have done some changes for winforms, and I got IndexOutOfRanfeExceprion, I can't understand what went wrong, so here are the same classes and functions but changed for Winforms.
Class Cell
public abstract class Cell
{
public string Path;
public Image Image;
public Cell(string path)
{
Path = path;
if (!File.Exists(Path))
{
throw new Exception("File does not exist: " + Path);
}
Image = new Bitmap(Path);
}
public virtual void Draw(Graphics gr, int j, int i, int side, int x, int y)
{
gr.DrawImage(this.Image, j * side + x, i * side + y, new Rectangle(new Point(0, 0), new Size(side, side)), GraphicsUnit.Pixel);
}
}
FileStorer wasn't modified.
Class Player
public class Player:Cell
{
public string path;
protected Direction direction;
public Image SpriteAnimation;
public int X, Y;
public Size Scale;
public int CurrentFrame = 2;
public int CurrentAnimation = 5;
public Image Part;
public int speed;
public Direction CurrentDirection
{
get { return direction; }
}
public Player() : base("D:\\GIT\\maze-game\\MazeGame\\MazeGame\\Resources\\sprite.png") { }
public Player(Size scale, int x, int y, Image spriteAnimation):base("D:\\GIT\\maze-game\\MazeGame\\MazeGame\\Resources\\sprite.png")
{
SpriteAnimation = spriteAnimation;
Scale = scale;
X = x;
Y = y;
speed = 2;
if (!File.Exists(Path))
{
throw new Exception("File does not exist: " + Path);
}
base.Image = new Bitmap(Path);
}
public Player(int x, int y) : base("D:\\GIT\\maze-game\\MazeGame\\MazeGame\\Resources\\sprite.png")
{
X = x;
Y = y;
}
public void Action()
{
switch (direction)
{
case Direction.Left:
CurrentAnimation = 1;
break;
case Direction.Up:
CurrentAnimation = 3;
break;
case Direction.Right:
CurrentAnimation = 0;
break;
case Direction.Down:
CurrentAnimation = 2;
break;
}
}
public void Static()
{
switch (direction)
{
case Direction.Left:
CurrentAnimation = 6;
break;
case Direction.Up:
CurrentAnimation = 8;
break;
case Direction.Right:
CurrentAnimation = 5;
break;
case Direction.Down:
CurrentAnimation = 7;
break;
}
}
public void Rotate(int dx, int dy)
{
if (dx == -speed)
direction = Direction.Left;
else if (dx == speed)
direction = Direction.Right;
else if (dy == -speed)
direction = Direction.Up;
else if (dy == speed)
direction = Direction.Down;
}
public void MakeStep(int dx, int dy)
{
X += dx;
Y += dy;
}
public void DrawAction(Graphics gr, int x, int y)
{
gr.DrawImage(SpriteAnimation, X + x, Y + y, new Rectangle(new Point(75 * CurrentFrame, 170 * CurrentAnimation), new Size(75, 170)), GraphicsUnit.Pixel);
}
public void DrawStatic(Graphics gr, int x, int y)
{
gr.DrawImage(SpriteAnimation, X + x, Y + y, new Rectangle(new Point(75 * CurrentFrame, 170 * (CurrentAnimation - 5)), new Size(75, 170)), GraphicsUnit.Pixel);
}
}
Class LevelLoader was modified juct for player cell
case 'P':
player = new Player(new Size(35, 75), 100, 100,player.Image);
goto case ' ';
Class Field
class Field
{
private bool toggle_key = false;
private readonly Cell[,] field;
public int Width
{
get { return field.GetLength(1); }
}
public int Height
{
get { return field.GetLength(0); }
}
public Field(int width, int height)
{
field = new Cell[height, width];
}
public Cell this[int x, int y]
{
get { return field[y, x]; }
set { field[y, x] = value; }
}
public void Print(Graphics gr, int side, int j, int i)
{
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
this[x, y].Draw(gr, x, y,side, j, i);
}
}
}
public bool NotOutOfField(int x, int y)
{
return x >= 0 && x < Width && y >= 0 && y < Height;
}
public void MakeEmpty(int x, int y)
{
this[x, y] = new Empty();
}
public bool CanMakeStep(int x, int y)
{
if (NotOutOfField(x, y) && this[x, y] is Empty)
return true;
if (NotOutOfField(x, y) && this[x, y] is Key && !toggle_key)
{
toggle_key = true;
Key.count--;
return true;
}
if (NotOutOfField(x, y) && this[x, y] is Door && toggle_key)
{
toggle_key = false;
Door.count--;
return true;
}
return false;
}
}
Here are Level class method PrintLevel,(PutCharactersOnField wasn't modified)
public void PrintLevel(Graphics gr)
{
gameField.Print(gr, mapSide,point.X, point.Y);
player.DrawStatic(gr, point.X,point.Y);
if (Door.count == 0)
{
Win();
};
}
I'm very new in this topic, but I want to deal with this issue.So, I need help, what is wrong, where I made a mistake?
**Exception was called in the stack of calls
I got some problem with my Tetris game on highscore, here's the game script
/// The width of the Grid...
public static int gridWidth = 10;
/// The weight of the Grid...
public static int gridWeight = 20;
/// The grid...
public static Transform[,] grid = new Transform[gridWidth, gridWeight];
public static bool startingAtLevelZero;
public static int startingLevel;
public int scoreOneLine = 50;
public int scoreTwoLine = 100;
public int scoreThreeLine = 400;
public int scoreFourLine = 1500;
public int currentLevel = 0;
private int numLinesCleared = 0;
public static float fallSpeed = 1.0f;
public AudioClip clearedLineSound;
public Text hud_score;
public Text hud_level;
public Text hud_lines;
private int numberOfRowsThisTurn = 0;
private AudioSource audioSource;
public static int currentScore = 0;
private GameObject previewTetromino;
private GameObject nextTetromino;
private bool gameStarted = false;
private int startingHighScore;
private int startingHighScore2;
private int startingHighScore3;
private Vector2 previewTetrominoPosition = new Vector2(-6.5f, 16);
// Start is called before the first frame update
void Start()
{
currentScore = 0;
hud_score.text = "0";
currentLevel = startingLevel;
hud_level.text = currentLevel.ToString();
hud_lines.text = "0";
SpawnNextTetromino();
audioSource = GetComponent<AudioSource>();
startingHighScore = PlayerPrefs.GetInt("highScore");
startingHighScore2 = PlayerPrefs.GetInt("highscore2");
startingHighScore3 = PlayerPrefs.GetInt("highscore3");
}
void Update()
{
UpdateScore();
UpdateUI();
UpdateLevel();
UpdateSpeed();
}
void UpdateLevel()
{
if ((startingAtLevelZero == true) || (startingAtLevelZero == false && numLinesCleared / 10 > startingLevel))
currentLevel = numLinesCleared / 10;
Debug.Log("current Level : " + currentLevel);
}
void UpdateSpeed()
{
fallSpeed = 1.0f - ((float)currentLevel * 0.1f);
Debug.Log("current Fall Speed : " + fallSpeed);
}
public void UpdateUI()
{
hud_score.text = currentScore.ToString();
hud_level.text = currentLevel.ToString();
hud_lines.text = numLinesCleared.ToString();
}
public void UpdateScore()
{
if (numberOfRowsThisTurn > 0)
{
if (numberOfRowsThisTurn == 1)
{
ClearedOneLine();
}
else if (numberOfRowsThisTurn == 2)
{
ClearedOneLine();
}
else if (numberOfRowsThisTurn == 3)
{
ClearedThreeLine();
}
else if (numberOfRowsThisTurn == 4)
{
ClearedFourLine();
}
numberOfRowsThisTurn = 0;
PlayLineClearedSound();
}
}
public void ClearedOneLine()
{
currentScore += scoreOneLine + (currentLevel * 20);
numLinesCleared++;
}
public void ClearedTwoLine()
{
currentScore += scoreTwoLine + (currentLevel * 25);
numLinesCleared += 2;
}
public void ClearedThreeLine()
{
currentScore += scoreThreeLine + (currentLevel * 30);
numLinesCleared += 3;
}
public void ClearedFourLine()
{
currentScore += scoreFourLine + (currentLevel * 40);
numLinesCleared += 4;
}
public void PlayLineClearedSound()
{
audioSource.PlayOneShot(clearedLineSound);
}
public void UpdateHighScore()
{
if (currentScore > startingHighScore)
{
PlayerPrefs.SetInt("highScore3", startingHighScore2);
PlayerPrefs.SetInt("highScore2", startingHighScore);
PlayerPrefs.SetInt("highscore", currentScore);
}
else if (currentScore > startingHighScore2)
{
PlayerPrefs.SetInt("highScore3", startingHighScore2);
PlayerPrefs.SetInt("highscore2", currentScore);
}
else if (currentScore > startingHighScore3)
{
PlayerPrefs.SetInt("highscore3", currentScore);
}
}
public bool CheckIsAboveGrid(Tetromino tetromino)
{
for (int x = 0; x < gridWidth; ++x)
{
foreach (Transform mino in tetromino.transform)
{
Vector2 pos = Round(mino.position);
if (pos.y > gridWeight - 1)
{
return true;
}
}
}
return false;
}
public bool IsFullRowAt (int y)
{
for (int x = 0; x < gridWidth; ++x)
{
if (grid [x, y] == null)
{
return false;
}
}
numberOfRowsThisTurn++;
return true;
}
public void DeleteMinoAt(int y)
{
for (int x = 0; x < gridWidth; ++x)
{
Destroy(grid[x, y].gameObject);
grid[x, y] = null;
}
}
public void MoveRowDown (int y)
{
for (int x = 0; x < gridWidth; ++x)
{
if (grid[x, y] != null)
{
grid[x,y -1] = grid[x, y];
grid[x, y] = null;
grid[x, y -1].position += new Vector3(0, -1, 0);
}
}
}
public void MoveAllRowsDown (int y)
{
for (int i = y; i < gridWeight; ++i)
{
MoveRowDown(i);
}
}
public void DeleteRow()
{
for (int y = 0; y < gridWeight; ++y)
{
if (IsFullRowAt(y))
{
DeleteMinoAt(y);
MoveAllRowsDown(y + 1);
--y;
}
}
}
public void UpdateGrid (Tetromino tetromino)
{
for (int y = 0; y < gridWeight; ++y)
{
for (int x = 0; x < gridWidth; ++x)
{
if (grid[x, y] != null)
{
if (grid[x,y].parent == tetromino.transform)
{
grid[x, y] = null;
}
}
}
}
foreach (Transform mino in tetromino.transform)
{
Vector2 pos = Round(mino.position);
if (pos.y < gridWeight)
{
grid[(int)pos.x, (int)pos.y] = mino;
}
}
}
public Transform GetTransformAtGridPosition (Vector2 pos)
{
if (pos.y > gridWeight -1)
{
return null;
}
else
{
return grid[(int)pos.x, (int)pos.y];
}
}
public void SpawnNextTetromino()
{
if (!gameStarted)
{
gameStarted = true;
nextTetromino = (GameObject)Instantiate(Resources.Load(GetRandomTetromino(), typeof(GameObject)), new Vector2(5.0f, 20.0f), Quaternion.identity);
previewTetromino = (GameObject)Instantiate(Resources.Load(GetRandomTetromino(), typeof(GameObject)), previewTetrominoPosition, Quaternion.identity);
previewTetromino.GetComponent<Tetromino>().enabled = false;
}
else
{
previewTetromino.transform.localPosition = new Vector2(5.0f, 20.0f);
nextTetromino = previewTetromino;
nextTetromino.GetComponent<Tetromino>().enabled = true;
previewTetromino = (GameObject)Instantiate(Resources.Load(GetRandomTetromino(), typeof(GameObject)), previewTetrominoPosition, Quaternion.identity);
previewTetromino.GetComponent<Tetromino>().enabled = false;
}
}
public bool CheckIsInsideGrid (Vector2 pos)
{
return ((int)pos.x >= 0 && (int)pos.x < gridWidth && (int)pos.y >= 0);
}
public Vector2 Round (Vector2 pos)
{
return new Vector2(Mathf.Round(pos.x), Mathf.Round(pos.y));
}
string GetRandomTetromino()
{
int randomTetromino = Random.Range(1, 8);
string randomTetrominoName = "Prefabs/Tetromino_T";
switch (randomTetromino)
{
case 1:
randomTetrominoName = "Prefabs/Tetromino_T";
break;
case 2:
randomTetrominoName = "Prefabs/Tetromino_Long";
break;
case 3:
randomTetrominoName = "Prefabs/Tetromino_Square";
break;
case 4:
randomTetrominoName = "Prefabs/Tetromino_J";
break;
case 5:
randomTetrominoName = "Prefabs/Tetromino_L";
break;
case 6:
randomTetrominoName = "Prefabs/Tetromino_S";
break;
case 7:
randomTetrominoName = "Prefabs/Tetromino_Z";
break;
}
return randomTetrominoName;
}
public void GameOver()
{
UpdateHighScore();
Application.LoadLevel("GameOver");
}
and here's the game menu script
public Text levelText;
public Text highScoreText;
public Text highScoreText2;
public Text highScoreText3;
// Start is called before the first frame update
void Start()
{
levelText.text = "0";
highScoreText.text = PlayerPrefs.GetInt("highscore").ToString();
highScoreText2.text = PlayerPrefs.GetInt("highscore2").ToString();
highScoreText3.text = PlayerPrefs.GetInt("highScore3").ToString();
}
public void PlayGame()
{
if (Game.startingLevel == 0)
Game.startingAtLevelZero = true;
else
Game.startingAtLevelZero = false;
Application.LoadLevel("tetris");
}
public void ChangedValue (float value)
{
Game.startingLevel = (int)value;
levelText.text = value.ToString();
}
public void LaunchGameMenu()
{
Application.LoadLevel("tetris menu");
}
When I got 1120 score in the Tetris game, it shows up in 2nd score instead of 3rd or 1st ,when I got 720 score, it doesn't show up in 3rd score, when I score 1300 It shows up in 2nd and 1120 in 3rd, but not in 1st, can somehow help me what is wrong?
It appears you have various typographical errors while typing the keys when accessing the player's PlayerPrefs. PlayerPrefs is case-sensitive.
↓↓↓
startingHighScore = PlayerPrefs.GetInt("highScore");
startingHighScore2 = PlayerPrefs.GetInt("highscore2");
startingHighScore3 = PlayerPrefs.GetInt("highscore3");
...
↓↓↓
highScoreText.text = PlayerPrefs.GetInt("highscore").ToString();
Consider the use of the nameof() command. The nameof() command allows you to treat a variable in-code as a string. This is SUPER helpful if you ever re-name the variable for example, the string will be renamed along with it. It also has the added bonus of giving you compilation errors if they are misspelled.
Example:
public Text levelText;
public Text highScoreText;
public Text highScoreText2;
public Text highScoreText3;
// Start is called before the first frame update
void Start()
{
levelText.text = "0";
highScoreText.text = PlayerPrefs.GetInt(nameof(highScoreText)).ToString();
highScoreText2.text = PlayerPrefs.GetInt(nameof(highScoreText2)).ToString();
highScoreText3.text = PlayerPrefs.GetInt(nameof(highScoreText3)).ToString();
}
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
So in a few words i'm getting an error whenever i run this
System.NullReferenceException
Ball.boxContent.get returned null
i get this error on this line
box1.Content.Add(Myballs[5]);
what I'm doing is creating balls of different colors,weight and material
adding them into a list called MyBalls
then
adding them from that list into a box(that has a property that is a list called Content)
after this is done I'm supposed to call some of the box function and calculate the weight and print what is inside. Not yet reached this stage as i cannot
any help would be greatly appreciated
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace Ball
{
class Ball
{
private string color;
private string material;
private double weight;
public string Color { get; set; }
public string Material { get; set; }
public double Weight { get; set; }
public Ball() { }
public Ball(string color, double weight, string material)
{
this.Color = color;
this.Material = material;
this.Weight = weight;
}
public bool changecolorbymorethanweight(string c, double w)
{
if (Weight >= w)
{
Color = c;
return true;
}
else return false;
}
public void printall()
{
Console.WriteLine("Η μπάλα είναι χρώματος {0}\nυλικού {1}\nκαι βάρους {2}", Color, Material, Weight);
}
}
-
class Box
{
private double height;
private double width;
private double length;
private string material;
public List<Ball> content = new List<Ball>();
private double weight;
public double Height { get; set; }
public double Width { get; set; }
public double Length { get; set; }
public string Material { get; set; }
public List<Ball> Content { get; set; }
public double Weight
{
get
{
double varos = 0;
for (int i = 0; i < content.Count; i++)
{
varos = varos + content[i].Weight;
}
weight = varos;
return weight;
}
set
{
Weight = weight;
}
}
public void removefirst3()
{
Content.RemoveAt(0);
Content.RemoveAt(1);
Content.RemoveAt(2);
}
public void removeall()
{
Content.Clear();
}
public void removeallbycolor(string rbc)
{
for (int i = 0; i < Content.Count; i++)
if (Content[i].Color == rbc)
Content.RemoveAt(i);
}
public int getnumberbycolor(string gnbc)
{
int counter = 0;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Color == gnbc)
counter++;
return counter;
}
public bool removeallmorethanbyweight(double rbwb)
{
bool result = false;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Weight >= rbwb)
{
Content.RemoveAt(i);
result = true;
}
return result;
}
public bool removealllessthanbyweight(double rbws)
{
bool result = false;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Weight >= rbws)
{
Content.RemoveAt(i);
result = true;
}
return result;
}
public bool removeallbymaterial(string rabm)
{
bool result = false;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Material == rabm)
{
Content.RemoveAt(i);
result = true;
}
return result;
}
public void changecolorbyposition(int p, string c)
{
for (int i = 0; i < Content.Count; i++)
if (i == p)
Content[i].Color = c;
}
public void printall()
{
Console.WriteLine("Tο κουτί μας έχει \n{0} ύψος\n{1} πλάτος\n{2} μήκος\nείναι φτιαγμένο από {3}\nτο βάρος του είναι {4}\n και μέσα του έχει:\n{5}", Height, Width, Length, Material, Weight, Content);
}
public Box() { }
public Box(double length, double width, double height, string material, double weight, List<Ball> content)
{
this.Length = length;
this.Width = width;
this.Height = height;
this.Material = material;
this.Weight = weight;
this.Content = content;
}
public Box(double length, double width, double height, string material)
{
this.Length = length;
this.Width = width;
this.Height = height;
this.Material = material;
}
}
-
class Program
{
static void Main(string[] args)
{
Box box1 = new Box(1.2, 1.3, 1.8, "χάρτινο");
Box box2 = new Box(1.2, 2.3, 2.5, "ξύλινο");
Ball b1 = new Ball("Red", 2.5, "μεταλλική");
Ball b2 = new Ball("Red", 2.5, "μεταλλική");
Ball b3 = new Ball("Red", 2.5, "μεταλλική");
Ball b4 = new Ball("Red", 1.5, "μεταλλική");
Ball b5 = new Ball("Red", 1.5, "μεταλλική");
Ball b6 = new Ball("Black", 0.5, "πλαστική");
Ball b7 = new Ball("Black", 0.5, "πλαστική");
Ball b8 = new Ball("Black", 0.5, "πλαστική");
Ball b9 = new Ball("Black", 0.5, "πλαστική");
Ball b10 = new Ball("Black", 0.5, "πλαστική");
Ball b11 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b12 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b13 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b14 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b15 = new Ball("Άσπρο", 1.1, "λαστιχένια");
List<Ball> Myballs = new List<Ball>() { b1, b2 };
Myballs.Capacity = 15;
Myballs.Add(b1);
Myballs.Add(b2);
Myballs.Add(b3);
Myballs.Add(b4);
Myballs.Add(b5);
Myballs.Add(b6);
Myballs.Add(b7);
Myballs.Add(b8);
Myballs.Add(b9);
Myballs.Add(b10);
Myballs.Add(b11);
Myballs.Add(b12);
Myballs.Add(b13);
Myballs.Add(b14);
Myballs.Add(b15);
box1.Content.Add(Myballs[5]);
box1.Content.Add(Myballs[6]);
box1.Content.Add(Myballs[7]);
box1.Content.Add(Myballs[8]);
box1.Content.Add(Myballs[9]);
box1.Content.Add(Myballs[10]);
box1.Content.Add(Myballs[11]);
box1.Content.Add(Myballs[12]);
box1.Content.Add(Myballs[13]);
box1.Content.Add(Myballs[14]);
box2.Content.Add(Myballs[0]);
box2.Content.Add(Myballs[1]);
box2.Content.Add(Myballs[2]);
box2.Content.Add(Myballs[3]);
box2.Content.Add(Myballs[4]);
Console.ReadKey();
}
}
}
Initialize the Content property, either in the Box class:
public List<Ball> Content { get; set; } = new List<Ball>();
...or in the Main method before you add any balls:
box1.Content = new List<Ball>();
box1.Content.Add(Myballs[5]);
...