Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[SOLVED-C# AND JS Answer]Trying to Combine Meshes Selected In Editor

Discussion in 'Scripting' started by keenanwoodall, Jul 15, 2014.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    So if i have objects selected, and I press a button, I want the selected objects to combine. I've been working at it for a while, haven't gotten far, and can't figure it out! here's my error:

    NullReferenceException: Object reference not set to an instance of an object
    (wrapper stelemref) object:stelemref (object,intptr,object)
    KeenansCoolTools.CombineSelected () (at Assets/Editor/KeenansCoolTools.js:142)

    Here's my code:

    Code (csharp):
    1.  
    2. @MenuItem ("Keenan's Cool Tools / Combine Selected")
    3. static function CombineSelected ()
    4. {
    5.     if (EditorUtility.DisplayDialog("Do you want to combine these object?", "This can't be undone! Make sure you have a backup if you don't know what you're doing.","Heck Yeah!","No, I'm scared"))
    6.     {
    7.         var meshFilters : MeshFilter[];
    8.         var amountSelected : int = Selection.gameObjects.Length;
    9.         for (var i = 0; i < amountSelected;)
    10.         {
    11.             meshFilters[i] = Selection.gameObjects[i].GetComponent(MeshFilter);
    12.             Debug.Log (meshFilters);
    13.             i++;
    14.         }
     
  2. landon912

    landon912

    Joined:
    Nov 8, 2011
    Posts:
    1,579
    You never created meshFilters therefore the array is null.

    Here, I wrote this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEditor;
    4.  
    5. public class CombineMeshes : Editor
    6. {
    7.  
    8.     [MenuItem("GameObject/CombineSelectedObjects")]
    9.     static void CombineSelected()
    10.     {
    11.         if (EditorUtility.DisplayDialog("Do you want to combine these objects?", "This can't be undone! Make sure you have a backup if you don't know what you're doing.", "Heck Yeah!", "No, I'm scared"))
    12.         {
    13.             int amountSelected = Selection.gameObjects.Length;
    14.  
    15.             MeshFilter[] meshFilters = new MeshFilter[amountSelected];
    16.             CombineInstance[] combineInstances = new CombineInstance[amountSelected];
    17.  
    18.  
    19.             for (var i = 0; i < amountSelected; i++)
    20.             {
    21.                 meshFilters[i] = Selection.gameObjects[i].GetComponent<MeshFilter>();
    22.  
    23.                 combineInstances[i].mesh = meshFilters[i].sharedMesh;
    24.                 combineInstances[i].transform = meshFilters[i].transform.localToWorldMatrix;
    25.             }
    26.  
    27.             GameObject obj = new GameObject("CombinededMeshes", typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider));
    28.             obj.GetComponent<MeshFilter>().mesh = new Mesh();
    29.             obj.GetComponent<MeshFilter>().sharedMesh.CombineMeshes(combineInstances);
    30.             obj.GetComponent<MeshRenderer>().sharedMaterial = new Material(meshFilters[0].gameObject.GetComponent<MeshRenderer>().sharedMaterial);
    31.             obj.GetComponent<MeshCollider>().sharedMesh = obj.GetComponent<MeshFilter>().sharedMesh;
    32.  
    33.  
    34.             foreach (MeshFilter m in meshFilters)
    35.             {
    36.                 DestroyImmediate(m.gameObject);
    37.             }
    38.         }
    39.     }
    40. }
    41.  
     
  3. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    Thanks a bunch! I'm working on translating that to javascript and I'm getting issues withe the bottom part, where you are using a foreach. I'm probably making a stupid translating error but I'll show you what I've got just in case:
    Code (csharp):
    1.  
    2. @MenuItem ("Keenan's Cool Tools / Combine Selected")
    3. static function CombineSelected ()
    4. {
    5.     if (EditorUtility.DisplayDialog("Do you want to combine these object?", "This can't be undone! Make sure you have a backup if you don't know what you're doing.","Heck Yeah!","No, I'm scared"))
    6.     {
    7.         var amountSelected : int = Selection.gameObjects.Length;
    8.         var meshFilters : MeshFilter[] = new MeshFilter[amountSelected];
    9.         var combineInstances : CombineInstance[]= new CombineInstance[amountSelected];
    10.         for (var i = 0; i < amountSelected; i++)
    11.         {
    12.             meshFilters[I] = Selection.gameObjects[I].GetComponent(MeshFilter);
    13.             combineInstances[I].mesh = meshFilters[I].sharedMesh;
    14.             combineInstances[I].transform = meshFilters[I].transform.localToWorldMatrix;
    15.             Debug.Log (meshFilters);
    16.         }
    17.         var obj : GameObject = new GameObject ("CombinedMesh", typeof (MeshFilter), typeof (MeshRenderer), typeof (MeshCollider));
    18.         obj.GetComponent(MeshFilter).mesh = new Mesh();
    19.        obj.GetComponent(MeshFilter).sharedMesh.CombineMeshes(combineInstances);
    20.        obj.GetComponent(MeshRenderer).sharedMaterial = new Material(meshFilters[0].gameObject.GetComponent(MeshRenderer).sharedMaterial);
    21.        obj.GetComponent(MeshCollider).sharedMesh = obj.GetComponent(MeshFilter).sharedMesh;
    22.      
    23.        foreach (var m : MeshFilter in meshFilters)
    24.        {
    25.           DestroyImmediate(m.gameObject);
    26.        }
    27.     }
    28. }
     
  4. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    So I changed foreach to for, I didn't know javascript didn't have foreach, and then I tried to combine to objects. Unity almost crashed and I got

    MissingComponentException: There is no 'MeshFilter' attached to the "GameObject" game object, but a script is trying to access it.
    You probably need to add a MeshFilter to the game object "GameObject". Or your script needs to check if the component is attached before using it.
    KeenansCoolTools.CombineSelected () (at Assets/Editor/Keenanscooltools/KeenansCoolTools.js:92)

    Whats the best way to check if the objects have the right components. I know how it would normally be done, but I feel like its different since this script is running in the editor. I tried it again with a box and a cube and it worked perfectly! I'm assuming it will get really advanced if I optimized the mesh so that the new object has one clean mesh without all the extra polys inside each other. Another quick question (don't right a huge script to show me anything unless its really easy), but would making booles out of two objects be hard? I would think so! Anyways, thanks for the help and for putting in the time to type up that script!
     
  5. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    595
    Here's the working javascript for any javascript users like myself
    Code (csharp):
    1.  
    2. @MenuItem ("Keenan's Cool Tools / Combine Selected")
    3. static function CombineSelected ()
    4. {
    5.     if (EditorUtility.DisplayDialog("Do you want to combine these object?", "This can't be undone! Make sure you have a backup if you don't know what you're doing.","Heck Yeah!","No, I'm scared"))
    6.     {
    7.         var amountSelected : int = Selection.gameObjects.Length;
    8.         var meshFilters : MeshFilter[] = new MeshFilter[amountSelected];
    9.         var combineInstances : CombineInstance[]= new CombineInstance[amountSelected];
    10.         for (var i = 0; i < amountSelected; i++)
    11.         {
    12.             meshFilters[i] = Selection.gameObjects[i].GetComponent(MeshFilter);
    13.             combineInstances[i].mesh = meshFilters[i].sharedMesh;
    14.             combineInstances[i].transform = meshFilters[i].transform.localToWorldMatrix;
    15.             Debug.Log (meshFilters);
    16.         }
    17.         if ()
    18.         var obj : GameObject = new GameObject ("CombinedMesh", typeof (MeshFilter), typeof (MeshRenderer), typeof (MeshCollider));
    19.         obj.GetComponent(MeshFilter).mesh = new Mesh();
    20.        obj.GetComponent(MeshFilter).sharedMesh.CombineMeshes(combineInstances);
    21.        obj.GetComponent(MeshRenderer).sharedMaterial = new Material(meshFilters[0].gameObject.GetComponent(MeshRenderer).sharedMaterial);
    22.        obj.GetComponent(MeshCollider).sharedMesh = obj.GetComponent(MeshFilter).sharedMesh;
    23.        var m : MeshFilter;
    24.        for (m in meshFilters)
    25.        {
    26.           DestroyImmediate(m.gameObject);
    27.        }
    28.     }
    29. }
     
  6. landon912

    landon912

    Joined:
    Nov 8, 2011
    Posts:
    1,579
    What line is that on in the forums numbering system? Also, it should be the same. I'd just put it into a variable and check if it's null before trying to assign it to the array. I assume you mean making a "hole" out of two objects, and honestly can't think of how I'd do it on the top of my head, therefore I won't make any suggestions.

    Don't worry, I've been meaning to write that script for a while, I see it come up often on the forums.