Quick answer: When you edit a ProBuilder mesh, the MeshCollider component does not automatically update its internal collision mesh. The collider still references the old mesh data until you explicitly refresh it. This causes players to collide with invisible geometry or pass through visible walls.

Here is how to fix Unity probuilder mesh collider mismatch. You sculpt a hallway with ProBuilder, playtest your level, and the player gets stuck on an invisible wall that no longer exists. Or worse, they walk straight through a wall you just added. The MeshCollider is out of sync with the visible geometry. This is one of the most disorienting ProBuilder bugs because the editor view looks perfect — the mismatch only reveals itself at runtime. Here is why it happens and how to fix it permanently.

The Symptom

After editing a ProBuilder mesh — moving vertices, extruding faces, merging objects, or deleting edges — the collision boundary no longer matches the rendered shape. Players collide with geometry that is not visible, or pass through walls that are clearly rendered on screen. The problem is intermittent: sometimes the collider updates correctly, sometimes it does not.

If you select the object and look at the MeshCollider component in the Inspector, you may notice that the collider's wireframe overlay in the Scene view does not line up with the ProBuilder mesh. The green wireframe shows the old shape. This confirms the collider is stale.

The issue is especially common after batch operations like merging multiple ProBuilder objects, subdividing faces, or using the mirror tool. Single-vertex moves sometimes trigger an automatic refresh, but larger structural edits often do not.

What Causes This

ProBuilder modifies the mesh data on the MeshFilter component directly. When you move a vertex or extrude a face, ProBuilder writes new vertex positions and triangle indices to the MeshFilter's shared mesh. However, the MeshCollider component maintains its own internal copy of the collision mesh. It does not watch the MeshFilter for changes.

Unity's physics engine bakes the collision mesh when the MeshCollider's sharedMesh property is assigned. After baking, the physics engine uses the baked data exclusively. Even if the underlying mesh asset changes, the collider does not re-bake until you explicitly re-assign the sharedMesh property or disable and re-enable the component.

In some Unity versions, ProBuilder does attempt to refresh colliders after edits. But this auto-refresh has historically been unreliable, particularly after undo/redo operations, multi-object edits, or when the ProBuilder window is not focused. The result is a collider that silently falls behind the visible mesh.

A second layer of confusion comes from the convex setting. If your MeshCollider has convex set to true, Unity generates a convex hull approximation of the mesh. This approximation may look nothing like your actual geometry — it wraps around the outer boundary and fills in any concavities or holes. Developers often enable convex because Unity requires it for Rigidbody objects, then wonder why the collision shape is wrong. It is not wrong; it is convex.

The Fix

Step 1: Force-refresh the MeshCollider after edits. The most direct fix is to re-assign the shared mesh to the MeshCollider. This forces Unity to re-bake the collision data from the current mesh geometry.

using UnityEngine;

public class ColliderRefresh : MonoBehaviour
{
    /// Call this after any runtime ProBuilder mesh edit
    public void RefreshCollider()
    {
        var meshFilter = GetComponent<MeshFilter>();
        var meshCollider = GetComponent<MeshCollider>();

        if (meshFilter == null || meshCollider == null)
        {
            Debug.LogWarning("Missing MeshFilter or MeshCollider on " + gameObject.name);
            return;
        }

        // Re-assign the mesh to force a physics re-bake
        meshCollider.sharedMesh = null;
        meshCollider.sharedMesh = meshFilter.sharedMesh;

        Debug.Log($"Collider refreshed on {gameObject.name} " +
                  $"({meshFilter.sharedMesh.vertexCount} verts)");
    }
}

Setting sharedMesh to null first and then re-assigning it ensures Unity treats it as a new assignment even if the mesh reference is the same object. Without the null step, Unity may skip the re-bake because it sees the same reference and assumes nothing changed.

Step 2: Automate collider refresh in the editor. Rather than remembering to refresh manually, hook into ProBuilder's edit callbacks. This editor script will automatically update every MeshCollider on any object that ProBuilder modifies.

using UnityEngine;
using UnityEditor;
using UnityEngine.ProBuilder;
using UnityEditor.ProBuilder;

[InitializeOnLoad]
public static class ProBuilderColliderSync
{
    static ProBuilderColliderSync()
    {
        // Subscribe to ProBuilder's mesh modification event
        ProBuilderEditor.afterMeshModification += OnMeshModified;
    }

