Hi everyone,
I’m working on a project in Unity (version 2021.3.2f1, Built-in Render Pipeline) and want to optimize my scene by combining multiple static meshes into a single mesh. At the same time, I’d also like to bake the lighting for these combined objects in one unified process if possible.
My goal is to avoid doing two separate steps—combining the meshes first and then rebaking (or vice versa). Ideally, I want a workflow or tool that can both merge the meshes (for reduced draw calls) and also generate correct lightmaps (or maintain existing lightmaps) in a single pass.
I’ve considered using “Mesh Baker” or writing a custom script, but I’m not sure if there’s an established best practice or recommended approach for simultaneous mesh combining and lightmap baking. Has anyone successfully done this? Do you have any tips, tutorials, or documentation references?
Additionally, if simultaneous baking isn’t practical, what’s the standard pipeline? Should I combine the meshes first and then bake the lighting, or bake the lighting and adjust the UVs afterwards? Any guidance would be greatly appreciated. Thanks in advance!
There is a mesh combiner in the asset store already.
Suppose you could put that into an editor window script,
with a list of objects to combine in the layout.
Then just have that list execute on run. (See below)
As for baking at runtime, the consensus is that Unity has
no scriptable runtime light baking. Some suggest UE4, but
that is a stretch, and likely also no.
So I asked brave a.i to help me generate a runtime shader
that outputs a light bake to folder.
Here is a sample script for your mesh combining…
(Not tested)
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
public class MeshCombiner : EditorWindow
{
// List of objects to combine
public List<GameObject> objectsToCombine = new List<GameObject>();
// Output folder path
public string outputFolderPath = "";
// Button to combine meshes
[MenuItem("Window/Mesh Combiner")]
public static void ShowWindow()
{
GetWindow<MeshCombiner>("Mesh Combiner");
}
private void OnGUI()
{
// Objects to combine list
EditorGUILayout.LabelField("Objects to Combine:");
objectsToCombine = (List<GameObject>)EditorGUILayout.PropertyField(objectsToCombine, true);
// Output folder path
EditorGUILayout.LabelField("Output Folder:");
outputFolderPath = EditorGUILayout.TextField(outputFolderPath);
// Button to select output folder
if (GUILayout.Button("Select Output Folder"))
{
outputFolderPath = EditorUtility.OpenFolderPanel("Select Output Folder", outputFolderPath, "");
}
// Button to combine meshes
if (GUILayout.Button("Combine Meshes"))
{
CombineMeshes();
}
}
private void CombineMeshes()
{
// Check if output folder path is valid
if (string.IsNullOrEmpty(outputFolderPath))
{
Debug.LogError("Output folder path is invalid.");
return;
}
// Create output folder if it doesn't exist
if (!Directory.Exists(outputFolderPath))
{
Directory.CreateDirectory(outputFolderPath);
}
// Combine meshes
Mesh combinedMesh = new Mesh();
foreach (GameObject obj in objectsToCombine)
{
MeshFilter meshFilter = obj.GetComponent<MeshFilter>();
if (meshFilter != null)
{
Mesh mesh = meshFilter.mesh;
combinedMesh.CombineMeshes(new Mesh[] { mesh });
}
}
// Save combined mesh to file
string filePath = Path.Combine(outputFolderPath, "CombinedMesh.obj");
MeshExporter.ExportMesh(combinedMesh, filePath);
Debug.Log("Meshes combined and saved to " + filePath);
}
}
// Helper class to export mesh to file
public static class MeshExporter
{
public static void ExportMesh(Mesh mesh, string filePath)
{
using (StreamWriter writer = new StreamWriter(filePath))
{
// Write header
writer.WriteLine("# OBJ file generated by MeshCombiner");
// Write vertices
foreach (Vector3 vertex in mesh.vertices)
{
writer.WriteLine("v " + vertex.x + " " + vertex.y + " " + vertex.z);
}
// Write triangles
int[] triangles = mesh.triangles;
for (int i = 0; i < triangles.Length; i += 3)
{
writer.WriteLine("f " + (triangles[i] + 1) + " " + (triangles[i + 1] + 1) + " " + (triangles[i + 2] + 1));
}
}
}
}
Here is a sample script of a shader that bakes lighting at runtime to an output folder