using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class MeshData : MonoBehaviour { [SerializeField, HideInInspector] private int m_currentSubdivisions = 1; [SerializeField, HideInInspector] private List m_data = new List(); [SerializeField, HideInInspector] private List m_colliderData = new List(); [System.Serializable] public class SubData { public Mesh originalMesh; public Mesh currentMesh; public Vector3[] subdividedVertices; public MeshFilter meshFilter; public SubData(MeshFilter meshFilter) { this.meshFilter = meshFilter; originalMesh = this.meshFilter.sharedMesh; } } [System.Serializable] public class ColliderData { public Collider originalCollider; public MeshCollider currentCollider; public SubData attachedData; public ColliderData(Collider collider, SubData data) { originalCollider = collider; originalCollider.enabled = false; currentCollider = originalCollider.gameObject.AddComponent(); attachedData = data; Update(); } public void Update() { currentCollider.sharedMesh = attachedData.currentMesh; } } public static MeshData Add(GameObject gameObject) { MeshData _meshData = gameObject.AddComponent(); foreach (MeshFilter meshFilter in gameObject.GetComponentsInChildren()) { SubData _data = new SubData(meshFilter); _meshData.m_data.Add(_data); _meshData.SubdivideData(_data); } foreach(Collider collider in gameObject.GetComponentsInChildren()) { MeshFilter meshFilter = collider.gameObject.GetComponentInChildren(); SubData data = _meshData.m_data.FirstOrDefault(p => p.meshFilter == meshFilter); if (data != null) _meshData.m_colliderData.Add(new ColliderData(collider, data)); } return _meshData; } public void Remove() { foreach (SubData data in m_data) { data.meshFilter.sharedMesh = data.originalMesh; DestroyImmediate(data.currentMesh); } foreach(ColliderData data in m_colliderData) { data.originalCollider.enabled = true; DestroyImmediate(data.currentCollider); } DestroyImmediate(this); } public void SubdivideMesh(int subdivisionAmount) { if (m_currentSubdivisions == subdivisionAmount) return; m_currentSubdivisions = subdivisionAmount; foreach (SubData data in m_data) SubdivideData(data); foreach (ColliderData collisionData in m_colliderData) collisionData.Update(); } public void CurveMesh(Vector3 Centre, Vector3 Axis) { foreach (SubData data in m_data) CurveData(data, Centre, Axis); foreach (ColliderData collisionData in m_colliderData) collisionData.Update(); } private void CurveData(SubData data, Vector3 Centre, Vector3 Axis) { data.currentMesh.vertices = Utility.Meshes.Curve.CurveVertices(data.subdividedVertices, Centre, Axis, data.meshFilter.transform,transform.position); } private void SubdivideData(SubData data) { if (data.currentMesh != null) DestroyImmediate(data.currentMesh); data.currentMesh = null; data.currentMesh = Utility.Meshes.Subdivion.DuplicateMesh(data.originalMesh); Debug.Log($"Subdividing by: {m_currentSubdivisions}"); Utility.Meshes.Subdivion.Subdivide(data.currentMesh, m_currentSubdivisions); data.currentMesh.RecalculateBounds(); data.currentMesh.RecalculateNormals(); data.currentMesh.RecalculateTangents(); data.subdividedVertices = data.currentMesh.vertices; data.meshFilter.sharedMesh = data.currentMesh; } }