    static void OnMeshModified(ProBuilderMesh[] meshes)
    {
        foreach (var pbMesh in meshes)
        {
            var collider = pbMesh.GetComponent<MeshCollider>();
            if (collider == null) continue;

            var filter = pbMesh.GetComponent<MeshFilter>();
            collider.sharedMesh = null;
            collider.sharedMesh = filter.sharedMesh;

            Debug.Log($"[ProBuilderColliderSync] Refreshed collider: {pbMesh.name}");
        }
    }
}

Place this script in an Editor folder in your project. It runs automatically whenever ProBuilder finishes modifying a mesh. The [InitializeOnLoad] attribute ensures the callback is registered when the editor starts, so you never have to think about it again.

Step 3: Choose the right collider type. If your ProBuilder object is static environment geometry — floors, walls, ceilings, ramps — use a non-convex MeshCollider. This gives you pixel-accurate collision that matches the visible mesh exactly, including concave shapes and holes.

using UnityEngine;

public class ColliderSetup : MonoBehaviour
{
    [SerializeField] bool isDynamic = false;

    void Start()
    {
        var collider = GetComponent<MeshCollider>();
        if (collider == null) return;

        if (isDynamic)
        {
            // Dynamic objects MUST use convex colliders
            collider.convex = true;
            // Consider using a compound collider instead for
            // complex shapes that lose detail when convex-hulled
        }
        else
        {
            // Static geometry: non-convex for exact collision
            collider.convex = false;
        }
    }
}

If you need a dynamic Rigidbody with a complex ProBuilder shape, avoid MeshCollider entirely. Instead, build a compound collider from BoxColliders, SphereColliders, and CapsuleColliders parented to the object. Compound colliders are cheaper to simulate and give you explicit control over the collision boundary.

Why This Works

The null-then-reassign pattern works because Unity's MeshCollider internally caches a baked PhysX mesh. When you assign a new value to sharedMesh, Unity invalidates the cache and triggers a full re-bake from the current vertex and triangle data. Setting it to null first ensures that the subsequent assignment is always treated as a change, even when the mesh reference has not changed.

The editor callback approach works because ProBuilder exposes its modification pipeline through events. The afterMeshModification event fires after ProBuilder has finished writing new geometry to the MeshFilter, which means the mesh data is in its final state when our callback reads it. This is important — subscribing to a mid-edit event would bake intermediate geometry into the collider.

Choosing non-convex colliders for static geometry works because Unity only requires convex colliders on objects that participate in dynamic physics simulation (non-kinematic Rigidbodies). Static colliders and kinematic Rigidbodies can use concave mesh colliders, which exactly match the source mesh without any approximation. This eliminates the class of bugs where the convex hull creates phantom collision surfaces that do not correspond to any visible geometry.

Edge Cases to Watch For

Undo operations. ProBuilder's undo integration sometimes restores the mesh geometry without firing the modification callback. If you undo a ProBuilder edit and the collider does not update, select the object and run the refresh manually, or toggle the MeshCollider component off and on in the Inspector.

Merged meshes. When you merge multiple ProBuilder objects into one, the resulting mesh may exceed the 255-triangle limit for convex colliders. If the merged object has a convex MeshCollider, Unity will silently simplify the collision hull, potentially creating a shape that barely resembles the visible mesh. Switch to non-convex or use compound colliders.

Runtime ProBuilder edits. If you use ProBuilder's runtime API to deform meshes during gameplay (destructible environments, terrain sculpting), you must call the refresh method after every modification. Batch your edits and refresh once per frame rather than after every individual vertex move to avoid performance spikes from repeated PhysX re-bakes.

"The null-reassign trick is the first thing I teach anyone working with ProBuilder. It solves ninety percent of the phantom wall and walk-through-geometry bugs in a single line."

Related Issues

If your colliders are correct but physics interactions feel wrong, the issue may be with your physics material or Rigidbody settings rather than the mesh itself. For objects that fall through floors entirely, check that your fixed timestep is small enough to prevent tunneling at the object's velocity. And if you are seeing performance problems with many MeshColliders in a scene, consider replacing complex ProBuilder geometry with simplified collision meshes assigned via the MeshCollider's sharedMesh property directly, rather than using the visible mesh for collision.

Null it first, then reassign. Every time.