コード例 #1
0
        public virtual void LateUpdate()
        {
            if (!valid)
            {
                return;
            }

            if (
                (!meshRenderer.enabled)
                                #if SPINE_OPTIONAL_RENDEROVERRIDE
                && this.generateMeshOverride == null
                                #endif
                )
            {
                return;
            }


            // STEP 1. Determine a SmartMesh.Instruction. Split up instructions into submeshes. ============================================================
            ExposedList <Slot> drawOrder = skeleton.drawOrder;
            var  drawOrderItems          = drawOrder.Items;
            int  drawOrderCount          = drawOrder.Count;
            bool renderMeshes            = this.renderMeshes;

            // Clear last state of attachments and submeshes
            var workingInstruction = this.currentInstructions;
            var workingAttachments = workingInstruction.attachments;
            workingAttachments.Clear(false);
            workingAttachments.GrowIfNeeded(drawOrderCount);
            workingAttachments.Count = drawOrderCount;
            var workingAttachmentsItems = workingInstruction.attachments.Items;

            var workingSubmeshInstructions = workingInstruction.submeshInstructions;                    // Items array should not be cached. There is dynamic writing to this list.
            workingSubmeshInstructions.Clear(false);

                        #if !SPINE_TK2D
            bool isCustomSlotMaterialsPopulated = customSlotMaterials.Count > 0;
                        #endif

            bool     hasSeparators = separatorSlots.Count > 0;
            int      vertexCount = 0;
            int      submeshVertexCount = 0;
            int      submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
            Material lastMaterial = null;
            for (int i = 0; i < drawOrderCount; i++)
            {
                Slot       slot       = drawOrderItems[i];
                Attachment attachment = slot.attachment;
                workingAttachmentsItems[i] = attachment;

                object rendererObject = null;                 // An AtlasRegion in plain Spine-Unity. Spine-TK2D hooks into TK2D's system. eventual source of Material object.
                int    attachmentVertexCount, attachmentTriangleCount;
                bool   noRender = false;

                var regionAttachment = attachment as RegionAttachment;
                if (regionAttachment != null)
                {
                    rendererObject          = regionAttachment.RendererObject;
                    attachmentVertexCount   = 4;
                    attachmentTriangleCount = 6;
                }
                else
                {
                    if (!renderMeshes)
                    {
                        noRender = true;
                        attachmentVertexCount   = 0;
                        attachmentTriangleCount = 0;
                        //continue;
                    }
                    else
                    {
                        var meshAttachment = attachment as MeshAttachment;
                        if (meshAttachment != null)
                        {
                            rendererObject          = meshAttachment.RendererObject;
                            attachmentVertexCount   = meshAttachment.worldVerticesLength >> 1;
                            attachmentTriangleCount = meshAttachment.triangles.Length;
                        }
                        else
                        {
                            noRender = true;
                            attachmentVertexCount   = 0;
                            attachmentTriangleCount = 0;
                            //continue;
                        }
                    }
                }

                // Create a new SubmeshInstruction when material changes. (or when forced to separate by a submeshSeparator)
                // Slot with a separator/new material will become the starting slot of the next new instruction.
                bool forceSeparate = (hasSeparators && separatorSlots.Contains(slot));
                if (noRender)
                {
                    if (forceSeparate && vertexCount > 0
                                                #if SPINE_OPTIONAL_RENDEROVERRIDE
                        && this.generateMeshOverride != null
                                                #endif
                        )
                    {
                        workingSubmeshInstructions.Add(
                            new Spine.Unity.MeshGeneration.SubmeshInstruction {
                            skeleton         = this.skeleton,
                            material         = lastMaterial,
                            startSlot        = submeshStartSlotIndex,
                            endSlot          = i,
                            triangleCount    = submeshTriangleCount,
                            firstVertexIndex = submeshFirstVertex,
                            vertexCount      = submeshVertexCount,
                            forceSeparate    = forceSeparate
                        }
                            );
                        submeshTriangleCount  = 0;
                        submeshVertexCount    = 0;
                        submeshFirstVertex    = vertexCount;
                        submeshStartSlotIndex = i;
                    }
                }
                else
                {
                                        #if !SPINE_TK2D
                    Material material;
                    if (isCustomSlotMaterialsPopulated)
                    {
                        if (!customSlotMaterials.TryGetValue(slot, out material))
                        {
                            material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                        }
                    }
                    else
                    {
                        material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                    }
                                        #else
                    Material material = (rendererObject.GetType() == typeof(Material)) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject;
                                        #endif

                    if (vertexCount > 0 && (forceSeparate || lastMaterial.GetInstanceID() != material.GetInstanceID()))
                    {
                        workingSubmeshInstructions.Add(
                            new Spine.Unity.MeshGeneration.SubmeshInstruction {
                            skeleton         = this.skeleton,
                            material         = lastMaterial,
                            startSlot        = submeshStartSlotIndex,
                            endSlot          = i,
                            triangleCount    = submeshTriangleCount,
                            firstVertexIndex = submeshFirstVertex,
                            vertexCount      = submeshVertexCount,
                            forceSeparate    = forceSeparate
                        }
                            );
                        submeshTriangleCount  = 0;
                        submeshVertexCount    = 0;
                        submeshFirstVertex    = vertexCount;
                        submeshStartSlotIndex = i;
                    }
                    // Update state for the next iteration.
                    lastMaterial          = material;
                    submeshTriangleCount += attachmentTriangleCount;
                    vertexCount          += attachmentVertexCount;
                    submeshVertexCount   += attachmentVertexCount;
                }
            }

            if (submeshVertexCount != 0)
            {
                workingSubmeshInstructions.Add(
                    new Spine.Unity.MeshGeneration.SubmeshInstruction {
                    skeleton         = this.skeleton,
                    material         = lastMaterial,
                    startSlot        = submeshStartSlotIndex,
                    endSlot          = drawOrderCount,
                    triangleCount    = submeshTriangleCount,
                    firstVertexIndex = submeshFirstVertex,
                    vertexCount      = submeshVertexCount,
                    forceSeparate    = false
                }
                    );
            }

            workingInstruction.vertexCount        = vertexCount;
            workingInstruction.immutableTriangles = this.immutableTriangles;


            // STEP 1.9. Post-process workingInstructions. ============================================================

                        #if SPINE_OPTIONAL_MATERIALOVERRIDE
            // Material overrides are done here so they can be applied per submesh instead of per slot
            // but they will still be passed through the GenerateMeshOverride delegate,
            // and will still go through the normal material match check step in STEP 3.
            if (customMaterialOverride.Count > 0)               // isCustomMaterialOverridePopulated
            {
                var workingSubmeshInstructionsItems = workingSubmeshInstructions.Items;
                for (int i = 0; i < workingSubmeshInstructions.Count; i++)
                {
                    var      m = workingSubmeshInstructionsItems[i].material;
                    Material mo;
                    if (customMaterialOverride.TryGetValue(m, out mo))
                    {
                        workingSubmeshInstructionsItems[i].material = mo;
                    }
                }
            }
                        #endif
                        #if SPINE_OPTIONAL_RENDEROVERRIDE
            if (this.generateMeshOverride != null)
            {
                this.generateMeshOverride(workingInstruction);
                if (disableRenderingOnOverride)
                {
                    return;
                }
            }
                        #endif


            // STEP 2. Update vertex buffer based on verts from the attachments.  ============================================================
            // Uses values that were also stored in workingInstruction.
            if (tintBlack)
            {
                ArraysMeshGenerator.EnsureSize(vertexCount, ref this.uv2);
                ArraysMeshGenerator.EnsureSize(vertexCount, ref this.uv3);
            }

                        #if SPINE_OPTIONAL_NORMALS
            bool vertexCountIncreased = ArraysMeshGenerator.EnsureSize(vertexCount, ref this.vertices, ref this.uvs, ref this.colors);
            if (vertexCountIncreased && calculateNormals)
            {
                Vector3[] localNormals = this.normals = new Vector3[vertexCount];
                Vector3   normal       = new Vector3(0, 0, -1);
                for (int i = 0; i < vertexCount; i++)
                {
                    localNormals[i] = normal;
                }
            }
                        #else
            ArraysMeshGenerator.EnsureSize(vertexCount, ref this.vertices, ref this.uvs, ref this.colors);
                        #endif

            Vector3 meshBoundsMin;
            Vector3 meshBoundsMax;
            if (vertexCount <= 0)
            {
                meshBoundsMin = new Vector3(0, 0, 0);
                meshBoundsMax = new Vector3(0, 0, 0);
            }
            else
            {
                meshBoundsMin.x = int.MaxValue;
                meshBoundsMin.y = int.MaxValue;
                meshBoundsMax.x = int.MinValue;
                meshBoundsMax.y = int.MinValue;

                if (zSpacing > 0f)
                {
                    meshBoundsMin.z = 0f;
                    meshBoundsMax.z = zSpacing * (drawOrderCount - 1);
                }
                else
                {
                    meshBoundsMin.z = zSpacing * (drawOrderCount - 1);
                    meshBoundsMax.z = 0f;
                }
            }
            int vertexIndex = 0;

            if (tintBlack)
            {
                ArraysMeshGenerator.FillBlackUVs(skeleton, 0, drawOrderCount, this.uv2, this.uv3, vertexIndex, renderMeshes);                 // This needs to be called before FillVerts so we have the correct vertexIndex argument.
            }
            ArraysMeshGenerator.FillVerts(skeleton, 0, drawOrderCount, this.zSpacing, pmaVertexColors, this.vertices, this.uvs, this.colors, ref vertexIndex, ref tempVertices, ref meshBoundsMin, ref meshBoundsMax, renderMeshes);



            // Step 3. Move the mesh data into a UnityEngine.Mesh ============================================================
            var currentSmartMesh = doubleBufferedMesh.GetNext();                // Double-buffer for performance.
            var currentMesh      = currentSmartMesh.mesh;
            currentMesh.vertices = this.vertices;
            currentMesh.colors32 = colors;
            currentMesh.uv       = uvs;
            currentMesh.bounds   = ArraysMeshGenerator.ToBounds(meshBoundsMin, meshBoundsMax);

            if (tintBlack)
            {
                currentMesh.uv2 = this.uv2;
                currentMesh.uv3 = this.uv3;
            }

            var currentSmartMeshInstructionUsed = currentSmartMesh.instructionUsed;
                        #if SPINE_OPTIONAL_NORMALS
            if (calculateNormals && currentSmartMeshInstructionUsed.vertexCount < vertexCount)
            {
                currentMesh.normals = normals;
            }
                        #endif

            // Check if the triangles should also be updated.
            // This thorough structure check is cheaper than updating triangles every frame.
            bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(workingInstruction, currentSmartMeshInstructionUsed);
            int  submeshCount            = workingSubmeshInstructions.Count;
            if (mustUpdateMeshStructure)
            {
                var thisSubmeshMaterials = this.submeshMaterials;
                thisSubmeshMaterials.Clear(false);

                int oldSubmeshCount = submeshes.Count;

                if (submeshes.Capacity < submeshCount)
                {
                    submeshes.Capacity = submeshCount;
                }
                for (int i = oldSubmeshCount; i < submeshCount; i++)
                {
                    submeshes.Items[i] = new ArraysMeshGenerator.SubmeshTriangleBuffer(workingSubmeshInstructions.Items[i].triangleCount);
                }
                submeshes.Count = submeshCount;

                var mutableTriangles = !workingInstruction.immutableTriangles;
                for (int i = 0, last = submeshCount - 1; i < submeshCount; i++)
                {
                    var submeshInstruction = workingSubmeshInstructions.Items[i];

                    if (mutableTriangles || i >= oldSubmeshCount)
                    {
                        var currentSubmesh           = submeshes.Items[i];
                        int instructionTriangleCount = submeshInstruction.triangleCount;
                        if (renderMeshes)
                        {
                            ArraysMeshGenerator.FillTriangles(ref currentSubmesh.triangles, skeleton, instructionTriangleCount, submeshInstruction.firstVertexIndex, submeshInstruction.startSlot, submeshInstruction.endSlot, (i == last));
                            currentSubmesh.triangleCount = instructionTriangleCount;
                        }
                        else
                        {
                            ArraysMeshGenerator.FillTrianglesQuads(ref currentSubmesh.triangles, ref currentSubmesh.triangleCount, ref currentSubmesh.firstVertex, submeshInstruction.firstVertexIndex, instructionTriangleCount, (i == last));
                        }
                    }

                    thisSubmeshMaterials.Add(submeshInstruction.material);
                }

                currentMesh.subMeshCount = submeshCount;

                for (int i = 0; i < submeshCount; ++i)
                {
                    currentMesh.SetTriangles(submeshes.Items[i].triangles, i);
                }
            }

                        #if SPINE_OPTIONAL_SOLVETANGENTS
            if (calculateTangents)
            {
                ArraysMeshGenerator.SolveTangents2DEnsureSize(ref this.tangents, ref this.tempTanBuffer, vertices.Length);
                for (int i = 0; i < submeshCount; i++)
                {
                    var submesh = submeshes.Items[i];
                    ArraysMeshGenerator.SolveTangents2DTriangles(this.tempTanBuffer, submesh.triangles, submesh.triangleCount, this.vertices, this.uvs, vertexCount);
                }
                ArraysMeshGenerator.SolveTangents2DBuffer(this.tangents, this.tempTanBuffer, vertexCount);
                currentMesh.tangents = this.tangents;
            }
                        #endif

            // CheckIfMustUpdateMaterialArray (last pushed materials vs currently parsed materials)
            // Needs to check against the Working Submesh Instructions Materials instead of the cached submeshMaterials.
            {
                var  lastPushedMaterials         = this.sharedMaterials;
                bool mustUpdateRendererMaterials = mustUpdateMeshStructure ||
                                                   (lastPushedMaterials.Length != submeshCount);

                // Assumption at this point: (lastPushedMaterials.Count == workingSubmeshInstructions.Count == thisSubmeshMaterials.Count == submeshCount)

                // Case: mesh structure or submesh count did not change but materials changed.
                if (!mustUpdateRendererMaterials)
                {
                    var workingSubmeshInstructionsItems = workingSubmeshInstructions.Items;
                    for (int i = 0; i < submeshCount; i++)
                    {
                        if (lastPushedMaterials[i].GetInstanceID() != workingSubmeshInstructionsItems[i].material.GetInstanceID())                             // Bounds check is implied by submeshCount above.
                        {
                            mustUpdateRendererMaterials = true;
                            {
                                var thisSubmeshMaterials = this.submeshMaterials.Items;
                                if (mustUpdateRendererMaterials)
                                {
                                    for (int j = 0; j < submeshCount; j++)
                                    {
                                        thisSubmeshMaterials[j] = workingSubmeshInstructionsItems[j].material;
                                    }
                                }
                            }
                            break;
                        }
                    }
                }

                if (mustUpdateRendererMaterials)
                {
                    if (submeshMaterials.Count == sharedMaterials.Length)
                    {
                        submeshMaterials.CopyTo(sharedMaterials);
                    }
                    else
                    {
                        sharedMaterials = submeshMaterials.ToArray();
                    }

                    meshRenderer.sharedMaterials = sharedMaterials;
                }
            }


            // Step 4. The UnityEngine.Mesh is ready. Set it as the MeshFilter's mesh. Store the instructions used for that mesh. ============================================================
            meshFilter.sharedMesh = currentMesh;
            currentSmartMesh.instructionUsed.Set(workingInstruction);
        }
