Hey guys. Brand new to the forum, started working on programming a few months back and I’m following along with a YT series on recreating Minecraft, as the Chunk system has always been appealing to me and I would like to make a small scale “Minecraft Clone” as my first real practice for making a game.
So here’s my issue, I’m following along with the tutorial, and I’ve gotten to this part where I can’t seem to resolve my error;
public Mesh CreateMeshFromData(int[,] Data)
{
List Vertices = new List();
List Indices = new List();
Mesh m = new Mesh();
My error lies in the first line of this segment of code, it’s saying that 'public; is not a valid modifier for this term.
I’ve searched the forums for a while and I’ve seen similar issues, but all the solutions are very problem specific and I can’t seem to get it to work. I’ve tried changing it to a private class, and i get the same error. I tried removing it all together and it doesn’t work either.
I’m not sure if I’ve just made some super obvious typo somewhere, but I can’t seem to figure it out.
That line of code is fine. C#'s compiler has a tendency to become confused and incorrectly identify an error on a line that is perfectly fine. Check the code above it.
We need context. The modifier public is only allowed either on type declaration (outside of anything or inside a namespace or class) or on member declaration inside a type declaration. Since you get this error you may have put your method inside another method or something like that. We don’t know what you did because that context is missing from the partial code snippet you posted.
So essentially, the way I interpret what you said is, I could have an error that is actually all the way up on line, say, 3 or 4, but the compiler could show the error as being on line 38 or 70?
Could you please edit your post and put your code in actual code tags?
Your code is already completely broken, so please copy it again from your original source. The code button opens a new popup where you should insert your code.
Totally apologize, I was a bit drunk when i made the post and I just didn’t feel like fixing it. I also was unaware of the sticky post, I really should look around more.
I deleted my broken code comment and heres the fixed version;
Forgot to add my errors
line 5 “{ expected”
Line 17 “Top level statements must preceed namespace and type declarations”
UPDATE: 12pm May 16 / '24
I’m also getting a huge group of errors for all of my “ReadOnly” and “Static” modifiers, the errors are saying they are not valid modifiers.
Also at the end of my code, the final line I am getting:
“Type of namespace definition, or end of file expected”
I’m really getting confused because at this point, it SEEMS as though my code is fine, but clearly I am missing something.
public class ChunkMeshCreator
{ public Class FaceData
{
public FaceData(Vector3[] verts, int[] tris)
{
Vertices = verts;
Indices = tris;
}
public Vector3[] Vertices;
public int[] Indices;
};
#region FaceData
static readonly Vector3Int[] CheckDirections = new Vector3Int[]
{
Vector3Int.right,
Vector3Int.left,
Vector3Int.up,
Vector3Int.down,
Vector3Int.forward,
Vector3Int.back
};
static readonly Vector3[] RightFace = new Vector3[]
{
new Vector3(.5f, -.5f, -.5f),
new Vector3(.5f, -.5f, .5f),
new Vector3(.5f, .5f, .5f),
new Vector3(.5f, .5f, -.5f)
};
static readonly int[] RightTris = new int[]
{
0,2,1,0,3,2
};
static readonly Vector3[] LeftFace = new Vector3[]
{
new Vector3(-.5f, -.5f, -.5f),
new Vector3(-.5f, -.5f, .5f),
new Vector3(-.5f, .5f, .5f),
new Vector3(-.5f, .5f, -.5f)
};
static readonly int[] LeftTris = new int[]
{
0,1,2,0,2,3
};
static readonly Vector3[] UpFace = new Vector3[]
{
new Vector3(-.5f, .5f, -.5f),
new Vector3(-.5f, .5f, .5f),
new Vector3(.5f, .5f, .5f),
new Vector3(.5f, .5f, -.5f)
};
static readonly int[] UpTris = new int[]
{
0,1,2,0,2,3
};
static readonly Vector3[] DownFace = new Vector3[]
{
new Vector3(-.5f, -.5f, -.5f),
new Vector3(-.5f, -.5f, .5f),
new Vector3(.5f, -.5f, .5f),
new Vector3(.5f, -.5f, -.5f)
};
static readonly int[] DownTris = new int[]
{
0,2,1,0,3,2
};
static readonly Vector3[] ForwardFace = new Vector3[]
{
new Vector3(-.5f, -.5f, .5f),
new Vector3(-.5f, .5f, .5f),
new Vector3(.5f, .5f, .5f),
new Vector3(.5f, -.5f, .5f)
};
static readonly int[] ForwardTris = new int[]
{
0,2,1,0,3,2
};
static readonly Vector3[] BackFace = new Vector3[]
{
new Vector3(-.5f, -.5f, -.5f),
new Vector3(-.5f, .5f, -.5f),
new Vector3(.5f, .5f, -.5f),
new Vector3(.5f, -.5f, -.5f)
};
static readonly int[] BackTris = new int[]
{
0,1,2,0,2,3
};
#endregion
private Dictionary<Vector3Int, FaceData> CubeFaces = new Dictionary<Vector3Int, FaceData>();
public ChunkMeshCreator()
{
CubeFaces = new Dictionary<Vector3Int, FaceData>();
for(int i = 0; i < CheckDirections.Length; i++)
{
if(CheckDirections[i] == Vector3Int.up) {
CubeFaces.Add(CheckDirections[i], new FaceData(UpFace, UpTris));
} else if (CheckDirections[i] == Vector3Int.down) {
CubeFaces.Add(CheckDirections[i], new FaceData(DownFace, DownTris));
} else if (CheckDirections[i] == Vector3Int.forward) {
CubeFaces.Add(CheckDirections[i], new FaceData(ForwardFace, ForwardTris));
} else if (CheckDirections[i] == Vector3Int.back) {
CubeFaces.Add(CheckDirections[i], new FaceData(BackFace, BackTris));
} else if (CheckDirections[i] == Vector3Int.left) {
CubeFaces.Add(CheckDirections[i], new FaceData(LeftFace, LeftTris));
} else if (CheckDirections[i] == Vector3Int.right) {
CubeFaces.Add(CheckDirections[i], new FaceData(RightFace, RightTris));
}
}
}
public Mesh CreateMeshFromData(int[,,] Data)
{
List<Vector3> Vertices = new List<Vector3>();
List<int> Indices = new List<int>();
Mesh m = new Mesh();
for(int x = 0; x < WorldGenerator.ChunkSize.x; x++)
{
for(int y = 0; y < WorldGenerator.ChunkSize.y; y++)
{
for(int z = 0; z < WorldGenerator.ChunkSize.z; z++)
{
Vector3Int BlockPos = new Vector3Int(x, y, z);
for (int i = 0; i < CheckDirections.Length; i++)
{
Vector3Int BlockToCheck = BlockPos + CheckDirections[i];
try
{
if(Data[BlockToCheck.x, BlockToCheck.y, BlockToCheck.z] == 0)
{
if(Data[BlockPos.x, BlockPos.y, BlockPos.z] != 0)
{
FaceData FaceToApply = CubeFaces[CheckDirections[i]];
foreach(Vector3 vert in FaceToApply.Vertices)
{
Vertices.Add(new Vector3(x, y, z) + vert);
}
foreach(int tri in FaceToApply.Indices)
{
Indices.Add(Vertices.Count - 4 + tri);
}
}
}
}
catch(System.Exception)
//draws faces towarsds the outside of data
{ if(Data[BlockToCheck.x, BlockToCheck.y, BlockToCheck.z] == 0)
{
if(Data[BlockPos.x, BlockPos.y, BlockPos.z] != 0)
{
FaceData FaceToApply = CubeFaces[CheckDirections[i]];
foreach(Vector3 vert in FaceToApply.Vertices)
{
Vertices.Add(new Vector3(x, y, z) + vert);
}
foreach(int tri in FaceToApply.Indices)
{
Indices.Add(Vertices.Count - 4 + tri);
}
}
}
}
}
}
}
m.SetVertices(Vertices);
m.SetIndices(Indices, MeshTopology.Triangles, 0);
m.RecalculateBounds();
m.RecalculateTangents();
m.RecalculateNormals();
return m;
}
}
}
This worked for that line, I’m not getting an error on that THANK YOU! I’m still having trouble with the upper parts of my code, and now i have a huge string of errors saying all the “ReadOnly” and “Static” modifiers are not valid.
The correct keyword is class, as you use on the line immediately above.
That’s just the first thing I see on line 2.
Look, you can save a LOT of time by just fixing your errors. You’re gonna have to anyway, so why not just do it?
You can fix your own typing mistakes. Here’s how:
Remember: NOBODY here memorizes error codes. That’s not a thing. The error code is absolutely the least useful part of the error. It serves no purpose at all. Forget the error code. Put it out of your mind.
The complete error message contains everything you need to know to fix the error yourself.
The important parts of the error message are:
the description of the error itself (google this; you are NEVER the first one!)
the file it occurred in (critical!)
the line number and character position (the two numbers in parentheses)
also possibly useful is the stack trace (all the lines of text in the lower console window)
Always start with the FIRST error in the console window, as sometimes that error causes or compounds some or all of the subsequent errors. Often the error will be immediately prior to the indicated line, so make sure to check there as well.
Look in the documentation. Every API you attempt to use is probably documented somewhere. Are you using it correctly? Are you spelling it correctly? Are you structuring the syntax correctly? Look for examples!
All of that information is in the actual error message and you must pay attention to it. Learn how to identify it instantly so you don’t have to stop your progress and fiddle around with the forum.
THAT was my error. I knew it was gonna be such a simple thing like a typo or a syntax error.
First off I appreciate that and your response!
So when I first ran into this issue I actually did try googling it a few times, and maybe it was my phrasing in google, but I couldn’t find anything related to my issue, all I found were very problem specific solutions. With that being said, I 100% need to work on solving things myself. I’ve had a few minor errors that I’ve been able to work out on my own, but I think what happened here was I had so many errors I was overwhelmed, and wasn’t even sure where to start looking.
I think one of the first things I really should do is familiarize myself with error messages like you said, because yeah, I very much so could have been able to sort this out within an hour rather than waiting around for the forum to help me.
Also I knew that the first number in the error message referred to the line, I did not know the second number was the character, so that in itself will help me.
I think one of my other issues is I hate taking my time with stuff. I’d rather just jump head first, make mistakes, and then go “okay what’s wrong with this now?” but Seeing as how new I am to C# I just got a bit overwhelmed.
Thanks a lot for your comment!! it means a lot, I will for sure try and work on what you’ve suggested
Great you solved that one Note that you have your mesh creation and the return statement inside your first loop and not outside. So one curly brace is essentially misplaced.
Apart from that this is quite verbose and unnecessarily complex. The worst part is your “ChunkMeshCreator” constructor. You use an array to iterate through 6 values and for each iteration you have one specialized case.
So instead of that for loop you could just do:
public ChunkMeshCreator()
{
CubeFaces = new Dictionary<Vector3Int, FaceData>();
CubeFaces.Add(Vector3Int.up, new FaceData(UpFace, UpTris));
CubeFaces.Add(Vector3Int.down, new FaceData(DownFace, DownTris));
CubeFaces.Add(Vector3Int.forward, new FaceData(ForwardFace, ForwardTris));
CubeFaces.Add(Vector3Int.back, new FaceData(BackFace, BackTris));
CubeFaces.Add(Vector3Int.left, new FaceData(LeftFace, LeftTris));
CubeFaces.Add(Vector3Int.right, new FaceData(RightFace, RightTris));
}
Though apart from that using Vector3Int as key in a dictionary seems completely unnecessary since all you do is iterating through all 6 directions in every case. So storing the normal inside the “FaceData” and storing the face data instances in a normal array would make more sense. Dictionary lookups in this case will make your code much slower.
Also your triangle data for the 6 faces are kinda randomly arranged. That could be streamlined so each face use the exact same 6 triangle index offsets. It’s just a matter of arranging the vertices properly. The vertex data could also be constructed based on two direction vectors.
Finally while multi dimensional arrays seem convenient, they are actually quite slow. Under the hood a multidimensional array is just a normal one dimensional array and it just does the index calculation and bounds checks for every single access. When you just use a flattened one dimensional array, you can actually calculate the x, y and z offsets separately at the start of each loop and just add them together.
Instead of recalculate normals, it would be much cheaper to just build the normals array yourself. All vertices of a face would have the same normal vector and it would be equal to your “direction vector”
Many of those things I mentioned aren’t necessary, but they can have an effect in the long run when you run into performance issues.