Using out keyword in iterator is violation - c#

I'm creating a mesh with vertices and triangles. I would like to assign the value of triangles in my MonoBehavior through out keyword:
public IEnumerable grabTriangle(int xSize, int zSize, out int[] triangles)
{
triangles = new int[xSize * zSize * 6];
int vert = 0;
int tris = 0;
for (int z = 0; z < zSize; z++)
{
for (int x = 0; x < xSize; x++)
{
triangles[tris + 0] = vert + 0;
triangles[tris + 1] = vert + xSize+1;
triangles[tris + 2] = vert + 1;
triangles[tris + 3] = vert + 1;
triangles[tris + 4] = vert + xSize + 1;
triangles[tris + 5] = vert + xSize + 2;
vert++;
tris += 6;
yield return new WaitForSeconds(.01f);
}
vert++;
}
}
But, I'm getting the following error:
Iterators can not have out parameters.
Is there any other alternative?

Related

How do i fix the IndexOutOfRangeException error? [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 4 months ago.
I am trying to make mesh rendering in Unity 3D but the code is supposed to work, Here is what it said: IndexOutOfRangeException: Index was outside the bounds of the array. MeshGen.CreateShape () (at Assets/MeshGen.cs:33)
MeshGen.Start () (at Assets/MeshGen.cs:22)
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class MeshGen : MonoBehaviour {
Mesh mesh;
Vector3[] vertices;
int[] triangles;
public int xSize = 20;
public int zSize = 20;
// Start is called before the first frame update
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
CreateShape();
UpdateMesh();
}
void CreateShape()
{
vertices = new Vector3[(xSize * 1) * (zSize * 1)];
int i = 0;
for (int z = 0; z <= zSize; z++)
{
for (int x = 0; x <= xSize; x++)
{
vertices[i] = new Vector3(x, 0, z);
i++;
}
}
triangles = new int[xSize * zSize * 6];
int vert = 0;
int tris = 0;
for (int x = 0; x < xSize; x++)
{
triangles[tris + 0] = vert + 0;
triangles[tris + 1] = vert + xSize + 1;
triangles[tris + 2] = vert + 1;
triangles[tris + 3] = vert + 1;
triangles[tris + 4] = vert + xSize + 1;
triangles[tris + 5] = vert + xSize + 2;
vert++;
tris += 6;
}
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
private void OnDrawGizmos()
{
if (vertices == null)
{return;}
for (int i = 0; i < vertices.Length; i++)
{
Gizmos.DrawSphere(vertices[i], .1f);
}
}
}
I tried fixing it, tried searching on google and i made sure that it is right.
This was the only error i got.
Let's check this:
public int xSize = 20;
public int zSize = 20;
// array of size 20*20=400 : indexes in range [0:399]
vertices = new Vector3[(xSize * 1) * (zSize * 1)];
int i = 0;
// loop in range [0:20] (21 iterations)
for (int z = 0; z <= zSize; z++)
{
// loop in range [0:20] (21 iterations)
for (int x = 0; x <= xSize; x++)
{
vertices[i] = new Vector3(x, 0, z);
i++;
// after we reach z=18 and x=20, i=399
// from now on, we are OutOfBounds
}
}
You should probably switch to strict inequality < instead of <=

Problem with making mesh at runtime. (Unity3d)

I'm trying to make mesh with Vector3 data from database at runtime.
Here is my code
private IEnumerator CreateShape()
{
int count = 0;
triangles = new int[x_size * y_size * 6];
//index buffer
for (int i = 0; i < x_size - 1; i++)
{
for (int j = 0; j < y_size - 1; j++)
{
triangles[((i * y_size + j) * 6) + 0] = i * y_size + j;
triangles[((i * y_size + j) * 6) + 1] = (i + 1) * y_size + j;
triangles[((i * y_size + j) * 6) + 2] = i * y_size + j + 1;
triangles[((i * y_size + j) * 6) + 3] = i * y_size + j + 1;
triangles[((i * y_size + j) * 6) + 4] = (i + 1) * y_size + j;
triangles[((i * y_size + j) * 6) + 5] = (i + 1) * y_size + j + 1;
}
yield return new WaitForSeconds(0.01f);
}
}
And check updates for updating Mesh data..
private void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
Vertices data has no problem, cuz i checked it with different way.
private void OnDrawGizmos()
{
if (vertices[x_size * y_size - 1] != Vector3.zero)
{
for (int i = 0; i < x_size - 1; i++)
{
for (int j = 0; j < y_size - 1; j++)
{
Gizmos.DrawSphere(vertices[i * y_size + j], .1f);
}
}
}
}
Checked whether vertices data is wrong or not with gizmos but the data has no probs:
It should form a simple plane mesh shape, but it goes back to the start point and continue making in the middle of mesh-create-process..
What i expected:
But it goes wrong:
It seemed somehow internal index buffer calculation goes wrong..
Vertices data is about 160,000ea Vector3, and tris is also about 160,000*6 = 1,000,000ea integer.
Maybe the data is too much for making mesh while runtime at all..?
or.. the axis is changed when x value become larger than y value..?
Why this happens? How can i fix this?
As said per default meshes in unity have an index buffer of 16-bit (= UInt16) meaning the maximum index is 65535.
If you want to go higher (like with your mesh) you will need to change the Mesh.indexFormat to 32-bit (= UInt32), allowing a maximum index of 4294967295.
Note though that not all GPU support this!

I can create a mesh (in awake) but I cannot see it

this is the part of the code that generate a mesh, if you want more information ask.
So in the scene I cannot see it, I tried to enter play mode but nothing, if I go in the inspector I can see: 4 verts, 2 tris, the right amount of tris and verts.
public void ConstructMesh()
{
Vector3[] vertices = new Vector3[(resolution + 2) * (resolution + 2)];
int[] triangles = new int[(resolution + 1) * (resolution + 1) * 6];
int triIndex = 0;
for (int y = 0; y < resolution; y++)
{
for (int x = 0; x < resolution; x++)
{
int i = x + y * resolution;
Vector2 percent = new Vector2(x, y) / (resolution - 1);
Vector3 pointOnUnitCode = localUp + (percent.x - .5f) * 2 * axisA + (percent.y - .5f) * 2 * axisB;
vertices[i] = pointOnUnitCode;
triangles[triIndex] = i;
triangles[triIndex + 1] = i + resolution + 1;
triangles[triIndex + 2] = i + resolution;
triangles[triIndex + 3] = i;
triangles[triIndex + 4] = i + 1;
triangles[triIndex + 5] = i + resolution + 1;
triIndex += 6;
}
}
planet.Clear();
planet.vertices = vertices;
planet.triangles = triangles;
planet.RecalculateNormals();
}
You need a MeshRenderer and MeshFilter in the GameObject to be able to render your mesh.
Supposing your method ConstructMesh is a MonoBehaviour and it's attached to the same object you want to display the mesh, you can do the following:
GetComponent<MeshFilter>().mesh = planet;

Unity map generation mesh doing weird things

So for some reason, this map generation works for up to xSize=100 and zSize=100.
As soon as I go further it does weird things like this (at xSize=300 and zSize=300):
Going even more up to 1000x1000 it generates something like this:
I have no idea why it works just up to 100x100.
Is there some mesh limitation I'm not aware of?
I first thought just the vertices weren't connecting properly but then after doing the 1000x1000 example and looking the 300x300 example from top it definitely doesn't even make the vertices in right place...
I can't see an error in my code for some reason. I'm stuck here looking the code blindly all day.
Any help?
Code [Just the CreateMapXZ() function]:
vertices = new Vector3[(xSize + 1) * (zSize + 1)];
uvs = new Vector2[(xSize + 1) * (zSize + 1)];
float uvFactorX = 1.0f / xSize;
float uvFactorZ = 1.0f / zSize;
for (int i = 0, z = 0; z <= zSize; z++)
{
for (int x = 0; x <= xSize; x++)
{
vertices[i] = new Vector3(x, 0, z);
uvs[i++] = new Vector2(x * uvFactorX, z * uvFactorZ);
//i++;
}
}
triangles = new int[xSize * zSize * 6];
int vert = 0;
int tris = 0;
for (int z = 0; z < zSize; z++)
{
for (int x = 0; x < xSize; x++)
{
triangles[tris + 0] = vert + 0;
triangles[tris + 1] = vert + xSize + 1;
triangles[tris + 2] = vert + 1;
triangles[tris + 3] = vert + 1;
triangles[tris + 4] = vert + xSize + 1;
triangles[tris + 5] = vert + xSize + 2;
vert++;
tris += 6;
}
vert++;
}
applyNoise();
UpdateMesh();

What error did I make while copying this procedural plane generator from a video?

I am trying to start work on learning strategy/base building games in unity. I started out by copying code from this video but my version only does a single line of squares.
It is the z dimension that does not continue and it does seem like it is a problem with the triangles/normals as the vertices seem to be in the right place via making the vertices a public variable and seeing them in unity's inspector. I think I'd have to write a widget to show the vertices to be sure as I'm no mathematician. I removed the actual creation of the object in unity for the sake of brevity as there is no math involved. Also the procedural object does seem to crumble to nothing at larger sizes, although that's not really an issue until the first one is fixed.
void BuildMesh()
{
int numTiles = size_x * size_z;
int numTris = numTiles * 2;
int vsize_x = size_x + 1;
int vsize_z = size_z + 1;
int numVerts = vsize_x * vsize_z;
//Generate Mesh Data
vertices = new Vector3[ numVerts ];
Vector3[] normals = new Vector3[ numVerts ];
Vector2[] uv = new Vector2[ numVerts ];
int[] triangles = new int[ numTris * 3];
int x, z;
for (z = 0; z < vsize_z; z++)
{
for (x = 0; x < vsize_x; x++)
{
vertices[z * vsize_x + x] = new Vector3(x * tileSize, 0, z * tileSize);
normals[ z * vsize_x + x] = Vector3.up;
uv[z * vsize_x + x] = new Vector2((float)x / vsize_x, (float)z / vsize_z);
}
}
for (z = 0; z < size_z; z++)
{
for (x = 0; x < size_x; x++)
{
int squareIndex = x * size_x + x;
int triOffset = squareIndex * 6;
triangles[triOffset + 0] = z * vsize_x + x + 0;
triangles[triOffset + 1] = z * vsize_x + x + vsize_x + 0;
triangles[triOffset + 2] = z * vsize_x + x + vsize_x + 1;
triangles[triOffset + 3] = z * vsize_x + x + 0;
triangles[triOffset + 4] = z * vsize_x + x + vsize_x + 1;
triangles[triOffset + 5] = z * vsize_x + x + 1;
}
}
The code from the video:
derHugo answered the question in the comments. Just posting this to mark it as answered. Thanks.

Categories

Resources