- Home /
Can I use variables when using the MultiDim script?
I'm using the MultiDim helper script, and it's throwing a problem when I try to define a multidimensional array with sizes set by variables (not explicitly set in the editor - they will be determined by code):
EDIT - here's a script showing just the problem This gets rid of the whole nodes thing in the script I'd included earlier and just shows the MultiDim problem. This script sets random sizes for a 3 dimensional array, and then attempts to fill each entry in the array with the number 1. The console error shows that even accessing Index(0,0,0) proves out of range.
Here it is, all outside of any function. This produces an Array Index Out Of Range error:
var mazeWidth : int; var mazeHeight : int; var mazeDepth : int;
mazeWidth = Random.Range(5,10); // anything from 5 to 9 mazeHeight = Random.Range(5,10); // anything from 5 to 9 mazeDepth = Random.Range(5,10); // anything from 5 to 9
Debug.Log( mazeWidth.ToString() ); Debug.Log( mazeHeight.ToString() ); Debug.Log( mazeDepth.ToString() );
var mazeNode = MultiDim.IntArray(mazeWidth,mazeHeight,mazeDepth);
for (var a =0;a<mazeWidth;a++) { for (var b=0;b<mazeWidth;b++) { for (var c=0;c<mazeWidth;c++) { Debug.Log( "Filling "+a.ToString()+","+b.ToString()+","+c.ToString() ); mazeNode[a,b,c] = 1; } } }
And here it is with functional code inside the Awake function. This results in a "Field 'System.Int32[,,]' not found" error.
var mazeWidth : int; var mazeHeight : int; var mazeDepth : int;
var mazeNode;
function Awake() { mazeWidth = Random.Range(5,10); // anything from 5 to 9 mazeHeight = Random.Range(5,10); // anything from 5 to 9 mazeDepth = Random.Range(5,10); // anything from 5 to 9
Debug.Log( mazeWidth.ToString() );
Debug.Log( mazeHeight.ToString() );
Debug.Log( mazeDepth.ToString() );
mazeNode = MultiDim.IntArray(mazeWidth,mazeHeight,mazeDepth);
for (var a =0;a<mazeWidth;a++) {
for (var b=0;b<mazeWidth;b++) {
for (var c=0;c<mazeWidth;c++) {
Debug.Log( "Filling "+a.ToString()+","+b.ToString()+","+c.ToString() );
mazeNode[a,b,c] = 1;
}
}
}
}
I recall a pattern in these kind of mistakes. It is probably misinformation by the error logging. When I get reports which clearly show me something is impossible when it is, start looking for syntax errors. Just segment the problem into chunks with comment blocks. But before that always blame yourself before the computer :P It's usually correct
Answer by duck · Nov 16, 2010 at 01:21 PM
Yes you can do this, it's totally valid as written and it should not cause the symptoms you're describing - so I have to guess that your "index out of range" errors are caused by something else.
Are you sure that you're not forgetting that array indices are zero-based? I.E. for a dimension that has a size of "9", the range of valid indices is from 0-8 inclusive (and not 9!).
Perhaps you could paste a larger sample of the code you're using.
--EDIT--
So, looking at the new piece of sample code you pasted in a comment:
xSize = node.transform.position.x;
ySize = node.transform.position.y;
zSize = node.transform.position.z;
var mazeNode = MultiDim.IntArray(xSize,ySize,zSize);
In the above code, you're using float values (the object position values) as input to a function which accepts integers, so these are going to get rounded. Perhaps this is your problem.
You really need to trace out the exact values that are being used to track this problem down, so perhaps you should do something like this, and look in the console at which values are really being used for the size and index numbers.
var xSize : int = node.transform.position.x; var ySize : int = node.transform.position.y; var zSize : int = node.transform.position.z; print("defining array of size "+xSize+" x "+ySize+" x "+zSize); var mazeNode = MultiDim.IntArray(xSize,ySize,zSize);
var xPos : int = someOtherPosition.x; var yPos : int = someOtherPosition.y; var zPos : int = someOtherPosition.z; print("inserting value at "+xPos+", "+yPos+", "+zPos); mazeNode[xPos,yPos,zPos] = someValue;
Tracing all this out to the console should help you narrow this down to the cause.
-- EDIT 2!--
Having tried out the sample code you pasted, it seems to run fine. However there are potential problems with it - the main one being the way you determine the array size. If any of your objects have a negative x, y or z value, they will mess up your maze size (since it seems your code assumes they will all have positive values - your code only checks for the max values and not the minimum).
What you should do is capture both the minimum and maximum values, and calculate the maze dimension sizes using the difference between the minimum and maximum. Eg, if your nodes x positions range from -12 to 14, your maze x dimension size would need to be 26 (whereas your current code would set it as 14!).
Hope this helps pinpoint the problem!
-- EDIT 3! --
Okay, this looks like the problem - there are two errors. First:
"Field 'System.Int32[,,]' not found" error.
This is occurring because you're declaring the var outside the function, but you're not specifying a type. This results in the variable becoming a special "dynamically typed" variable, and as such needs to be handled in special ways that I'm not entirely familiar with (because I mainly use C#!). To solve this, you can give the variable a specific type of a 3D int array by assigning a dummy value to it when defining it outside a function, like so:
var mazeNode = MultiDim.IntArray(1,1,1);
You can then assign the real size later. The important thing is that because you gave it a value when assigning it, it has a static type.
Secondly (and you'll kick yourself here), you are using "mazeWidth" as the limit in your for loops for each of the a, b, and c dimensions, instead of using mazeWidth, mazeHeight, mazeDepth! So the fixed code in its entirety would look like this:
var mazeWidth : int; var mazeHeight : int; var mazeDepth : int;
var mazeNode = MultiDim.IntArray(1,1,1);
function Awake() {
mazeWidth = Random.Range(5,10); // anything from 5 to 9
mazeHeight = Random.Range(5,10); // anything from 5 to 9
mazeDepth = Random.Range(5,10); // anything from 5 to 9
Debug.Log( mazeWidth.ToString() );
Debug.Log( mazeHeight.ToString() );
Debug.Log( mazeDepth.ToString() );
mazeNode = MultiDim.IntArray(mazeWidth,mazeHeight,mazeDepth);
for (var a =0;a<mazeWidth;a++) {
for (var b=0;b<mazeHeight;b++) {
for (var c=0;c<mazeDepth;c++) {
Debug.Log( "Filling "+a.ToString()+","+b.ToString()+","+c.ToString() );
mazeNode[a,b,c] = 1;
}
}
}
}
As stated in other comment, I actually oversimplified for the purpose of posting - the variables won't be declared as numbers but will be calculated (from the positions of objects within my scene). In a nutshell I have a matrix of 'node' objects, and I have an opening function which calculates the width, depth and height of a bounding box which will contain all the nodes. Then I want to declare the multidim array.
Unfortunately it's still not working... I tried one other thing, which was to separate the declaration from the assignment. So: var mazeNode; mazeNode = $$anonymous$$ultiDim.IntArray(sizex, sizey, sizez); But it still said array index out of range. I tried: var mazeNode : int; but it gave me the error "Int does not support slicing" I tried: var mazeNode : int[]; but it gave the error "mazeNode is rank 1 not rank 3" I tried: var mazeNode : int[,,]; but it gave a basic syntax error. I'm starting to think I may have to create this entire script in C#...
maybe you should paste your entire script, rather than snippets of it - otherwise we can only guess at what the problem might be, which is unlikely to be accurate.
I've edited the original question to include the entire script - thanks for giving me your time on this, I really appreciate it.
Answer by Mike 3 · Nov 16, 2010 at 01:22 PM
Make sure than xSize, ySize and zSize in the inspector are the same values as in the script, it could be that they're lower there if you've changed the script values at any point
Perhaps I should clarify further as I was simplifying for the question... The variables are actually deter$$anonymous$$ed by code at Awake(), based on the positions of node objects I will place in each scene - so they are never explicitly set at arbitrary numbers. Sorry for confusing things!
Something like this: xSize = node.transform.position.x; ySize = node.transform.position.y; zSize = node.transform.position.z; var mazeNode = $$anonymous$$ultiDim.IntArray(xSize,ySize,zSize);
I edited my answer to add more information based on your comment above.