コード例 #2
0
ファイル: SkeletonRenderer.cs プロジェクト: mrdivdiz/bpvita
        public virtual void LateUpdate()
        {
            if (!valid || (!meshRenderer.enabled && this.generateMeshOverride == null))
            {
                return;
            }
            ExposedList <Slot> drawOrder = skeleton.drawOrder;

            Slot[] items = drawOrder.Items;
            int    count = drawOrder.Count;
            bool   flag  = renderMeshes;

            SmartMesh.Instruction    instruction = currentInstructions;
            ExposedList <Attachment> attachments = instruction.attachments;

            attachments.Clear(clearArray: false);
            attachments.GrowIfNeeded(count);
            attachments.Count = count;
            Attachment[] items2 = instruction.attachments.Items;
            ExposedList <SubmeshInstruction> submeshInstructions = instruction.submeshInstructions;

            submeshInstructions.Clear(clearArray: false);
            bool     flag2            = customSlotMaterials.Count > 0;
            int      num              = 0;
            int      num2             = 0;
            int      num3             = 0;
            int      firstVertexIndex = 0;
            int      startSlot        = 0;
            Material material         = null;

            for (int i = 0; i < count; i++)
            {
                Slot             slot             = items[i];
                Attachment       attachment       = items2[i] = slot.attachment;
                RegionAttachment regionAttachment = attachment as RegionAttachment;
                object           rendererObject;
                int num4;
                int num5;
                if (regionAttachment != null)
                {
                    rendererObject = regionAttachment.RendererObject;
                    num4           = 4;
                    num5           = 6;
                }
                else
                {
                    if (!flag)
                    {
                        continue;
                    }
                    MeshAttachment meshAttachment = attachment as MeshAttachment;
                    if (meshAttachment == null)
                    {
                        continue;
                    }
                    rendererObject = meshAttachment.RendererObject;
                    num4           = meshAttachment.worldVerticesLength >> 1;
                    num5           = meshAttachment.triangles.Length;
                }
                Material value;
                if (flag2)
                {
                    if (!customSlotMaterials.TryGetValue(slot, out value))
                    {
                        value = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                    }
                }
                else
                {
                    value = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                }
                bool flag3 = separatorSlots.Count > 0 && separatorSlots.Contains(slot);
                if (num > 0 && (material.GetInstanceID() != value.GetInstanceID() || flag3))
                {
                    submeshInstructions.Add(new SubmeshInstruction
                    {
                        skeleton         = skeleton,
                        material         = material,
                        startSlot        = startSlot,
                        endSlot          = i,
                        triangleCount    = num3,
                        firstVertexIndex = firstVertexIndex,
                        vertexCount      = num2,
                        forceSeparate    = flag3
                    });
                    num3             = 0;
                    num2             = 0;
                    firstVertexIndex = num;
                    startSlot        = i;
                }
                material = value;
                num3    += num5;
                num     += num4;
                num2    += num4;
            }
            if (num2 != 0)
            {
                submeshInstructions.Add(new SubmeshInstruction
                {
                    skeleton         = skeleton,
                    material         = material,
                    startSlot        = startSlot,
                    endSlot          = count,
                    triangleCount    = num3,
                    firstVertexIndex = firstVertexIndex,
                    vertexCount      = num2,
                    forceSeparate    = false
                });
            }
            instruction.vertexCount        = num;
            instruction.immutableTriangles = immutableTriangles;
            if (customMaterialOverride.Count > 0)
            {
                SubmeshInstruction[] items3 = submeshInstructions.Items;
                for (int j = 0; j < submeshInstructions.Count; j++)
                {
                    Material material2 = items3[j].material;
                    Material value2;
                    if (customMaterialOverride.TryGetValue(material2, out value2))
                    {
                        items3[j].material = value2;
                    }
                }
            }
            if (this.generateMeshOverride != null)
            {
                this.generateMeshOverride(instruction);
                if (disableRenderingOnOverride)
                {
                    return;
                }
            }
            if (ArraysMeshGenerator.EnsureSize(num, ref vertices, ref uvs, ref colors) && calculateNormals)
            {
                Vector3[] array  = normals = new Vector3[num];
                Vector3   vector = new Vector3(0f, 0f, -1f);
                for (int k = 0; k < num; k++)
                {
                    array[k] = vector;
                }
            }
            Vector3 boundsMin = default(Vector3);
            Vector3 boundsMax = default(Vector3);

            if (num <= 0)
            {
                boundsMin = new Vector3(0f, 0f, 0f);
                boundsMax = new Vector3(0f, 0f, 0f);
            }
            else
            {
                boundsMin.x = 2.14748365E+09f;
                boundsMin.y = 2.14748365E+09f;
                boundsMax.x = -2.14748365E+09f;
                boundsMax.y = -2.14748365E+09f;
                if (zSpacing > 0f)
                {
                    boundsMin.z = 0f;
                    boundsMax.z = zSpacing * (float)(count - 1);
                }
                else
                {
                    boundsMin.z = zSpacing * (float)(count - 1);
                    boundsMax.z = 0f;
                }
            }
            int vertexIndex = 0;

            ArraysMeshGenerator.FillVerts(skeleton, 0, count, zSpacing, pmaVertexColors, vertices, uvs, colors, ref vertexIndex, ref tempVertices, ref boundsMin, ref boundsMax, flag);
            SmartMesh next = doubleBufferedMesh.GetNext();
            Mesh      mesh = next.mesh;

            mesh.vertices = vertices;
            mesh.colors32 = colors;
            mesh.uv       = uvs;
            mesh.bounds   = ArraysMeshGenerator.ToBounds(boundsMin, boundsMax);
            SmartMesh.Instruction instructionUsed = next.instructionUsed;
            if (calculateNormals && instructionUsed.vertexCount < num)
            {
                mesh.normals = normals;
            }
            bool flag4  = CheckIfMustUpdateMeshStructure(instruction, instructionUsed);
            int  count2 = submeshInstructions.Count;

            if (flag4)
            {
                ExposedList <Material> exposedList = submeshMaterials;
                exposedList.Clear(clearArray: false);
                int count3 = submeshes.Count;
                if (submeshes.Capacity < count2)
                {
                    submeshes.Capacity = count2;
                }
                for (int l = count3; l < count2; l++)
                {
                    submeshes.Items[l] = new ArraysMeshGenerator.SubmeshTriangleBuffer(submeshInstructions.Items[l].triangleCount);
                }
                submeshes.Count = count2;
                bool flag5 = !instruction.immutableTriangles;
                int  m     = 0;
                int  num6  = count2 - 1;
                for (; m < count2; m++)
                {
                    SubmeshInstruction submeshInstruction = submeshInstructions.Items[m];
                    if (flag5 || m >= count3)
                    {
                        ArraysMeshGenerator.SubmeshTriangleBuffer submeshTriangleBuffer = submeshes.Items[m];
                        int triangleCount = submeshInstruction.triangleCount;
                        if (flag)
                        {
                            ArraysMeshGenerator.FillTriangles(ref submeshTriangleBuffer.triangles, skeleton, triangleCount, submeshInstruction.firstVertexIndex, submeshInstruction.startSlot, submeshInstruction.endSlot, m == num6);
                            submeshTriangleBuffer.triangleCount = triangleCount;
                        }
                        else
                        {
                            ArraysMeshGenerator.FillTrianglesQuads(ref submeshTriangleBuffer.triangles, ref submeshTriangleBuffer.triangleCount, ref submeshTriangleBuffer.firstVertex, submeshInstruction.firstVertexIndex, triangleCount, m == num6);
                        }
                    }
                    exposedList.Add(submeshInstruction.material);
                }
                mesh.subMeshCount = count2;
                for (int n = 0; n < count2; n++)
                {
                    mesh.SetTriangles(submeshes.Items[n].triangles, n);
                }
            }
            if (calculateTangents)
            {
                ArraysMeshGenerator.SolveTangents2DEnsureSize(ref tangents, ref tempTanBuffer, vertices.Length);
                for (int num7 = 0; num7 < count2; num7++)
                {
                    ArraysMeshGenerator.SubmeshTriangleBuffer submeshTriangleBuffer2 = submeshes.Items[num7];
                    ArraysMeshGenerator.SolveTangents2DTriangles(tempTanBuffer, submeshTriangleBuffer2.triangles, submeshTriangleBuffer2.triangleCount, vertices, uvs, num);
                }
                ArraysMeshGenerator.SolveTangents2DBuffer(tangents, tempTanBuffer, num);
                mesh.tangents = tangents;
            }
            Material[] array2 = sharedMaterials;
            bool       flag6  = flag4 || array2.Length != count2;

            if (!flag6)
            {
                SubmeshInstruction[] items4 = submeshInstructions.Items;
                int num8 = 0;
                for (int num9 = array2.Length; num8 < num9; num8++)
                {
                    if (array2[num8].GetInstanceID() != items4[num8].material.GetInstanceID())
                    {
                        flag6 = true;
                        break;
                    }
                }
            }
            if (flag6)
            {
                if (submeshMaterials.Count == sharedMaterials.Length)
                {
                    submeshMaterials.CopyTo(sharedMaterials);
                }
                else
                {
                    sharedMaterials = submeshMaterials.ToArray();
                }
                meshRenderer.sharedMaterials = sharedMaterials;
            }
            meshFilter.sharedMesh = mesh;
            next.instructionUsed.Set(instruction);
        }