Hi,
i am working on a mesh generation algorithm using the advanced mesh API. When setting the submesh, I either get an error like
Index buffer element #0 (value 816551072) is out of bounds; mesh only has 4 vertices.
This makes sense so far, since the index buffer has just been allocated and still contains arbitrary data. I am actually using the flag MeshUpdateFlags.DontValidateIndices
when setting the SubmeshDescriptor. However when I do this, Unity will crash completely. I hope you can give me advice, I just cannot find the reason for this!
Here is a simplified version of my code, with which it is possible to reproduce this error:
using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class TestSubmeshCreation : MonoBehaviour
{
public void Generate()
{
int vertexCount = 4;
int indexCount = 6;
Mesh.MeshDataArray meshDataArray = Mesh.AllocateWritableMeshData(1);
Mesh.MeshData meshData = meshDataArray[0];
NativeArray<VertexAttributeDescriptor> descriptor = new(
4, Allocator.Temp, NativeArrayOptions.UninitializedMemory
);
try
{
descriptor[0] = new VertexAttributeDescriptor(dimension: 3);
descriptor[1] = new VertexAttributeDescriptor(
VertexAttribute.Normal, dimension: 3
);
descriptor[2] = new VertexAttributeDescriptor(
VertexAttribute.Tangent, dimension: 4
);
descriptor[3] = new VertexAttributeDescriptor(
VertexAttribute.TexCoord0, dimension: 2
);
meshData.SetVertexBufferParams(vertexCount, descriptor);
meshData.SetIndexBufferParams(indexCount, IndexFormat.UInt32);
meshData.subMeshCount = 1;
int startIndex = 0;
var subMeshDescriptor = new SubMeshDescriptor(startIndex, indexCount);
meshData.SetSubMesh(
0, subMeshDescriptor
//MeshUpdateFlags.DontValidateIndices
);
var mesh = GetComponent<MeshFilter>().mesh;
Mesh.ApplyAndDisposeWritableMeshData(meshDataArray, mesh);
}
finally
{
meshDataArray.Dispose();
descriptor.Dispose();
}
}
}
Here is the stack trace from the crash log:
Assertion failed on expression: ‘(int)lastVertex < data.GetVertexCount()’
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.Mesh/MeshData:SetSubMeshImpl (intptr,int,UnityEngine.Rendering.SubMeshDescriptor,UnityEngine.Rendering.MeshUpdateFlags)
UnityEngine.Mesh/MeshData:SetSubMesh (int,UnityEngine.Rendering.SubMeshDescriptor,UnityEngine.Rendering.MeshUpdateFlags)
TestSubmeshCreation:Generate () (at Assets/Scripts/TestSubmeshCreation.cs:49)
LiquidPlanet.EditorUI.TestSubmeshCreationInspector:OnInspectorGUI () (at Assets/Scripts/EditorUI/TestSubmeshCreationInspector.cs:35)
UnityEditor.UIElements.InspectorElement/<>c__DisplayClass59_0:b__0 ()
UnityEngine.UIElements.IMGUIContainer:smile:oOnGUI (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,bool,UnityEngine.Rect,System.Action,bool)
UnityEngine.UIElements.IMGUIContainer:HandleIMGUIEvent (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,System.Action,bool)
UnityEngine.UIElements.IMGUIContainer:HandleIMGUIEvent (UnityEngine.Event,System.Action,bool)
UnityEngine.UIElements.IMGUIContainer:HandleIMGUIEvent (UnityEngine.Event,bool)
UnityEngine.UIElements.IMGUIContainer:SendEventToIMGUIRaw (UnityEngine.UIElements.EventBase,bool,bool)
UnityEngine.UIElements.IMGUIContainer:SendEventToIMGUI (UnityEngine.UIElements.EventBase,bool,bool)
UnityEngine.UIElements.IMGUIContainer:HandleEvent (UnityEngine.UIElements.EventBase)
UnityEngine.UIElements.CallbackEventHandler:HandleEventAtTargetPhase (UnityEngine.UIElements.EventBase)
UnityEngine.UIElements.MouseCaptureDispatchingStrategy:smile:ispatchEvent (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.IPanel)
UnityEngine.UIElements.EventDispatcher:ApplyDispatchingStrategies (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.IPanel,bool)
UnityEngine.UIElements.EventDispatcher:ProcessEvent (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.IPanel)
UnityEngine.UIElements.EventDispatcher:ProcessEventQueue ()
UnityEngine.UIElements.EventDispatcher:OpenGate ()
UnityEngine.UIElements.EventDispatcherGate:smile:ispose ()
UnityEngine.UIElements.EventDispatcher:ProcessEvent (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.IPanel)
UnityEngine.UIElements.EventDispatcher:smile:ispatch (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.IPanel,UnityEngine.UIElements.DispatchMode)
UnityEngine.UIElements.BaseVisualElementPanel:SendEvent (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.DispatchMode)
UnityEngine.UIElements.UIElementsUtility:smile:oDispatch (UnityEngine.UIElements.BaseVisualElementPanel)
UnityEngine.UIElements.UIElementsUtility:UnityEngine.UIElements.IUIElementsUtility.ProcessEvent (int,intptr,bool&)
UnityEngine.UIElements.UIEventRegistration:ProcessEvent (int,intptr)
UnityEngine.UIElements.UIEventRegistration/<>c:<.cctor>b__1_2 (int,intptr)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)