MultiMesh
One Mesh with arrays of transforms, colors and custom data for many instances.
MultiMesh is an instancing resource rather than an Entity or collection of separate MeshInstance3D objects. Every instance shares one Mesh. Assign it to MultiMeshInstance3D.Multimesh or MultiMeshInstance2D.Multimesh to display it. An element is a data-record index rather than an Entity with its own script, collision or skeleton.
using var geometry = new BoxMesh();
using var batch = new MultiMesh();
batch.TransformFormat = MultiMesh.TransformFormatEnum.Transform3D;
batch.Mesh = geometry;
batch.InstanceCount = 2;
batch.SetInstanceTransform(0, Transform3D.Identity);
batch.SetInstanceTransform(1,
new Transform3D(Basis.Identity, new Vector3(3, 0, 0)));
batch.VisibleInstanceCount = -1;The example configures a resource without adding a visible object. Keep batch and geometry alive while their consumer uses them; using scopes here end a configuration check. Default format is 2D, so set TransformFormat first for 3D. Set UseColors/UseCustomData before InstanceCount too. Format/flag changes with positive count are rejected. To reconfigure, preserve your own data, set InstanceCount = 0, change layout, then allocate/fill records again.
InstanceCount allocates capacity; VisibleInstanceCount selects a visible prefix: -1 means all, 0 none, N the first N. It is not an arbitrary visible-index list. Visibility limits do not shrink the buffer. After capacity changes set a valid visible count again and do not assume previous records survive reallocation. Explicitly initialize every displayed transform.
SetInstanceTransform takes a local Transform3D relative to the consumer; the 2D variant requires Transform2D and 2D format. UseColors enables additional color, but material must use it. UseCustomData enables four floats carried by Color for shader INSTANCE_CUSTOM: not necessarily a color or automatic gameplay logic. Neither provides a separate Material per instance.
Use Buffer/SetBuffer for full uploads. It is float[] rather than byte[] or serialized Transform3D[]. Length must equal InstanceCount × stride. Base stride is 12 floats for 3D or 8 for 2D; add 4 for UseColors and another 4 for UseCustomData. A 3D record contains three rows (basis row xyz, origin component): translation occupies 3,7,11. 2D uses two rows (xx,yx,0,origin.x) and (xy,yy,0,origin.y). Optional color RGBA and custom RGBA follow. Do not memcpy Transform3D: its basis ordering differs. GetBuffer returns a managed copy; upload it again after editing. SetBuffer does nothing when InstanceCount = 0.
CustomAabb encloses the entire group in local coordinates, including movement/deformation and source Mesh size. Bounds that are too small cause disappearance; overly large bounds reduce culling effectiveness. Partition large worlds spatially: MultiMesh does not replace streaming or separate Entity culling. Draw calls depend on materials, surfaces and render passes; do not assume one call or a fixed speedup. Shared Mesh blend shapes are not supported as separate per-instance animation.
PhysicsInterpolationQuality selects the method for already-configured interpolation; it neither enables it nor changes physics tick rate. SetBufferInterpolated takes current/previous buffers with matching layout/length; call in the appropriate physics process with consumer interpolation enabled. After teleporting, set the new transform and reset that index history using ResetInstancePhysicsInterpolation; ResetInstancesPhysicsInterpolation resets the whole group. Reset itself does not move an object.
ColorArray, CustomDataArray, TransformArray and Transform2DArray are SDK Obsolete properties that iterate over elements. Prefer per-instance methods or Buffer for new code. Changed is not a universal update signal: 2D transforms and CustomAabb emit it, while 3D transforms, color, custom data and bulk uploads do not.
21 Windows headless checks covered resource settings and bulk CPU-buffer copies. Dummy backend does not store scalar transform/color/custom writes, returns default bounds and has no interpolator. A successful headless call therefore does not establish object placement, visible color, interpolation, culling, GPU rendering or speedup; verify those separately with a renderer.
Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.
Constructors1
MultiMeshConstructor
public MultiMesh();Creates an owned empty resource: 2D format, count 0, visible -1, colors/custom disabled, Fast interpolation quality. Display requires a separate consumer.
Properties13
BufferProperty
public float[] Buffer { get; set; }Full InstanceCount × stride float buffer. Stride = (3D:12 / 2D:8) + colors:4 + custom:4. Getter returns a copy; setter uploads the entire buffer. Neither bytes nor a live view.
ColorArrayProperty · Deprecated
public Color[] ColorArray { get; set; }SDK Obsolete: legacy colors array accessing instances element by element. Use corresponding Set/GetInstance methods or Buffer for new code; not a live view.
CustomAabbProperty
public Aabb CustomAabb { get; set; }Local-space bounds of the whole group, including full Mesh size and movement. Zero Aabb removes the renderer custom override. Setter emits Changed; does not create collision.
CustomDataArrayProperty · Deprecated
public Color[] CustomDataArray { get; set; }SDK Obsolete: legacy custom data array accessing instances element by element. Use corresponding Set/GetInstance methods or Buffer for new code; not a live view.
InstanceCountProperty
public int InstanceCount { get; set; }Nonnegative record capacity. Setting allocates backend data; do not assume records survive capacity changes. Set format/flags beforehand.
MeshProperty
public Mesh Mesh { get; set; }Shared Mesh for every record or null. Materials come from the shared Mesh/consumer; does not create a separate Material per record.
PhysicsInterpolationQualityProperty
public MultiMesh.PhysicsInterpolationQualityEnum PhysicsInterpolationQuality { get; set; }Fast by default or High interpolation method. Does not enable interpolation, increase physics frequency or fix uninitialized transforms.
Transform2DArrayProperty · Deprecated
public Vector2[] Transform2DArray { get; set; }SDK Obsolete: legacy 2D transforms array accessing instances element by element. Use corresponding Set/GetInstance methods or Buffer for new code; not a live view.
TransformArrayProperty · Deprecated
public Vector3[] TransformArray { get; set; }SDK Obsolete: legacy 3D transforms array accessing instances element by element. Use corresponding Set/GetInstance methods or Buffer for new code; not a live view.
TransformFormatProperty
public MultiMesh.TransformFormatEnum TransformFormat { get; set; }Transform layout, 2D by default. Change only at zero capacity; select Transform3D before InstanceCount for 3D.
UseColorsProperty
public bool UseColors { get; set; }Four additional color floats per record, disabled by default. Configure only at count 0; visible use depends on material.
UseCustomDataProperty
public bool UseCustomData { get; set; }Four additional custom floats per record, disabled by default. Configure at count 0; shader reads the values.
VisibleInstanceCountProperty
public int VisibleInstanceCount { get; set; }Number of leading records to display, -1 for all. Not allocated-array size or automatic individual culling.
Methods32
GetAabbAabb
public Aabb GetAabb();Queries group bounds from the renderer rather than one instance bounds or the CustomAabb getter. Dummy returns default, so headless does not establish bounds/culling.
AabbRenderer group Aabb; default in dummy backend.
GetBufferfloat[]
public float[] GetBuffer();Gets a managed copy of the bulk float buffer. Edits require another upload; renderer readback can be expensive.
float[]New managed float-buffer copy; reading does not establish visible GPU output.
GetCustomAabbAabb
public Aabb GetCustomAabb();Reads the stored custom override rather than computed group bounds.
AabbStored custom Aabb, default until assigned.
GetInstanceColorColor
public Color GetInstanceColor(int instance);Reads record color with UseColors = true and a valid index. Dummy getter returns default rather than verified GPU color.
| Name | Type | Default |
|---|---|---|
instance | int | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
ColorRecord Color; default on diagnostics/in dummy. Not a universal invalid-index sentinel.
GetInstanceCountint
public int GetInstanceCount();Reads allocated record count, also InstanceCount. Not visible-object count.
intNonnegative allocated capacity.
GetInstanceCustomDataColor
public Color GetInstanceCustomData(int instance);Reads four custom floats through Color with UseCustomData = true. Shader defines their meaning; dummy returns default.
| Name | Type | Default |
|---|---|---|
instance | int | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
ColorFour floats through Color; dummy returns default.
GetInstanceTransformTransform3D
public Transform3D GetInstanceTransform(int instance);Reads a 3D-format record local Transform3D rather than an Entity global transform. Dummy returns identity regardless of scalar setter.
| Name | Type | Default |
|---|---|---|
instance | int | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
Transform3DLocal Transform3D; identity in dummy/on diagnostics.
GetInstanceTransform2DTransform2D
public Transform2D GetInstanceTransform2D(int instance);Reads a 2D-format record local Transform2D. Use the other method for 3D; dummy returns identity.
| Name | Type | Default |
|---|---|---|
instance | int | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
Transform2DLocal Transform2D; identity in dummy/on diagnostics.
GetMeshMesh
public Mesh GetMesh();Returns the shared source Mesh reference or null rather than MeshInstance3D or copied geometry.
MeshShared Mesh or null rather than a separate copy to Dispose early.
GetPhysicsInterpolationQualityMultiMesh.PhysicsInterpolationQualityEnum
public MultiMesh.PhysicsInterpolationQualityEnum GetPhysicsInterpolationQuality();Reads selected Fast/High, not whether interpolation is enabled or current physics FPS.
MultiMesh.PhysicsInterpolationQualityEnumStored Fast/High enum.
GetTransformFormatMultiMesh.TransformFormatEnum
public MultiMesh.TransformFormatEnum GetTransformFormat();Reads the 2D/3D format configured before record allocation.
MultiMesh.TransformFormatEnumStored 2D/3D enum.
GetVisibleInstanceCountint
public int GetVisibleInstanceCount();Reads prefix limit: -1 all, 0 none, N first N. A setting rather than an actual visible-pixel count.
intPrefix setting, -1 for all.
IsUsingColorsbool
public bool IsUsingColors();Reads color-channel configuration rather than whether material uses that color.
booltrue when the color channel is enabled.
IsUsingCustomDatabool
public bool IsUsingCustomData();Reads custom-channel configuration rather than whether shader logic consumes it.
booltrue when the custom channel is enabled.
ResetInstancePhysicsInterpolationvoid
public void ResetInstancePhysicsInterpolation(int instance);With active interpolation, copies one current record to previous. Call after writing teleport placement to avoid blending from the old location. Dummy has no interpolator.
| Name | Type | Default |
|---|---|---|
instance | int | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
ResetInstancesPhysicsInterpolationvoid
public void ResetInstancesPhysicsInterpolation();Resets every previous record to current. Does not move objects or enable interpolation; requires an interpolator.
SetBuffer2 overloads
public void SetBuffer(ReadOnlySpan<float> buffer);Uploads a full float buffer of exact length. Array/span overloads share layout. Ignored at count 0; wrong lengths with positive count are rejected. Does not emit Changed.
| Name | Type | Default |
|---|---|---|
buffer | ReadOnlySpan<float> | — |
bufferFull float[]/span of exact stride × InstanceCount length; row layout is described in the introduction.
public void SetBuffer(float[] buffer);Uploads a full float buffer of exact length. Array/span overloads share layout. Ignored at count 0; wrong lengths with positive count are rejected. Does not emit Changed.
| Name | Type | Default |
|---|---|---|
buffer | float[] | — |
bufferFull float[]/span of exact stride × InstanceCount length; row layout is described in the introduction.
SetBufferInterpolated2 overloads
public void SetBufferInterpolated(ReadOnlySpan<float> bufferCurr, ReadOnlySpan<float> bufferPrev);Supplies current and previous matching-layout data for physics interpolation rather than two render draw calls. Requires a renderer interpolator; dummy does nothing. Does not replace enabling consumer interpolation.
| Name | Type | Default |
|---|---|---|
bufferCurr | ReadOnlySpan<float> | — |
bufferPrev | ReadOnlySpan<float> | — |
bufferCurrFull-size current physics buffer with the same layout/count as previous.
bufferPrevFull-size previous physics buffer rather than velocity/delta or another instance set.
public void SetBufferInterpolated(float[] bufferCurr, float[] bufferPrev);Supplies current and previous matching-layout data for physics interpolation rather than two render draw calls. Requires a renderer interpolator; dummy does nothing. Does not replace enabling consumer interpolation.
| Name | Type | Default |
|---|---|---|
bufferCurr | float[] | — |
bufferPrev | float[] | — |
bufferCurrFull-size current physics buffer with the same layout/count as previous.
bufferPrevFull-size previous physics buffer rather than velocity/delta or another instance set.
SetCustomAabbvoid
public void SetCustomAabb(Aabb aabb);Sets group CustomAabb and emits Changed. Enclose every local instance and shader deformation; unconverted world-space bounds are wrong here.
| Name | Type | Default |
|---|---|---|
aabb | Aabb | — |
aabbLocal bounds of the entire group; zero Aabb disables renderer override.
SetInstanceColorvoid
public void SetInstanceColor(int instance, Color color);Writes one index color with UseColors = true. Material must use instance/vertex color; no Changed notification. Dummy does not store this write.
| Name | Type | Default |
|---|---|---|
instance | int | — |
color | Color | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
colorInstance color used only with the channel enabled and a suitable material.
SetInstanceCountvoid
public void SetInstanceCount(int count);Allocates a nonnegative count using the selected layout. Refill required data and check VisibleInstanceCount after changing it.
| Name | Type | Default |
|---|---|---|
count | int | — |
countNonnegative record count to allocate.
SetInstanceCustomDatavoid
public void SetInstanceCustomData(int instance, Color customData);Writes four custom floats for one index with its channel enabled. Color carries shader INSTANCE_CUSTOM data; no Changed notification.
| Name | Type | Default |
|---|---|---|
instance | int | — |
customData | Color | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
customDataFour finite floats in Color RGBA fields; shader defines their meaning, not necessarily color.
SetInstanceTransformvoid
public void SetInstanceTransform(int instance, Transform3D transform);Writes local Transform3D for 3D format and a valid index. Does not create an Entity/collision. No Changed notification; dummy does not store it.
| Name | Type | Default |
|---|---|---|
instance | int | — |
transform | Transform3D | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
transformLocal finite Transform3D for 3D layout.
SetInstanceTransform2Dvoid
public void SetInstanceTransform2D(int instance, Transform2D transform);Writes local Transform2D for 2D format. Unlike the 3D setter, emits Changed. Dummy notifies without storing the transform.
| Name | Type | Default |
|---|---|---|
instance | int | — |
transform | Transform2D | — |
instanceRecord index from 0 to InstanceCount-1 rather than Entity ID or visible surface number.
transformLocal finite Transform2D for 2D layout.
SetMeshvoid
public void SetMesh(Mesh mesh);Assigns shared Mesh or null without copying geometry. Assign MultiMesh itself to a display consumer too.
| Name | Type | Default |
|---|---|---|
mesh | Mesh | — |
meshShared Mesh or null. Keep the resource alive while the group uses it.
SetPhysicsInterpolationQualityvoid
public void SetPhysicsInterpolationQuality(MultiMesh.PhysicsInterpolationQualityEnum quality);Selects Fast/High interpolation method. Does not enable it or establish smooth output; headless checks only stored selection.
| Name | Type | Default |
|---|---|---|
quality | MultiMesh.PhysicsInterpolationQualityEnum | — |
qualityFast or High, without automatically enabling interpolation.
SetTransformFormatvoid
public void SetTransformFormat(MultiMesh.TransformFormatEnum format);Sets 2D/3D only with InstanceCount = 0. Even writing the same value with positive count is rejected.
| Name | Type | Default |
|---|---|---|
format | MultiMesh.TransformFormatEnum | — |
formatTransform2D or Transform3D with InstanceCount = 0.
SetUseColorsvoid
public void SetUseColors(bool enable);Enables the color channel only with InstanceCount = 0. Configure material separately.
| Name | Type | Default |
|---|---|---|
enable | bool | — |
enableEnable/disable the corresponding channel with InstanceCount = 0.
SetUseCustomDatavoid
public void SetUseCustomData(bool enable);Enables four custom floats per record only with InstanceCount = 0. Shader consumption is separate.
| Name | Type | Default |
|---|---|---|
enable | bool | — |
enableEnable/disable the corresponding channel with InstanceCount = 0.
SetVisibleInstanceCountvoid
public void SetVisibleInstanceCount(int count);Sets visible prefix: -1 or 0…InstanceCount. Does not change capacity or reorder records.
| Name | Type | Default |
|---|---|---|
count | int | — |
count-1 for all or 0…InstanceCount for the visible prefix.
MultiMesh.PhysicsInterpolationQualityEnum
MultiMesh.TransformFormatEnum
| Value | Description |
|---|---|
Transform2D = 0 | Use this when using 2D transforms. |
Transform3D = 1 | Use this when using 3D transforms. |