Unity 中的内存不足异常生成立方体将立方体的每个面细分 4 次
Out of Memory Exception in Unity generating Cube subdividing each face of the cube 4 times
我想生成一个立方体,并将立方体的每个面细分4次,这样一个6面的立方体就有24个面。我正在尝试在 Unity3d 中执行此操作,但是当我尝试执行它时它给了我 内存不足异常 。我认为这可能是由于一些效率低下的代码造成的,但我想我遗漏了一些东西,因为我正在尝试查看是否可以提高它的效率,但我并没有真正看到任何非常糟糕的事情。
这是我的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class sphereMesh : MonoBehaviour
{
// Start is called before the first frame update
Mesh mesh;
List<Vector3> vertices = new List<Vector3>();
List<int> triangulos = new List<int>();
public int numeroSubdivisiones = 1;
static Vector3[] faceCubes = {
new Vector3(1, 1, 1), //0
new Vector3(-1, 1, 1), //1
new Vector3(-1, -1, 1), //2
new Vector3(1, -1, 1), //3
new Vector3(-1, 1, -1), //4
new Vector3(1, 1, -1), //5
new Vector3(1, -1, -1), //6
new Vector3(-1, -1, -1) //7
};
static int[][] facetriangulos = {
// Cara trasera
new int[]{0,1,2,3},
// Cara derecha
new int[]{5,0,3,6},
// Cara frontal
new int[]{4,5,6,7},
// Cara izquierda
new int[]{1,4,7,2},
// Cara arriba
new int[]{5,4,1,0},
// Cara abajo
new int[]{3,2,7,6},
};
void MakeFace(int dir)
{
vertices.AddRange(faceVertices(dir));
int vCount = vertices.Count;
triangulos.Add(vCount - 4);
triangulos.Add(vCount - 4 + 1);
triangulos.Add(vCount - 4 + 2);
triangulos.Add(vCount - 4);
triangulos.Add(vCount - 4 + 2);
triangulos.Add(vCount - 4 + 3);
}
void MakeCube()
{
vertices = new List<Vector3>();
triangulos = new List<int>();
for (int i = 0; i <6; i++)
{
MakeFace(i);
}
}
// Funcion que crea una cara de vertices
public static Vector3[] faceVertices(int dir)
{
Vector3[] fv = new Vector3[4];
for (int i = 0; i < fv.Length; i++)
{
// La direccion y la posicion del array
fv[i] = faceCubes[facetriangulos[dir][i]];
}
return fv;
}
// Modifica la lista de vertices y la actualiza
// De forma que un cuadrado da lugar a otros cuatro cuadrados
// T --> Top, D --> Down, L --> Left, R --> Right
// v --> Vertice
void subdividirCuadrado(Vector3 vTL, Vector3 vTR, Vector3 vDL, Vector3 vDR)
{
Vector3 vT = vT = Vector3.Lerp(vTR, vTL, 0.5f);
Vector3 vD = vD = Vector3.Lerp(vDR, vDL, 0.5f);
Vector3 vR = vR = Vector3.Lerp(vTR,vDR, 0.5f);
Vector3 vL = vL = Vector3.Lerp(vTL,vDL, 0.5f);
Vector3 vCenter = Vector3.Lerp(vR, vL, 0.5f);
int size = vertices.Count;
vertices.AddRange(new List<Vector3> {vT, vD, vL, vR, vTL, vTR, vDL, vDR, vCenter});
int tT = size + 0;
int tD = size + 1;
int tL = size + 2;
int tR = size + 3;
int tTL = size + 4;
int tTR = size + 5;
int tDL = size + 6;
int tDR = size + 7;
int tCenter = size + 8;
triangulos.AddRange(new List<int> {tL, tTL, tT});
triangulos.AddRange(new List<int> {tL, tT, tCenter});
triangulos.AddRange(new List<int> {tCenter, tT, tTR});
triangulos.AddRange(new List<int> {tCenter, tTR, tR});
triangulos.AddRange(new List<int> {tDL, tL, tCenter});
triangulos.AddRange(new List<int> {tDL, tCenter, tD});
triangulos.AddRange(new List<int> {tD, tCenter, tR});
triangulos.AddRange(new List<int> {tD, tR, tDR});
}
void subCubo()
{
for(int j = 0; j < numeroSubdivisiones; j++)
{
Debug.Log("AAAAA" + vertices.Count);
for (int i = 0; i < vertices.Count; i += 4)
{
subdividirCuadrado(vertices[i], vertices[i+1], vertices[i+2], vertices[i+3]);
/*
mesh.vertices[i][0] = mesh.vertices[i][0]/i;
mesh.vertices[i][1] = mesh.vertices[i][1]/i;
mesh.vertices[i][2] = mesh.vertices[i][2]/i;
mesh.vertices[i+1][0] = mesh.vertices[i+1][0]/i+1;
mesh.vertices[i+1][1] = mesh.vertices[i+1][1]/i+1;
mesh.vertices[i+1][2] = mesh.vertices[i+1][2]/i+1;
mesh.vertices[i+2][0] = mesh.vertices[i+2][0]/i+2;
mesh.vertices[i+2][1] = mesh.vertices[i+2][1]/i+2;
mesh.vertices[i+2][2] = mesh.vertices[i+2][2]/i+2;
mesh.vertices[i+3][0] = mesh.vertices[i+3][0]/i+3;
mesh.vertices[i+3][1] = mesh.vertices[i+3][1]/i+3;
mesh.vertices[i+3][2] = mesh.vertices[i+3][2]/i+3;
*/
}
}
}
void Awake()
{
mesh = GetComponent<MeshFilter>().mesh;
}
void Start()
{
MakeCube();
subCubo();
UpdateMesh();
}
// Update is called once per frame
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices.ToArray();
mesh.triangles = triangulos.ToArray();
mesh.RecalculateNormals();
}
}
vertices.AddRange(新列表 { vT、vD、vL、vR、vTL、vTR、vDL、vDR、vCenter });
subdividirCuadrado() 中的这一行
您将 9 个新顶点添加到顶点列表,但它在内部
对于 (int i = 0; i < vertices.Count; i += 4)。
结果是计数不断上升。无限:)
我认为这是无限循环:
for (int i = 0; i < vertices.Count; i += 4)
{
subdividirCuadrado(vertices[i], vertices[i+1], vertices[i+2], vertices[i+3]);
你继续循环直到 i 大于顶点中的项目数。
在每次迭代中 i 增加 4,但顶点中有 9 个新项目:
vertices.AddRange(new List<Vector3> {vT, vD, vL, vR, vTL, vTR, vDL, vDR, vCenter});
因此 i 永远不会大于 vertices.count 因此循环是无限的。
我想生成一个立方体,并将立方体的每个面细分4次,这样一个6面的立方体就有24个面。我正在尝试在 Unity3d 中执行此操作,但是当我尝试执行它时它给了我 内存不足异常 。我认为这可能是由于一些效率低下的代码造成的,但我想我遗漏了一些东西,因为我正在尝试查看是否可以提高它的效率,但我并没有真正看到任何非常糟糕的事情。
这是我的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class sphereMesh : MonoBehaviour
{
// Start is called before the first frame update
Mesh mesh;
List<Vector3> vertices = new List<Vector3>();
List<int> triangulos = new List<int>();
public int numeroSubdivisiones = 1;
static Vector3[] faceCubes = {
new Vector3(1, 1, 1), //0
new Vector3(-1, 1, 1), //1
new Vector3(-1, -1, 1), //2
new Vector3(1, -1, 1), //3
new Vector3(-1, 1, -1), //4
new Vector3(1, 1, -1), //5
new Vector3(1, -1, -1), //6
new Vector3(-1, -1, -1) //7
};
static int[][] facetriangulos = {
// Cara trasera
new int[]{0,1,2,3},
// Cara derecha
new int[]{5,0,3,6},
// Cara frontal
new int[]{4,5,6,7},
// Cara izquierda
new int[]{1,4,7,2},
// Cara arriba
new int[]{5,4,1,0},
// Cara abajo
new int[]{3,2,7,6},
};
void MakeFace(int dir)
{
vertices.AddRange(faceVertices(dir));
int vCount = vertices.Count;
triangulos.Add(vCount - 4);
triangulos.Add(vCount - 4 + 1);
triangulos.Add(vCount - 4 + 2);
triangulos.Add(vCount - 4);
triangulos.Add(vCount - 4 + 2);
triangulos.Add(vCount - 4 + 3);
}
void MakeCube()
{
vertices = new List<Vector3>();
triangulos = new List<int>();
for (int i = 0; i <6; i++)
{
MakeFace(i);
}
}
// Funcion que crea una cara de vertices
public static Vector3[] faceVertices(int dir)
{
Vector3[] fv = new Vector3[4];
for (int i = 0; i < fv.Length; i++)
{
// La direccion y la posicion del array
fv[i] = faceCubes[facetriangulos[dir][i]];
}
return fv;
}
// Modifica la lista de vertices y la actualiza
// De forma que un cuadrado da lugar a otros cuatro cuadrados
// T --> Top, D --> Down, L --> Left, R --> Right
// v --> Vertice
void subdividirCuadrado(Vector3 vTL, Vector3 vTR, Vector3 vDL, Vector3 vDR)
{
Vector3 vT = vT = Vector3.Lerp(vTR, vTL, 0.5f);
Vector3 vD = vD = Vector3.Lerp(vDR, vDL, 0.5f);
Vector3 vR = vR = Vector3.Lerp(vTR,vDR, 0.5f);
Vector3 vL = vL = Vector3.Lerp(vTL,vDL, 0.5f);
Vector3 vCenter = Vector3.Lerp(vR, vL, 0.5f);
int size = vertices.Count;
vertices.AddRange(new List<Vector3> {vT, vD, vL, vR, vTL, vTR, vDL, vDR, vCenter});
int tT = size + 0;
int tD = size + 1;
int tL = size + 2;
int tR = size + 3;
int tTL = size + 4;
int tTR = size + 5;
int tDL = size + 6;
int tDR = size + 7;
int tCenter = size + 8;
triangulos.AddRange(new List<int> {tL, tTL, tT});
triangulos.AddRange(new List<int> {tL, tT, tCenter});
triangulos.AddRange(new List<int> {tCenter, tT, tTR});
triangulos.AddRange(new List<int> {tCenter, tTR, tR});
triangulos.AddRange(new List<int> {tDL, tL, tCenter});
triangulos.AddRange(new List<int> {tDL, tCenter, tD});
triangulos.AddRange(new List<int> {tD, tCenter, tR});
triangulos.AddRange(new List<int> {tD, tR, tDR});
}
void subCubo()
{
for(int j = 0; j < numeroSubdivisiones; j++)
{
Debug.Log("AAAAA" + vertices.Count);
for (int i = 0; i < vertices.Count; i += 4)
{
subdividirCuadrado(vertices[i], vertices[i+1], vertices[i+2], vertices[i+3]);
/*
mesh.vertices[i][0] = mesh.vertices[i][0]/i;
mesh.vertices[i][1] = mesh.vertices[i][1]/i;
mesh.vertices[i][2] = mesh.vertices[i][2]/i;
mesh.vertices[i+1][0] = mesh.vertices[i+1][0]/i+1;
mesh.vertices[i+1][1] = mesh.vertices[i+1][1]/i+1;
mesh.vertices[i+1][2] = mesh.vertices[i+1][2]/i+1;
mesh.vertices[i+2][0] = mesh.vertices[i+2][0]/i+2;
mesh.vertices[i+2][1] = mesh.vertices[i+2][1]/i+2;
mesh.vertices[i+2][2] = mesh.vertices[i+2][2]/i+2;
mesh.vertices[i+3][0] = mesh.vertices[i+3][0]/i+3;
mesh.vertices[i+3][1] = mesh.vertices[i+3][1]/i+3;
mesh.vertices[i+3][2] = mesh.vertices[i+3][2]/i+3;
*/
}
}
}
void Awake()
{
mesh = GetComponent<MeshFilter>().mesh;
}
void Start()
{
MakeCube();
subCubo();
UpdateMesh();
}
// Update is called once per frame
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices.ToArray();
mesh.triangles = triangulos.ToArray();
mesh.RecalculateNormals();
}
}
vertices.AddRange(新列表 { vT、vD、vL、vR、vTL、vTR、vDL、vDR、vCenter });
subdividirCuadrado() 中的这一行
您将 9 个新顶点添加到顶点列表,但它在内部 对于 (int i = 0; i < vertices.Count; i += 4)。 结果是计数不断上升。无限:)
我认为这是无限循环:
for (int i = 0; i < vertices.Count; i += 4)
{
subdividirCuadrado(vertices[i], vertices[i+1], vertices[i+2], vertices[i+3]);
你继续循环直到 i 大于顶点中的项目数。 在每次迭代中 i 增加 4,但顶点中有 9 个新项目:
vertices.AddRange(new List<Vector3> {vT, vD, vL, vR, vTL, vTR, vDL, vDR, vCenter});
因此 i 永远不会大于 vertices.count 因此循环是无限的。