Search Unity

Mesh Combiner script spamming my console with error message...

Discussion in 'Scripting' started by AndrewGrayGames, May 25, 2015.

  1. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    In my current game project, I build my levels out of a bunch of 3D tiles. Here's a (older) visual of what I'm doing:



    The script that I'm using to accomplish this is:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System;
    4.  
    5. public class MeshCombiner : DebuggableBehavior
    6. {
    7.     #region Variables / Properties
    8.  
    9.     public MeshFilter[] meshFilters;
    10.     public Material material;
    11.  
    12.     #endregion Variables / Properties
    13.  
    14.     #region Hooks
    15.  
    16.     public void Start()
    17.     {
    18.        // if not specified, go find meshes
    19.        if(meshFilters.Length == 0)
    20.        {
    21.             // find all the mesh filters
    22.             Component[] comps = GetComponentsInChildren(typeof(MeshFilter));
    23.             meshFilters = new MeshFilter[comps.Length];
    24.            
    25.             int filterIndex = 0;
    26.             foreach(Component comp in comps)
    27.                 meshFilters[filterIndex++] = (MeshFilter) comp;
    28.        }
    29.      
    30.        // figure out array sizes
    31.        int vertCount = 0;
    32.        int normCount = 0;
    33.        int triCount = 0;
    34.        int uvCount = 0;
    35.      
    36.        foreach(MeshFilter filter in meshFilters)
    37.        {
    38.             vertCount += filter.mesh.vertices.Length;
    39.             normCount += filter.mesh.normals.Length;
    40.             triCount += filter.mesh.triangles.Length;
    41.             uvCount += filter.mesh.uv.Length;
    42.          
    43.             Material mat = null;
    44.             try
    45.             {
    46.                 mat = filter.gameObject.renderer.material;
    47.             }
    48.             catch (MissingComponentException)
    49.             {
    50.                 continue;
    51.             }  
    52.             catch (Exception ex)
    53.             {
    54.                 DebugMessage("Unhandled Exception has occurred! \r\n"
    55.                              + ex.Message + "\r\n"
    56.                              + ex.StackTrace);
    57.             }
    58.            
    59.             if((material == null) && (mat != null))
    60.               material = mat;
    61.        }
    62.      
    63.        // allocate arrays
    64.        Vector3[] verts = new Vector3[vertCount];
    65.        Vector3[] norms = new Vector3[normCount];
    66.        Transform[] aBones = new Transform[meshFilters.Length];
    67.        Matrix4x4[] bindPoses = new Matrix4x4[meshFilters.Length];
    68.        BoneWeight[] weights = new BoneWeight[vertCount];
    69.        int[] tris  = new int[triCount];
    70.        Vector2[] uvs = new Vector2[uvCount];
    71.      
    72.        int vertOffset = 0;
    73.        int normOffset = 0;
    74.        int triOffset = 0;
    75.        int uvOffset = 0;
    76.        int meshOffset = 0;
    77.      
    78.        // merge the meshes and set up bones
    79.        foreach(MeshFilter filter in meshFilters)
    80.        {    
    81.             foreach(int i in filter.mesh.triangles)
    82.                 tris[triOffset++] = i + vertOffset;
    83.            
    84.             aBones[meshOffset] = filter.transform;
    85.             bindPoses[meshOffset] = Matrix4x4.identity;
    86.            
    87.             foreach(Vector3 v in filter.mesh.vertices)
    88.             {
    89.                 weights[vertOffset].weight0 = 1.0f;
    90.                 weights[vertOffset].boneIndex0 = meshOffset;
    91.                 verts[vertOffset++] = v;
    92.             }
    93.            
    94.             foreach(Vector3 n in filter.mesh.normals)
    95.                 norms[normOffset++] = n;
    96.            
    97.             foreach(Vector2 uv in filter.mesh.uv)
    98.                 uvs[uvOffset++] = uv;
    99.            
    100.             meshOffset++;
    101.            
    102.             MeshRenderer meshRenderer = filter.gameObject.GetComponent(typeof(MeshRenderer)) as MeshRenderer;
    103.             if(meshRenderer)
    104.                 meshRenderer.enabled = false;
    105.        }
    106.      
    107.        // hook up the mesh
    108.        Mesh me = new Mesh();      
    109.        me.name = gameObject.name;
    110.        me.vertices = verts;
    111.        me.normals = norms;
    112.        me.boneWeights = weights;
    113.        me.uv = uvs;
    114.        me.triangles = tris;
    115.        me.bindposes = bindPoses;
    116.      
    117.        // hook up the mesh renderer        
    118.        SkinnedMeshRenderer smr = gameObject.AddComponent(typeof(SkinnedMeshRenderer)) as SkinnedMeshRenderer;
    119.        smr.sharedMesh = me;
    120.        smr.bones = aBones;
    121.  
    122.         renderer.material = material;
    123.     }
    124.    
    125.     public void OnDestroy()
    126.     {
    127.         SkinnedMeshRenderer smr = GetComponent<SkinnedMeshRenderer>();
    128.         if(smr == null)
    129.             return;
    130.        
    131.         smr.material.mainTexture = null;
    132.         smr.material = null;
    133.         smr.bones = null;
    134.         smr.sharedMesh = null;
    135.  
    136.         meshFilters = null;
    137.  
    138.         GameObject.Destroy(smr);
    139.     }
    140.  
    141.     #endregion Hooks
    142. }

    I got this script from the Wiki a couple of years back, and have been modifying it a very little bit for organization. What it does is on Start, it crawls all children and adds their mesh vertices and normals to a super-mesh, then spins off a "SkinnedMeshRenderer" which renders the super mesh with the given texture; this more or less takes a bunch of objects and instead compacts them into one large object, which helps Unity perform better as it causes fewer draw calls.

    One "small" problem - actually using this script spams my console with the error message: "SkinnedMeshRenderer requires a mesh with skinning or blendshape information." Just a couple of seconds produces a few hundred instances of this error.

    What can I do to remove this spammy message? My 3D tiles don't need a bone, and even if they did, the mesh script here should be generating bones for each mesh filter that gets batched together.
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    If you don't use animation there's no reason to use a skinned mesh renderer. Use a standard mesh renderer instead, and remove the skinning info (boneweights etc.).

    --Eric