- Home /
Submeshs doesn't combine with materials
Simple as that, submeshs doesn't combine with materials and i get an error: Failed setting triangles. Some indices are referencing out of bounds vertices. IndexCount: 18, VertexCount: 4.
The count of submesh is same count as material, i think the error is coming from this: All submeshs aren't assing yet with an material. How can i fix it? Don't give me all the solution, i hate that...
Here's the script!
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ScreenBoard : MonoBehaviour {
public Transform ScreenObject;
//public Texture2D PixelsRed;
//public Texture2D PixelsBlue;
//public Texture2D PixelsGreen;
//public Texture2D PixelsBlack;
//public Texture2D PixelsWhite;
//public Texture2D PixelsYellow;
//public Texture2D PixelsOrange;
//public Texture2D PixelsMangenta;
public Material[] mats;
List<Vector3> vertices;
List<int> triangles;
List<Vector2> uvs;
MeshFilter mf;
Mesh mesh;
MeshRenderer mr;
int[,] ColorIdInt;
int ColorInt;
//15w by 10h pixelscreen
void ResetScreen() {
vertices = new List<Vector3>();
triangles = new List<int>();
uvs = new List<Vector2>();
ColorIdInt = new int[15,10];
mf = ScreenObject.GetComponent<MeshFilter>();
mesh = new Mesh();
mr = ScreenObject.GetComponent<MeshRenderer>();
mf.mesh = mesh;
mesh.subMeshCount = 8;
}
void SetPixelUpdate(float X, float Y, string ColorId) {
int SaveX = Mathf.RoundToInt(X);
int SaveY = Mathf.RoundToInt(Y);
X = Mathf.RoundToInt(X);
Y = Mathf.RoundToInt(Y);
X = X * 0.1f;
Y = Y * 0.1f;
Vector3[] verticles = new Vector3[4] {
new Vector3(X + 0, Y + 0, -0.01f), new Vector3( X + 0.1f, Y + 0, -0.01f), new Vector3(X + 0, Y + 0.1f, -0.01f), new Vector3(X + 0.1f, Y + 0.1f, -0.01f)
};
int[] tri = new int[6];
tri[0] = vertices.Count + 0;
tri[1] = vertices.Count + 2;
tri[2] = vertices.Count + 1;
tri[3] = vertices.Count + 2;
tri[4] = vertices.Count + 3;
tri[5] = vertices.Count + 1;
foreach(Vector3 V3 in verticles) {
vertices.Add(V3);
}
foreach(int TS in tri) {
triangles.Add(TS);
}
mesh.vertices = vertices.ToArray();
mesh.triangles = triangles.ToArray();
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0,0);
uv[1] = new Vector2(1,0);
uv[2] = new Vector2(0,1);
uv[3] = new Vector2(1,1);
foreach(Vector2 SingleUV in uv) {
uvs.Add(SingleUV);
}
mesh.uv = uvs.ToArray();
mesh.RecalculateNormals();
ColorInt = 0;
switch(ColorId) {
case "Red":
ColorInt = 0;
ColorIdInt[SaveX,SaveY] = 1;
break;
case "Green":
ColorInt = 1;
ColorIdInt[SaveX,SaveY] = 2;
break;
case "Blue":
ColorInt = 2;
ColorIdInt[SaveX,SaveY] = 3;
break;
case "Black":
ColorInt = 3;
ColorIdInt[SaveX,SaveY] = 4;
break;
case "White":
ColorInt = 4;
ColorIdInt[SaveX,SaveY] = 5;
break;
case "Yellow":
ColorInt = 5;
ColorIdInt[SaveX,SaveY] = 6;
break;
case "Orange":
ColorInt = 6;
ColorIdInt[SaveX,SaveY] = 7;
break;
case "Magenta":
ColorInt = 7;
ColorIdInt[SaveX,SaveY] = 8;
break;
default:
ColorInt = 0;
ColorIdInt[SaveX,SaveY] = 1;
break;
}
mesh.subMeshCount = 8;
mf.mesh.SetTriangles(triangles, ColorInt); //ColorInt > submesh
mr.materials = mats;
}
void Fill (int X1, int Y1, int X2, int Y2, string ColorId) {
for(int x = 0; x < X2; x++) {
for(int y = 0; y < Y2; y++) {
SetPixelUpdate(x + X1, y + Y1, ColorId);
}
}
}
int GetColorOnPixel (int X, int Y) {
if(ColorIdInt[X,Y] != null) {
return ColorIdInt[X,Y];
} else {
return 0;
}
}
void RemovePixel (int X, int Y) {
//new Vector3(X + 0, Y + 0, -0.01f), new Vector3( X + 0.1f, Y + 0, -0.01f), new Vector3(X + 0, Y + 0.1f, -0.01f), new Vector3(X + 0.1f, Y + 0.1f, -0.01f)
vertices.Remove(new Vector3(X + 0, Y + 0, -0.01f));
vertices.Remove(new Vector3(X + 0.1f, Y + 0, -0.01f));
vertices.Remove(new Vector3(X + 0, Y + 0.1f, -0.01f));
vertices.Remove(new Vector3(X + 0.1f, Y + 0.1f, -0.01f));
mesh.vertices = vertices.ToArray();
ColorIdInt[X,Y] = 0;
}
// Use this for initialization
void Start () {
ResetScreen();
SetPixelUpdate(1,1, "Red");
SetPixelUpdate(1,2, "Blue");
SetPixelUpdate(1,3, "Green");
}
// Update is called once per frame
void Update () {
}
}
I hope you understand; "bad english".
Answer by tomhog · Dec 10, 2015 at 11:54 PM
Hi
I've literally no idea what you're trying to achieve but here's working version
void SetPixelUpdate(float X, float Y, string ColorId) {
int SaveX = Mathf.RoundToInt(X);
int SaveY = Mathf.RoundToInt(Y);
X = Mathf.RoundToInt(X);
Y = Mathf.RoundToInt(Y);
X = X * 0.1f;
Y = Y * 0.1f;
Vector3[] verticles = new Vector3[4] {
new Vector3(X + 0, Y + 0, -0.01f), new Vector3( X + 0.1f, Y + 0, -0.01f), new Vector3(X + 0, Y + 0.1f, -0.01f), new Vector3(X + 0.1f, Y + 0.1f, -0.01f)
};
int[] tri = new int[6];
tri[0] = vertices.Count + 0;
tri[1] = vertices.Count + 2;
tri[2] = vertices.Count + 1;
tri[3] = vertices.Count + 2;
tri[4] = vertices.Count + 3;
tri[5] = vertices.Count + 1;
foreach(Vector3 V3 in verticles) {
vertices.Add(V3);
}
foreach(int TS in tri) {
triangles.Add(TS);
}
mesh.vertices = vertices.ToArray();
//mesh.triangles = triangles.ToArray();
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0,0);
uv[1] = new Vector2(1,0);
uv[2] = new Vector2(0,1);
uv[3] = new Vector2(1,1);
foreach(Vector2 SingleUV in uv) {
uvs.Add(SingleUV);
}
mesh.uv = uvs.ToArray();
mesh.RecalculateNormals();
ColorInt = 0;
switch(ColorId) {
case "Red":
ColorInt = 0;
ColorIdInt[SaveX,SaveY] = 1;
break;
case "Green":
ColorInt = 1;
ColorIdInt[SaveX,SaveY] = 2;
break;
case "Blue":
ColorInt = 2;
ColorIdInt[SaveX,SaveY] = 3;
break;
case "Black":
ColorInt = 3;
ColorIdInt[SaveX,SaveY] = 4;
break;
case "White":
ColorInt = 4;
ColorIdInt[SaveX,SaveY] = 5;
break;
case "Yellow":
ColorInt = 5;
ColorIdInt[SaveX,SaveY] = 6;
break;
case "Orange":
ColorInt = 6;
ColorIdInt[SaveX,SaveY] = 7;
break;
case "Magenta":
ColorInt = 7;
ColorIdInt[SaveX,SaveY] = 8;
break;
default:
ColorInt = 0;
ColorIdInt[SaveX,SaveY] = 1;
break;
}
mesh.subMeshCount = 8;
mesh.SetTriangles(triangles, ColorInt); //ColorInt > submesh
mr.materials = mats;
}
So you had two problems, 1. you were calling mesh.triangles = triangles.ToArray(); which kept destroying previous SetTriangles calls, 2. At the end you call mf.mesh.SetTriangles(triangles, ColorInt); //ColorInt > submesh, were as in the rest of the code you just use mesh. You need to read up on what happens when you set a mesh to a mesh filter and the difference between mf.mesh and mf.sharedMesh
Hope that helps Tom
Still not working but i will try to better explain.
This function is set a new pixel without delete all the other pixel which is save in the 'triangles' and 'vertices' list. X and Y variable is used to set the position of the new pixel. ColorId string is used for say in which submesh the new pixel will be. For exemple; "Red" is assing the pixel to the submesh with the red materials. I don't want to replace any submesh. - StudioSetPixelUpdate(X, Y, ColorId);
The code I gave compiles and runs with no errors, wether or not that solves your actual algorithm problem is a different question entirely.
I would simplify what you're doing, have separate meshes until you get it working, then try to combine into submeshes.
How can fix it? There's nothing on the web... I will post a forum for more help.