NullReferenceException in child class when referring to member of parent [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
Pretty much the title. I first set it in the first method and as soon as I wanna call it up it says it´s empty. Even in the Inspector it says that it´s set to the right thing but it can´t be called for some reason.
The two relevant code snippets:
public class WUZ_Unit : Leader
{
public override void UpdatePosition()
{
vecPos = GameObject.Find("WUZ(Clone)").transform.position;
Debug.Log(this + " the grid: " + grid);
**position = grid.GetNode((int)vecPos.x, (int)vecPos.y);**
}
}
and:
public abstract class Entity : MonoBehaviour {
public void InitiateGrid(Gridmanager g)
{
anim = GetComponent<Animator>();
if (anim.gameObject.activeSelf)
{
anim.SetBool("IsAlive", true);
}
grid = g;
Debug.Log(this + " set " + grid);
}
}
what the console spits out on the first Debug Log:
and what the console spits out on the second Debug Log:
This is the Error Code in Text:
NullReferenceException: Object reference not set to an instance of an object
WUZ_Unit.UpdatePosition () (at Assets/Scripts/Unit/WUZ_Unit.cs:21)
GameHandler.UpdateAllMoves () (at Assets/Scripts/GameHandler.cs:1805)
GameHandler.Start () (at Assets/Scripts/GameHandler.cs:1697)
The asked for code regarding instantiation:
public void GenerateCharacters(int x, int y, GameObject c, int i)
{
GameObject go = Instantiate(c) as GameObject;
//Entity e = go.GetComponent<Entity>();
//StartCoroutine(e.SpawnAnim());
if (i == 0)
{
Unit u = go.GetComponent<Unit>();
go.GetComponent<Enemy>().enabled = false;
u.enabled = true;
u.InitializeUnits();
u.healthBarEnemy = healthBarEnemy;
u.healthBarAlly = healthBarAlly;
u.healthMeter = healthbarMeter;
u.highlightAttack = highlightAttack;
u.highlightIndicator = highlightIndicator;
u.highlightMove = highlightMove;
u.InitiateGrid(grid);
u.SetPos(x, y);
GeneratePosition(u, x, y);
u.PlayerChange(gamePhase);
go.GetComponent<Enemy>().enabled = false;
}
This is the asked for code regarding updateposition:
public void UpdateAllMoves()
{
Debug.Log("updating all moves");
//Updating the grid status
grid.UpdatePosition();
Unit[] ul = unitList.ToArray();
for (int i = 0; i < ul.Length; i++)
{
ul[i].UpdatePosition();
}
Enemy[] el = enemyList.ToArray();
for (int i = 0; i < el.Length; i++)
{
el[i].UpdatePosition();
}
CheckforCheckUnit(grid);
CheckforCheckEnemy(grid);
ConvertAllMoves();
grid.ClearNodeMoves();
grid.UpdatePosition();
UpdateNodes();
grid.UpdatePosition();
for (int i = 0; i < ul.Length; i++)
{
**ul[i].UpdatePosition();**
}
for (int i = 0; i < el.Length; i++)
{
el[i].UpdatePosition();
}
CheckforCheckUnit(grid);
CheckforCheckEnemy(grid);
ConvertAllMoves();
grid.ClearNodeMoves();
grid.UpdatePosition();
UpdateNodes();
}
so I made sure that vecPos is not the problem:
Debug.Log(this + " the grid: " + grid + " the vecPos " + vecPos.x + " " + vecPos.y);
What the console spits out:
WUZ (WUZ_Unit) the grid: the vecPos 2 28
UnityEngine.Debug:Log(Object)
WUZ_Unit:UpdatePosition() (at Assets/Scripts/Unit/WUZ_Unit.cs:20)
GameHandler:UpdateAllMoves() (at Assets/Scripts/GameHandler.cs:1805)
GameHandler:Start() (at Assets/Scripts/GameHandler.cs:1697)
more clarification code:
public void GettingCharacters()
{
Debug.Log(StaticPara.player1Units.Length);
for(int i = 0; StaticPara.player1Units.Length > i; i++)
{
unitList.Add(StaticPara.player1Units[i].GetComponent<Unit>());
int x = startingTilesBlue[i].xPos;
int y = startingTilesBlue[i].yPos;
GenerateCharacters(x, y, StaticPara.player1Units[i], 0);
}
for (int i = 0; StaticPara.player2Units.Length > i; i++)
{
enemyList.Add(StaticPara.player2Units[i].GetComponent<Enemy>());
int x = startingTilesRed[i].xPos;
int y = startingTilesRed[i].yPos;
GenerateCharacters(x, y, StaticPara.player2Units[i], 1);
}
}
void Start()
{
grid = gridGO.GetComponent<Gridmanager>();
grid.CreateGrid();
//setting up ui and the game
gamePhase = 0;
phaseStatusString = "Move Phase";
endPhaseButton.GetComponent<Button>().interactable = false;
ability_ALX = true;
//spawning character Models
GenerateStartingPositions();
GettingCharacters();
//Updating their stats
Unit[] ul = unitList.ToArray();
for (int i = 0; i < ul.Length; i++)
{
ul[i].healthMax = ul[i].healthBase;
ul[i].healthCurrent = ul[i].healthMax;
ul[i].damageCurrent = ul[i].damageBase;
}
Enemy[] el = enemyList.ToArray();
for (int i = 0; i < el.Length; i++)
{
el[i].healthMax = el[i].healthBase;
el[i].healthCurrent = el[i].healthMax;
el[i].damageCurrent = el[i].damageBase;
}
SelectKing();
**UpdateAllMoves();**
}
Here is the Update Nodes Function:
public void UpdateNodes()
{
for(int i = 0; i < unitList.Count; i++)
{
for(int j = 0; j < unitList[i].possibleMoves.Length; j++)
{
for(int k = 0; k < unitList[i].possibleMoves[j].Count; k++)
{
unitList[i].possibleMoves[j][k].moveableByUnit.Add(new CheckAssist(unitList[i], j));
}
}
for (int j = 0; j < unitList[i].possibleAttacks.Length; j++)
{
for (int k = 0; k < unitList[i].possibleAttacks[j].Count; k++)
{
unitList[i].possibleAttacks[j][k].attackableByUnit.Add(new CheckAssist(unitList[i], j));
}
}
for (int j = 0; j < unitList[i].possibleAttackIndicators.Length; j++)
{
for (int k = 0; k < unitList[i].possibleAttackIndicators[j].Count; k++)
{
unitList[i].possibleAttackIndicators[j][k].attackableByUnit.Add(new CheckAssist(unitList[i], j));
}
}
for (int j = 0; j < unitList[i].possibleAttacksInactive.Length; j++)
{
for (int k = 0; k < unitList[i].possibleAttacksInactive[j].Count; k++)
{
unitList[i].possibleAttacksInactive[j][k].passiveAAByUnit.Add(new CheckAssist(unitList[i], j));
}
}
}
for (int i = 0; i < enemyList.Count; i++)
{
for (int j = 0; j < enemyList[i].possibleMoves.Length; j++)
{
for (int k = 0; k < enemyList[i].possibleMoves[j].Count; k++)
{
enemyList[i].possibleMoves[j][k].moveableByEnemy.Add(new CheckAssist(enemyList[i], j));
}
}
for (int j = 0; j < enemyList[i].possibleAttacks.Length; j++)
{
for (int k = 0; k < enemyList[i].possibleAttacks[j].Count; k++)
{
enemyList[i].possibleAttacks[j][k].attackableByEnemy.Add(new CheckAssist(enemyList[i], j));
//Debug.Log("added attack to" + enemyList[i].possibleAttackIndicators[j][k].xPos + " " + enemyList[i].possibleAttackIndicators[j][k].yPos);
}
}
for (int j = 0; j < enemyList[i].possibleAttackIndicators.Length; j++)
{
for (int k = 0; k < enemyList[i].possibleAttackIndicators[j].Count; k++)
{
enemyList[i].possibleAttackIndicators[j][k].attackableByEnemy.Add(new CheckAssist(enemyList[i], j));
//Debug.Log("added attack to" + enemyList[i].possibleAttackIndicators[j][k].xPos + " " + enemyList[i].possibleAttackIndicators[j][k].yPos);
}
}
for (int j = 0; j < enemyList[i].possibleAttacksInactive.Length; j++)
{
for (int k = 0; k < enemyList[i].possibleAttacksInactive[j].Count; k++)
{
enemyList[i].possibleAttacksInactive[j][k].passiveAAByEnemy.Add(new CheckAssist(unitList[i], j));
}
}
}
}

The problem seems to be that some line among these:
CheckforCheckUnit(grid);
CheckforCheckEnemy(grid);
ConvertAllMoves();
grid.ClearNodeMoves();
grid.UpdatePosition();
UpdateNodes();
grid.UpdatePosition();
is modifying the Units in unitList in some way that sets the Unit.grid value to null.
Something else you might consider is adding GridManager as a parameter to UpdatePosition():
public override void UpdatePosition(GridManager gameGrid) {
vecPos = GameObject.Find("WUZ(Clone)").transform.position;
Debug.Log(this + " the grid: " + gameGrid);
position = gameGrid.GetNode((int)vecPos.x, (int)vecPos.y);
}
and then in UpdateAllMoves, include it in the calls. e.g.:
...
el[i].UpdatePosition(grid);
...
ul[i].UpdatePosition(grid);
...

I fixed my own Code and here is how:
unitList.Add(StaticPara.player1Units[i].GetComponent<Unit>());
int x = startingTilesBlue[i].xPos;
int y = startingTilesBlue[i].yPos;
GenerateCharacters(x, y, StaticPara.player1Units[i], 0);
I added the Unit script from the passed the GameObject rather than the Unit script from the instantiated Gameobject meaning I changed variables that were not even in the List
Thanks for all the help #ruzihm
EDIT: Yes I did I moved unitList.Add from GettingCharacters() to GenerateCharacters()

Related

How to remove an element from an array and resize the array

I want to remove a specific object from an array, put it in a smaller array without getting out of range. This is what I've tried but it won't work.
Skateboard[] newSkateboard = new Skateboard[_skateboards.Length - 1];
for (int i = 0; i < _skateboards.Length; i++)
{
if (skateboard.Code != _skateboards[i].Code)
{
newSkateboard[i] = _skateboards[i];
}
}
Sure.
var j = 0;
for (int i = 0; i < _skateboards.Length; i++)
{
if (skateboard.Code != _skateboards[i].Code)
{
newSkateboard[j] = _skateboards[i];
j = j + 1;
}
}

Unity: Index was outside the bounds of the Array

im developing with Unity for about a year now and very often I got this Error:
IndexOutOfRangeException: Index was outside the bounds of the array.
I know that that error means that the given index is bigger then the array itself. But I dont think that the Array is bigger than the used value.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ProceduralGeneration : MonoBehaviour
{
public GameObject[,] tiles = new GameObject[3000, 3000];
public GameObject[] prefabs;
int sizeyet = 0;
GameObject obj;
public int renderdistance;
int[,] map;
// Start is called before the first frame update
void Start()
{
map = CreateMap(map);
for (int i = 0; i < map.Length; i++)
{
for (int j = 0; j < map.Length; j++)
{
obj = Instantiate(prefabs[map[i,j]], new Vector2(i, j), Quaternion.identity);
tiles[i, j] = obj;
}
}
}
public int[,] CreateMap(int[,] map)
{
map = new int[4000, 4000];
for(int i = 0; i < 3000 - 1; i++)
{
for(int j = 0; i < 3000 - 1; j++)
{
map[i, j] = Mathf.RoundToInt(Mathf.PerlinNoise(i, j) * 10);
}
}
return map;
}
// Update is called once per frame
void Update()
{
}
}
I very often canceled project because I couldn't fix this error.
If my English is not so good, excuse me. Im a german student.
There are a few problems here. Firstly, there's a typo in CreateMap:
for(int j = 0; i < 3000 - 1; j++)
Note how you're using i in the condition instead of j - so that loop will never terminate, assuming that i is less than 2999 to start with. But even changing that won't fix the bigger problem. Let's look at the rest of the code.
Here's how you initialize map:
map = new int[4000, 4000];
And here's how you initialize tiles:
public GameObject[,] tiles = new GameObject[3000, 3000];
So map.Length is 16000000, because that's the total size of the array.
Now let's look at your loop:
for (int i = 0; i < map.Length; i++)
{
for (int j = 0; j < map.Length; j++)
{
obj = /* irrelevant */
tiles[i, j] = obj;
}
}
So your code is a bit like this:
GameObject[,] tiles = new GameObject[3000, 3000];
for (int i = 0; i < 16000000; i++)
{
for (int j = 0; j < 16000000; j++)
{
tiles[i, j] = something;
}
}
Can you see how that's clearly going to go way out of bounds?
Even if the code behaved as you expected it to, tiles is 3000x3000 and map is 4000x4000, so that would be a problem.
I suggest you create some constants, and use those everywhere:
private const int MapWidth = 4000;
private const int MapHeight = 4000;
public GameObject[,] tiles = new GameObject[MapWidth, MapHeight];
...
// Then later...
for (int i = 0; i < MapWidth; i++)
{
for (int j = 0; j < MapHeight; j++)
{
tiles[i, j] = ...;
}
}
// And in CreateMap:
map = new int[MapWidth, MapHeight];
for (int i = 0; i < MapWidth; i++)
{
for (int j = 0; j < MapHeight; j++)
{
map[i, j] = Mathf.RoundToInt(Mathf.PerlinNoise(i, j) * 10);
}
}

How to get all possible 2x2 sub matrices in a 3x3 matrix in C#?

If matrix A of size (3x3), then should i use the method of finding determinants, like grabbing the rows and column of first element and removing it from the array 2D array to get the remaining elements and then moving to the next element and repeating the same steps ?
[{1,2,3},
{4,5,6},
{7,8,9}]
I finally was able to do it, here's what I did :
enter image description here
class program
{
public static void Main()
{
int[,] arr = new int[3, 3];
Console.WriteLine("Enter elements of " + (arr.GetUpperBound(0) + 1) + "x" + (arr.GetUpperBound(1) + 1) + " matrix:");
for (int i = 0; i < (arr.GetUpperBound(0) + 1); i++)
{
for (int j = 0; j < (arr.GetUpperBound(1) + 1); j++)
{
arr[i, j] = Convert.ToInt32(Console.ReadLine());
}
}
Console.WriteLine("Matrix entered: ");
for (int i = 0; i < (arr.GetUpperBound(0) + 1); i++)
{
for (int j = 0; j < (arr.GetUpperBound(1) + 1); j++)
{
Console.Write("\t" + arr[i, j]);
}
Console.WriteLine();
}
Console.WriteLine("Possible sub-matrices: ");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j< 3; j++)
{
TrimArray(i,j,arr);
}
}
}
public static int[,] TrimArray(int row, int column, int[,] original)
{
int[,] resultant = new int[original.GetLength(0) - 1, original.GetLength(1) - 1];
for (int i = 0, j = 0; i < original.GetLength(0); i++)
{
if (i == row)
continue;
for (int k = 0, u = 0; k < original.GetLength(1); k++)
{
if (k == column)
continue;
resultant[j, u] = original[i, k];
u++;
}
j++;
}
Console.WriteLine();
for (int i = 0; i < 2; i++)
{
for (int j = 0; j< 2; j++)
{
Console.Write("\t"+resultant[i,j]);
}
Console.WriteLine();
}
return resultant;
}
}
I did this for you yesterday, I created a method that will return a square matrix, given a parent matrix and the length.
static void Main(string[] args)
{
int[][] parentMatrix = new int[][]
{
new int [] { 1, 2, 3 },
new int [] { 4, 5, 6 },
new int [] { 7, 8, 9 }
};
var chunks = GetSubMatrices(parentMatrix, 2);
Console.WriteLine(chunks);
}
static List<int[][]> GetSubMatrices(int[][] parentMatrix, int m)
{
int n = parentMatrix.Length > m ? parentMatrix.Length : throw new InvalidOperationException("You can't use a matrix smaller than the chunk size");
var chunks = new List<int[][]>();
int movLimit = n - m + 1;
var allCount = Math.Pow(movLimit, 2);
for (int selRow = 0; selRow < movLimit; selRow ++)
{
for (int selCol = 0; selCol < movLimit; selCol ++)
{
// this is start position of the chunk
var chunk = new int[m][];
for (int row = 0; row < m; row++)
{
chunk[row] = new int[m];
for (int col = 0; col < m; col++)
{
chunk[row][col] = parentMatrix[selRow + row][selCol + col];
}
}
chunks.Add(chunk);
}
}
return chunks;
}
If you have any problems using it, you can simply comment below.
I needed to solve a problem like and came up with this answer. Hope it adds to your library of answers. If the submatrix specified is not greater than 1, do nothing.
public static void GetSubMatrixes(int[,] arr, int size)
{
int parentMatrixRowLength = arr.GetLength(0);
int parentMatrixColLength = arr.GetLength(1);
var overall = new List<object>();
if(size > 1)
{
for (int i = 0; i < parentMatrixRowLength; i++)
{
//get the columns
for (int j = 0; j < parentMatrixColLength; j++)
{
var subMatrix = new int[size, size];
/*if the new matrix starts from second to the last value in either the row(horizontal or column)
* do not proceed, go to the row or column in the parent matrix
* */
if (j < parentMatrixColLength - (size - 1) && i < parentMatrixRowLength - (size - 1))
{
//add
for (int m = 0; m < subMatrix.GetLength(0); m++)
{
for (int n = 0; n < subMatrix.GetLength(1); n++)
{
/*check the sum of current column value and the sum of the current row value
* of the parent column length and row length if it goes out of bounds
*/
var row = i + m; var col = j + n;
//actual check here
if (row < parentMatrixRowLength && col < parentMatrixColLength)
{
subMatrix[m, n] = arr[i + m, j + n];
}
}
}
overall.Add(subMatrix);
}
}
}
//display the sub matrixes here
for (int i = 0; i < overall.Count; i++)
{
var matrix = overall[i] as int[,];
for (int y = 0; y < matrix.GetLength(0); y++)
{
for (int x = 0; x < matrix.GetLength(1); x++)
{
Console.Write(string.Format("{0} ", matrix[y, x]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
Console.WriteLine();
}
}
}

Data insertion loop does not work

Related to this question : I'm trying to write an "INSERT" loop : I have got the following query:
CommandText = "INSERT into sample2Prot(timestp,idq,idz,prot,Lhowmany,Rhowmany) VALUES(#timestp,#idq,#idz,#prot,#Lhowmany,#Rhowmany)";
When I execute my code (which can be found just below) I get the following error:
'#timestp' cannot be handle by SqlParameterCollection. ("timestp" = tableNames[0], of string type)
for (int j = 0; j < tableNames.Count; j++)
// tableNames contains the name of the columns, tableTypes the types of the columns
// tableTypes contains
{
if (tableTypes[j] == "INTEGER")
{
myCommand3.Parameters.Add("#" + tableNames[j], System.Data.SqlDbType.Int);
Console.WriteLine("#" + tableNames[j]);
}
else
{
myCommand3.Parameters.Add("#" + tableNames[j], System.Data.SqlDbType.VarChar);
Console.WriteLine("#" + tableNames[j]);
}
}
Console.WriteLine(myCommand3.CommandText);
for (int f = 0; f < total.Count(); f++)
{
for (int k = 0; k < tableNames.Count; k++)
{
myCommand3.Parameters.Clear();
myCommand3.Parameters["#" + tableNames[k]].Value = total[f][k];
}
myCommand3.ExecuteNonQuery();
}
Has someone an idea ? Don't mind asking for more precision.
for (int f = 0; f < total.Count(); f++)
{
for (int k = 0; k < tableNames.Count; k++)
{
myCommand3.Parameters.Clear(); // < ==== PROBLEM is here!
// After clearing the Parameters, there is no Parameter "["#" + tableNames[k]]"
// hence "SqlParameter mit ParameterName '#timestp' ist nicht in SqlParameterCollection enthalten."
// (eng: SqlParameterCollection does not contain SqlParameter with name '#timestp' )
myCommand3.Parameters["#" + tableNames[k]].Value = total[f][k];
}
myCommand3.ExecuteNonQuery();
}
In above code, move the Clear() statement like so:
for (int f = 0; f < total.Count(); f++)
{
for (int k = 0; k < tableNames.Count; k++)
{
myCommand3.Parameters["#" + tableNames[k]].Value = total[f][k];
}
myCommand3.ExecuteNonQuery();
}
myCommand3.Parameters.Clear();

How to find that one matrix is submatrix of the other in C#?

I want to find that a given matrix is a sub matrix of the other.
I have tried below piece of code but I am not sure that it would work:-
for (int i = 0; i < a.length - b.length + 1; i++) {
for (int j = 0; j < a[0].length - b[0].length + 1; j++) {
boolean submatrix = true; // at start we assume we have a submatrix
for (int k = 0; k < b.length; ++k) {
for (int l = 0; l < b[0].length; ++l) {
if (a[i + k][j + l] == b[k][l]) {
Console.WriteLine("a[" + (i + k) + "][" + (j + l) + "] = b[" + k + "][" + l + "]");
} else {
submatrix = false; // we found inequality, so it's not a submatrix
}
}
}
if (submatrix) {
Console.WriteLine("Found subatrix at " + i + "," + j + ".");
}
}
}
Please suggest??
Your suggested method is correct, there are only a few syntax and control flow issues which I've fixed.
It is important to point out that this method is only useful for detecting a submatrix of a 2D matrix, not any dimension matrix.
I assumed the datatype is a jagged array of int, though it can easily be changed.
private static bool IsSubMatrix(int[][] a, int[][] b)
{
for (int i = 0; i < a.Length - b.Length + 1; i++)
{
for (int j = 0; j < a[0].Length - b[0].Length + 1; j++)
{
bool found = true;
for (int k = 0; k < b.Length; ++k)
{
for (int l = 0; l < b[0].Length; ++l)
{
if (a[i + k][j + l] != b[k][l])
{
found = false;
break;
}
}
if (!found) break;
}
if (found) return true;
}
}
return false;
}
This is probably also not the fastest implementation.

Categories