Function using seemingly impossible, unset values
So, if you notice, near the bottom in the "BuildWorld()" function, I build the world (draw cubes on screen) based on what the int[,,] world_data is. However, nowhere else in the code do I set "world_data", other than setting it to 0 across the board. There is also an int[,,] called copyOfWorldData, which is set locally to be equal to world_data. I do this as a way of altering copyOfWorldData without actually changing world_data. Toward the bottom of the Tick() function, I set the value of copyOfWorldData. If I don't set that, there's no problem. However if I do set it, when building the world, the function seemingly uses copyOfWorldData instead of world_data. Note I never set world_data to copyOfWorldData, so it should always be 0 (Or whatever little configuration the player has built) and should never change unless the scene is reloaded or the Awake function is called. Here's my code:
using UnityEngine; using System.Collections;
public class world_main : MonoBehaviour {
int world_size = 32;
int[,,] world_data;
int[,,] copyOfWorldData;
public Texture2D unitTexture;
float tickSpeed = 1f;
public GameObject unit;
bool simulation_paused = false;
public Transform world;
void Tick () {
if ( simulation_paused == false ) {
copyOfWorldData = world_data;
for (int x = 0; x < world_size; x++) {
for (int y = 0; y < world_size; y++) {
for (int z = 0; z < world_size; z++) {
//for (int i = 0; i < 26; i++) {
if ( x < world_size-1 && y < world_size-1 && z < world_size-1 && x > 1 && y > 1 && z > 1 ) {
int neighbors = 0;
//top (blender coordinates)
if ( world_data[x-1, y-1, z+1 ] == 1 ) neighbors ++;
if ( world_data[x-1, y, z+1 ] == 1 ) neighbors ++;
if ( world_data[x-1, y+1, z+1 ] == 1 ) neighbors ++;
if ( world_data[x, y-1, z+1 ] == 1 ) neighbors ++;
if ( world_data[x, y, z+1 ] == 1 ) neighbors ++;
if ( world_data[x, y+1, z+1 ] == 1 ) neighbors ++;
if ( world_data[x+1, y-1, z+1 ] == 1 ) neighbors ++;
if ( world_data[x+1, y, z+1 ] == 1 ) neighbors ++;
if ( world_data[x+1, y+1, z+1 ] == 1 ) neighbors ++;
//bottom (blender coordinates)
if ( world_data[x-1, y-1, z-1 ] == 1 ) neighbors ++;
if ( world_data[x-1, y, z-1 ] == 1 ) neighbors ++;
if ( world_data[x-1, y+1, z-1 ] == 1 ) neighbors ++;
if ( world_data[x, y-1, z-1 ] == 1 ) neighbors ++;
if ( world_data[x, y, z-1 ] == 1 ) neighbors ++;
if ( world_data[x, y+1, z-1 ] == 1 ) neighbors ++;
if ( world_data[x+1, y-1, z-1 ] == 1 ) neighbors ++;
if ( world_data[x+1, y, z-1 ] == 1 ) neighbors ++;
if ( world_data[x+1, y+1, z-1 ] == 1 ) neighbors ++;
//middle ring (blender coordinates)
if ( world_data[x-1, y-1, z ] == 1 ) neighbors ++;
if ( world_data[x-1, y, z ] == 1 ) neighbors ++;
if ( world_data[x-1, y+1, z ] == 1 ) neighbors ++;
if ( world_data[x, y-1, z ] == 1 ) neighbors ++;
if ( world_data[x, y+1, z ] == 1 ) neighbors ++;
if ( world_data[x+1, y-1, z ] == 1 ) neighbors ++;
if ( world_data[x+1, y, z ] == 1 ) neighbors ++;
if ( world_data[x+1, y+1, z ] == 1 ) neighbors ++;
if ( world_data[x,y,z] == 1 ) {
copyOfWorldData[x,y,z] = 0;
}
else if ( world_data[x,y,z] == 0 ) {
if ( neighbors == 1 || neighbors == 7 ) {
copyOfWorldData[x,y,z] = 1;
}
}
neighbors = 0;
}
}
//}
}
}
BuildWorld();
TickEnd();
}
}
void TickEnd () {
Invoke ( "Tick", tickSpeed );
}
void StartSimulation () {
PauseSimulation(false);
copyOfWorldData = new int[world_size,world_size,world_size];
Tick();
}
void Update () {
if ( Input.GetKeyDown ( KeyCode.Y ) ) {
StartSimulation();
return;
}
if ( Input.GetKeyDown ( KeyCode.U ) ) {
PauseSimulation(true);
return;
}
if ( Input.GetKeyDown ( KeyCode.I ) ) {
PauseSimulation ( true );
Awake();
return;
}
}
void PauseSimulation ( bool state ) {
simulation_paused = state;
}
void Awake () {
world_data = new int[world_size,world_size,world_size];
BuildWorld();
}
void Main () {
Camera.main.transform.root.position = new Vector3 ( world_size/2, world_size/2, world_size/2 - 5 );
}
public void AddUnit (Vector3 pos) {
if ( pos.x < world_size && pos.y < world_size && pos.z < world_size && pos.x > 0 && pos.y > 0 && pos.z > 0 ) {
world_data[(int)pos.x,(int)pos.y,(int)pos.z] = 1;
BuildWorld();
return;
}
}
public void RemoveUnit (Vector3 pos ) {
if ( pos.x < world_size && pos.y < world_size && pos.z < world_size && pos.x > 0 && pos.y > 0 && pos.z > 0) {
world_data[(int)pos.x,(int)pos.y,(int)pos.z] = 0;
BuildWorld();
return;
}
}
void BuildWorld () {
foreach ( Transform t in world.transform ) {
Destroy ( t.gameObject );
}
for (int x = 1; x < world_size-1; x++) {
for (int y = 1; y < world_size-1; y++) {
for (int z = 1; z < world_size-1; z++) {
if ( world_data[x,y,z] == 1 ) {
GameObject g = (GameObject)Instantiate(unit);
g.transform.parent = world;
g.transform.position = new Vector3 ( x, y, z );
}
}
}
}
}
}
Answer by HawkSandwich · Aug 23, 2016 at 02:56 AM
Also keep in mind that the problem doesn't lie in all the "neighbors ++" section. Even if I ignore all that and set copyOfWorldData to be a random value, each tick builds the world based on copyOfWorldData, and not world_data instead. At least this appears to be the case, as I never set world_data to copyOfWorldData.
This is not a good answer. Please post comments as comments and answers as answers.
Answer by NoseKills · Aug 23, 2016 at 06:58 AM
copyOfWorldData = world_data;
is pretty much the first thing you do in Tick(). You assign the copyOfWorldData
variable to point to the same memory address as world_data
. After this, no variable is pointing to the array that existed in copyOfWorldData before, and it will shortly get garbage collected since there's no way to reference it anymore. After this assignment you have two variables that point to the same set of data.
If you want to have 2 arrays with the same set of data, you must use e.g. Array.Copy(). This will work without extra headaches since the items in the array are value types (so the ints in the other array have no connection to the ints int the first array.
Bear in mind if you'd do the same with arrays of for example GameObjects, you'll get 2 arrays with the same GameObjects in them since it's just a pure c# method that assigns the old values into the other array (doesn't instantiate copies of them etc.)
Your answer
Follow this Question
Related Questions
Microphone Input to Spawn object 2 Answers
enable/disbale particle system in 5.3.2 1 Answer
Attaching fbx to Scene on Android 0 Answers
Try part of C# not being Read 1 Answer
enemy following issue 0 Answers