Created
January 17, 2025 19:36
-
-
Save jedjoud10/17dbab246eacee14d997134e91330864 to your computer and use it in GitHub Desktop.
Unity multiple physics material per sub-mesh for mesh collider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using UnityEngine; | |
[Serializable] | |
public struct PhysicsMaterialTemp { | |
public float dynamicFriction; | |
public float staticFriction; | |
public float bounce; | |
} | |
public class SubMeshPhysicsMaterial : MonoBehaviour { | |
public MeshCollider meshCollider; | |
public List<PhysicsMaterialTemp> materials; | |
private uint[] offsets; | |
private int instanceId; | |
private void Start() { | |
meshCollider.hasModifiableContacts = true; | |
Physics.ContactModifyEvent += Physics_ContactModifyEvent; | |
instanceId = meshCollider.GetInstanceID(); | |
Mesh mesh = meshCollider.sharedMesh; | |
if (mesh.subMeshCount != materials.Count) { | |
throw new Exception("uh oh"); | |
} | |
offsets = new uint[materials.Count]; | |
for (int i = 0; i < offsets.Length; i++) { | |
offsets[i] = (uint)mesh.GetSubMesh(i).indexStart; | |
} | |
} | |
public void OnDisable() { | |
Physics.ContactModifyEvent -= Physics_ContactModifyEvent; | |
} | |
private int GetMaterialIndex(uint triangleOffset) { | |
for (int j = offsets.Length - 1; j >= 0; j--) { | |
uint offset = offsets[j]; | |
if (triangleOffset >= offset) { | |
return j; | |
} | |
} | |
return -1; | |
} | |
public PhysicsMaterialTemp GetMaterial(uint triangleOffset) { | |
return materials[GetMaterialIndex(triangleOffset)]; | |
} | |
private void Physics_ContactModifyEvent(PhysicsScene arg1, Unity.Collections.NativeArray<ModifiableContactPair> pairs) { | |
foreach (var pair in pairs) { | |
if (pair.colliderInstanceID == instanceId || pair.otherColliderInstanceID == instanceId) { | |
for (int i = 0; i < pair.contactCount; i++) { | |
uint face = pair.GetFaceIndex(i); | |
int material = GetMaterialIndex(face * 3); | |
pair.SetDynamicFriction(i, materials[material].dynamicFriction); | |
pair.SetStaticFriction(i, materials[material].staticFriction); | |
pair.SetBounciness(i, materials[material].bounce); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Still needs commenting and cleaning up a bit