Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Whats wrong with this code?

Discussion in 'Scripting' started by keenanwoodall, Aug 1, 2014.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    the error is on the line where I round the point inside the byte array
    Code (js):
    1.  
    2.     //Inspector Variables-----------------------------------------------------
    3. var terrain : GameObject;//This will refer to the object with the 2DGeneratorScript. In the start function we'll get the script and apply it to the tScript variable
    4. var target : GameObject;
    5.     //Hidden Variables--------------------------------------------------------
    6. private var tScript;
    7. private var layerMask : LayerMask = (1 << 0);
    8.  
    9. function Start ()
    10. {
    11.     tScript = terrain.gameObject.GetComponent("2DGeneratorScript");
    12. }
    13.  
    14. function Update ()
    15. {
    16.     //The next 10 line create a ray between this objects position and your target objects possition. If you drag the target around in the Editor, you'll see the ray follow it
    17.     //If you drag the target so that the ray hits something, It'll turn green; telling you that the ray is hitting something
    18.     var hit : RaycastHit;
    19.     var distance : float = Vector3.Distance(this.transform.position, target.transform.position);
    20.     if(Physics.Raycast(this.transform.position, (target.transform.position - this.transform.position).normalized, hit, distance, layerMask))
    21.     {
    22.         Debug.DrawLine(this.transform.position, hit.point, Color.green);
    23.         //The next section of code is important. It finds the position that we hit and stores it in a variable--
    24.         var point : Vector2 = new Vector2(hit.point.x, hit.point.y);
    25.         //Then it adds the normal, which is the direction that points directly away from the poly(that the ray hit). That will move the vectors position one unit away from the poly
    26.         //That's not we want though. We are trying to find what square it hit. So we can't move out point farther away. At the end of the line you see we multiply it by -0.5
    27.         //That(negative)will reverse the variables position, so now it's on the opposite side of the square. Because we're multiplying it by -0.5 and not 1--
    28.         //the var, point's, position will be moved to the center of the object. Allowing us to round to the nearest position and get the block that we hit
    29.         point += (new Vector2(hit.normal.x, hit.normal.y)) * -0.5;
    30.         //Here we access the 2dGenerationScript, find the square we hit, and make it 0 (which is air)
    31.         tScript.blocks[(Mathf.RoundToInt(point.x -0.5)), (Mathf.RoundToInt(point.y + 0.5))] = 0;
    32.         tScript.update = true;
    33.     }
    34.     else
    35.     {
    36.         Debug.DrawLine(this.transform.position, target.transform.position, Color.red);
    37.     }
    38. }
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    We don't know where that is, and we're not gonna dig through your code to find out. Give us a line number. Also, give us the actual error message - they really do have meaning.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    I'm also guessing we will probably need to see the tScript script, too.
     
  4. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    your probably right, my bad
    Code (js):
    1.  
    2. import System.Collections.Generic;
    3.  
    4. @script AddComponentMenu ("Cool Tools/Random Generation/2D Generator")
    5. @script RequireComponent(MeshFilter)
    6. @script RequireComponent(MeshRenderer)
    7. @script RequireComponent(MeshCollider)
    8.     //Inspector Variables-----------------------------------------------------
    9. //The two variables below let us change how many blocks are created by feeding their values into the byte array
    10. var xAmount : int = 96;
    11. var yAmount : int = 128;
    12. //These two variables will increase the caves size
    13. var caveX_Size : int = 1;
    14. var caveY_Size : int = 2;
    15.  
    16. //This is the variable that will tell the mesh when to update. It will be set true from the PolyDestroyerScript when a square needs to be deleted
    17. var update : boolean;
    18.  
    19. //This is going to store all of the vertices of the mesh we are going to render
    20. var newVertices : List.<Vector3> = new List.<Vector3>();
    21. var colVertices : List.<Vector3> = new List.<Vector3>();
    22.  
    23. //The triangles tell Unity how to build the each part of the mesh that connects vertices
    24. var newTriangles : List.<int> = new List.<int>();
    25. var colTriangles : List.<int> = new List.<int>();
    26.  
    27. //The UV list tells Unity how to display/position the texture on each polygon
    28. var newUV : List.<Vector2> = new List.<Vector2>();
    29.  
    30. //Here we will store all of the different block types/information. For example, 0 could be air, 1 grass, and 2 rock
    31. var blocks : byte[,];
    32.  
    33.     //Hidden Variables--------------------------------------------------------
    34. //The mesh will be made up the vertices, polys, and UVs that we define. After we make them, we'll apply them to this mesh
    35. private var mesh : Mesh;
    36. private var col : MeshCollider;
    37.  
    38. //The texture applied to this objects mesh has different colored tiles to represent things like grass, dirt, rock etc.
    39. //Here we define a float that will be changed in the Start function
    40. //The float will represent the percentage of the textures width that one tile takes up. We will call that percentage a texUnit
    41. private var texUnit : float = 0.25;    //The texture has 16 tiles, 4 wide, 4 tall. One tile is a fourth, or takes up 0.25 or the width
    42. private var texStone : Vector2 = new Vector2(1, 0);    //Here we are defining the texture coordinates for the stone tile portion of the texture
    43. private var texGrass : Vector2 = new Vector2(0, 1);    //Here we are defining the texture coordinates for the grass tile portion of the texture
    44.  
    45. //This variable is important. It lets us know how many squares we have created so that
    46. //For instance, when we need to access the meshes 1046 vertice we can do so easily by knowing which square we're on and adding the ints to the triangles
    47. private var squareCount : int;
    48. private var colCount : int;
    49.  
    50. function Start ()
    51. {
    52.     mesh = GetComponent(MeshFilter).mesh;
    53.     col = GetComponent(MeshCollider);
    54.  
    55.     GenTerrain();
    56.     BuildMesh();
    57.     UpdateMesh();
    58. }
    59.  
    60. function Update ()
    61. {
    62.     if(update)
    63.     {
    64.         BuildMesh();
    65.         UpdateMesh();
    66.         update = false;
    67.     }
    68. }
    69.  
    70. //This function will generate a random whole number depending on each square's position and sets its height based on that
    71. function Noise (x : int, y : int, scale : float, mag : float, exp : float) : int
    72. {  
    73.     //We are getting the squares x and y coords and plugging it into Mathf.PerlinNoise to get a smooth height transition between squares
    74.     //Then we divide by scale to determine how big or small we want the terrain/noise to be. The larger the scale value, the smoother the terrain
    75.     //Next we multiply the value by "mag". Perlin Noise generates a value between 0 and 1. We want hills to be higher to we multiply that output by mag
    76.     //Lastly we put the value to the power of the xponent, or "exp". This will give us exponential growth which is good for mountains and steep valleys
    77.     return Mathf.Pow((Mathf.PerlinNoise(x / scale, y / scale) * mag), (exp));
    78.     //This function outputs an integer, whole number, which is how we will get a Terraria/Minecraft feel
    79. }
    80.  
    81. function GenTerrain ()
    82. {
    83.     //This makes a sets the array of blocks' size to 10x10. The actual blocks will be built in a seperate function
    84.     blocks = new byte[xAmount, yAmount];
    85.     for(var px : int = 0; px < blocks.GetLength(0); px++)//px will stand for the blocks that need to be generated on the x-axis
    86.     {
    87.         //We are layering the noise 3 times to get more textured values in the stone
    88.         var stone : int = Noise(px, 0, 80, 15, 1);//Layer 1 has a scale of 80, making the base terrain. It forms shallow, smooth hills that are max 15 units high
    89.         stone += Noise(px, 0, 50, 30, 1);//Layer 2 has a smaller scale so its less smooth(Not choppy yet). It has a larger magnitude so it creates the higher hills
    90.         stone += Noise(px, 0, 10, 10, 1);//Layer 3 has the choppiest noise, but it has a small height. It ends up adding bumps and stones for a more natural terrain
    91.         stone += 75;//With out adding 75, we would have one smooth line of stone, we add 75 raise the rock
    92.         //We are layering the noise 3 times to get more textured values in the dirt
    93.         var dirt : int = Noise(px, 0, 100, 35, 1);//The dirt is usually higher than the stone, although sometimes rocks come out. That's why we give the first layer a high mag
    94.         dirt += Noise(px, 0, 50, 30, 1);//The 2nd Layer of dirt is the same as the rocks 2nd Layer. It's just set higher
    95.         dirt += 75;//Now we add 75 to give the dirt depth
    96.         for(var py : int = 0; py < blocks.GetLength(1); py++)//py will stand for the blocks that need to be generated on the y-axis
    97.         {
    98.             if(py < stone)//If the squares position is less than where the stones start--
    99.             {
    100.                 blocks[px, py] = 1;//--We set the square to stone
    101.                 //This if-statement makes dirt squares in random places
    102.                 if(Noise(px, py, 12, 16, 1) > 10)//Here is a new noise layer that has a very frequent noise. If the value the noise returns is over 10, we'll make the square dirt
    103.                 {
    104.                     blocks[px, py] = 2;//Here we set the square to dirt (0 is air, 1 is stone, 2 is dirt)
    105.                 }
    106.                 //This if-statement removes dirt and rock to make caves in random places
    107.                 //We multiply py by 2(caveX_Size) to stretch out the caves so they are more wide than tall. Change the value in the Inspector to see what it does
    108.                 //We use a larger scale to make the caves larger and less frequent
    109.                 if(Noise(px * caveY_Size, py * caveX_Size, 16, 14, 1) > 10)
    110.                 {
    111.                     blocks[px, py] = 0;//Set the blocks to 0, which is an air block
    112.                 }
    113.             }
    114.             else if (py < dirt)
    115.             {
    116.                 blocks[px, py] = 2;
    117.             }
    118.         }
    119.     }
    120. }
    121.  
    122. function BuildMesh ()
    123. {
    124.     for (var px : int = 0; px < blocks.GetLength(0); px++)
    125.     {
    126.         for (var py : int = 0; py < blocks.GetLength(1); py++)
    127.         {
    128.             //If the block isn't air--
    129.             if(blocks[px, py] != 0)
    130.             {
    131.                 //--We call the GenCollider function to generate a collider for each square at the right place
    132.                 GenCollider(px, py);
    133.                 if(blocks[px, py] == 1)
    134.                 {
    135.                       GenSquare(px, py, texStone);
    136.                 }
    137.                 else if(blocks[px, py] == 2)
    138.                 {
    139.                     GenSquare(px, py, texGrass);
    140.                 }
    141.             }
    142.         }
    143.     }
    144. }
    145.  
    146. function Block (x : int, y : int) : byte
    147. {
    148.     if(x == -1 || x == blocks.GetLength(0) || y == -1 || y == blocks.GetLength(1))
    149.     {
    150.         return 1;
    151.     }
    152.     return blocks[x, y];
    153. }
    154.  
    155. //This is the function where we generate the necessary colliders for each block when we update the mesh
    156. function GenCollider (x : int, y : int)
    157. {
    158.     //Top Face
    159.     if(Block(x, y + 1) == 0)
    160.     {
    161.         //The next 13 lines are the doing the same things that the GenSquare function does, but we are'nt making this square on the xy plane
    162.         //This square is the top sqaure of our shape. As you can see it has a value of 1 on the first two vertices in the z axis. This gives the shape depth
    163.         colVertices.Add(new Vector3(x, y, 1));//Back-left vertice
    164.         colVertices.Add(new Vector3(x + 1, y, 1));//Back-right vertice
    165.         colVertices.Add(new Vector3(x + 1, y, 0));//Front-right vertice
    166.         colVertices.Add(new Vector3(x, y, 0));//Front-left vertice
    167.         ColliderTriangles ();//Instead of typing out colTriangles.Add(blahblah) over and over for every face, we can put that code into a function and call it for every face
    168.         colCount++;
    169.     }
    170.     //Bottom Face
    171.     if(Block(x, y - 1) == 0)
    172.     {
    173.         colVertices.Add(new Vector3(x, y - 1, 0));
    174.         colVertices.Add(new Vector3(x + 1, y - 1, 0));
    175.         colVertices.Add(new Vector3(x + 1, y - 1, 1));
    176.         colVertices.Add(new Vector3(x, y - 1, 1));
    177.         ColliderTriangles();
    178.         colCount++;
    179.     }
    180.     //Left Face
    181.     if(Block(x - 1, y) == 0)
    182.     {
    183.         colVertices.Add(new Vector3(x, y - 1, 1));
    184.         colVertices.Add(new Vector3(x, y, 1));
    185.         colVertices.Add(new Vector3(x, y, 0));
    186.         colVertices.Add(new Vector3(x, y - 1, 0));
    187.         ColliderTriangles();
    188.         colCount++;
    189.     }
    190.     //Right Face
    191.     if(Block(x + 1, y) == 0)
    192.     {
    193.         colVertices.Add(new Vector3(x + 1, y, 1));
    194.         colVertices.Add(new Vector3(x + 1, y - 1, 1));
    195.         colVertices.Add(new Vector3(x + 1, y - 1, 0));
    196.         colVertices.Add(new Vector3(x + 1, y, 0));
    197.         ColliderTriangles();
    198.         colCount++;
    199.     }
    200. }
    201.  
    202. function ColliderTriangles ()
    203. {
    204.     colTriangles.Add(colCount * 4);
    205.     colTriangles.Add((colCount * 4) + 1);
    206.     colTriangles.Add((colCount * 4) + 3);
    207.     colTriangles.Add((colCount * 4) + 1);
    208.     colTriangles.Add((colCount * 4) + 2);
    209.     colTriangles.Add((colCount * 4) + 3);
    210. }
    211.  
    212. function GenSquare (x : int, y : int, texture : Vector2)
    213. {
    214.     //This will create a simple square on the xy plane.
    215.     newVertices.Add(new Vector3(x, y, 0));//This creates a vertice at the objects origin; the top-left
    216.     newVertices.Add(new Vector3(x + 1, y, 0));//This creates a vertice on the top-right (i.e. +1 on the x axis which is left to right)
    217.     newVertices.Add(new Vector3(x + 1, y - 1, 0));//This creates the bottom-right vertice
    218.     newVertices.Add(new Vector3(x, y - 1, 0));//This creates the last vertice on the bottom-left
    219.  
    220.     //Here we are connecting the vertices and making polygons, everything we are doing below is multiplied by square count so that a new square is made
    221.     //The polygons must be triangles (tris). Tris are made by adding the vertices that make it up counter-clockwise
    222.         //First 3 make up the triangle. They go: top-left to top-right to bottom-right. 3 points, decared in counter-clockwise order
    223.     newTriangles.Add(squareCount * 4);
    224.     newTriangles.Add((squareCount * 4) + 1);
    225.     newTriangles.Add((squareCount * 4) + 3);
    226.         //Second 3 up the bottom triangle. They go: top-right to bottom-right to bottom-left. 3 points, decared in counter-clockwise order
    227.     newTriangles.Add((squareCount * 4) + 1);
    228.     newTriangles.Add((squareCount * 4) + 2);
    229.     newTriangles.Add((squareCount * 4)  + 3);
    230.  
    231.     newUV.Add(new Vector2(texUnit * texture.x, texUnit * texture.y + texUnit));
    232.     newUV.Add(new Vector2(texUnit * texture.x + texUnit, texUnit * texture.y + texUnit));
    233.     newUV.Add(new Vector2(texUnit * texture.x + texUnit, texUnit * texture.y));
    234.     newUV.Add(new Vector2(texUnit * texture.x, texUnit * texture.y));
    235.  
    236.     //Everytime the above sode is completed, we have succesfully created a new square, and there for need to raise the square count by one
    237.     squareCount++;
    238. }
    239.  
    240. function UpdateMesh ()
    241. {
    242.     //Now we clear whatever mesh the MeshFilter is holding, to replace it with our own
    243.     mesh.Clear();
    244.     //For Unity to use or vertices(verts), and polygons/triangles(polys/tris), we have to convert the Lists that they are stored in to Arrays
    245.     //The reason is that Unity can't directly use them is unknown to me :) Arrays and Lists are similar so don't worry about it
    246.     mesh.vertices = newVertices.ToArray();
    247.     mesh.triangles = newTriangles.ToArray();
    248.     mesh.uv = newUV.ToArray();
    249.     //Now we call Optimize which probably won't do anything here, but it doesn't use up any processing so its good to throw in
    250.     mesh.Optimize();
    251.     //Using the RecalculateNormals command is basically going to make sure the normals are generated automatically. Thanks unity!
    252.     mesh.RecalculateNormals();
    253.     newVertices.Clear();
    254.     newTriangles.Clear();
    255.     newUV.Clear();
    256.     //Now we clear all the data so that the next time we make the mesh the count starts at 0 and so that we don't add on top of existing data
    257.     squareCount = 0;
    258.  
    259.     //Here we are creating a temporary mesh that we can make a collider out of. This is done very similarly to the way we create the visible mesh
    260.     var newMesh : Mesh = new Mesh();
    261.     newMesh.vertices = colVertices.ToArray();
    262.     newMesh.triangles = colTriangles.ToArray();
    263.     col.sharedMesh = newMesh;
    264.     colVertices.Clear();
    265.     colTriangles.Clear();
    266.     colCount = 0;
    267. }
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    And the error message?
     
  6. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    MissingFieldException: System.Byte[,].
    Boo.Lang.Runtime.DynamicDispatching.SliceDispatcherFactory.ResolveMember ()
    Boo.Lang.Runtime.DynamicDispatching.SliceDispatcherFactory.CreateSetter ()
    Boo.Lang.Runtime.RuntimeServices.CreateSetSliceDispatcher (System.Object target, System.String name, System.Object[] args)
    Boo.Lang.Runtime.RuntimeServices+<SetSlice>c__AnonStorey1E.<>m__15 ()
    Boo.Lang.Runtime.DynamicDispatching.DispatcherCache.Get (Boo.Lang.Runtime.DynamicDispatching.DispatcherKey key, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
    Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.String cacheKeyName, System.Type[] cacheKeyTypes, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
    Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.Object[] args, System.String cacheKeyName, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
    Boo.Lang.Runtime.RuntimeServices.SetSlice (System.Object target, System.String name, System.Object[] args)
    Boo.Lang.Runtime.DynamicDispatching.SliceDispatcherFactory+<CreateSetter>c__AnonStorey13.<>m__6 (System.Object o, System.Object[] arguments)
    Boo.Lang.Runtime.RuntimeServices.SetSlice (System.Object target, System.String name, System.Object[] args)
    PolyDestroyer.Update () (at Assets/Resources/KeenansCoolResources/KeenansCoolScripts/VoxelGeneration/PolyDestroyer.js:31)
     
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    Have you confirmed that tScript is not null, and that the byte array has been initialized when you make that call?
     
  8. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    I have the polygon generatorScript on the object that is applied to the terrain variable in the inspector, and I've made another object called target that's applied to the target variable. Idk about the byte being initialized, I barely understand them right now