using System; using UnityEngine; [AddComponentMenu("Modifiers/Modify Object")] [ExecuteInEditMode] public class MegaModifyObject : MegaModifiers { [HideInInspector] public Mesh cachedMesh; public bool InvisibleUpdate; private bool visible = true; private int restorekeep; private static int CompareOrder(MegaModifier m1, MegaModifier m2) { return m1.Order - m2.Order; } [ContextMenu("Resort")] public virtual void Resort() { BuildList(); } [ContextMenu("Help")] public virtual void Help() { Application.OpenURL("http://www.west-racing.com/mf/?page_id=444"); } [ContextMenu("Remove Modify Object (Keep deformed mesh)")] public virtual void RemoveKeep() { MegaModifier[] components = GetComponents(); for (int i = 0; i < components.Length; i++) { if (Application.isEditor) { UnityEngine.Object.DestroyImmediate(components[i]); } else { UnityEngine.Object.Destroy(components[i]); } } restorekeep = 1; if (Application.isEditor) { UnityEngine.Object.DestroyImmediate(this); } else { UnityEngine.Object.Destroy(this); } } [ContextMenu("Remove Modify Object (Restore Mesh)")] public virtual void RemoveRestore() { MegaModifier[] components = GetComponents(); for (int i = 0; i < components.Length; i++) { if (Application.isEditor) { UnityEngine.Object.DestroyImmediate(components[i]); } else { UnityEngine.Object.Destroy(components[i]); } } restorekeep = 2; if (Application.isEditor) { UnityEngine.Object.DestroyImmediate(this); } else { UnityEngine.Object.Destroy(this); } } private void OnDestroy() { if (mesh != cachedMesh && (restorekeep == 0 || restorekeep == 2) && !SetMeshNew(base.gameObject, cachedMesh)) { if (Application.isEditor) { UnityEngine.Object.DestroyImmediate(mesh); } else { UnityEngine.Object.Destroy(mesh); } } } private void Start() { if (dynamicMesh) { cachedMesh = null; } } private void OnRenderObject() { if (UpdateMode == MegaUpdateMode.OnRender) { ModifyObjectMT(); } } public void GetMesh(bool force) { if (!(mesh == null) && !(cachedMesh == null) && sverts.Length != 0 && mesh.vertexCount == sverts.Length && !force) { return; } if (dynamicMesh) { cachedMesh = FindMesh(base.gameObject, out sourceObj); mesh = cachedMesh; if (mesh.vertexCount != 0) { SetMeshData(); } return; } cachedMesh = FindMesh(base.gameObject, out sourceObj); mesh = MegaCopyObject.DupMesh(cachedMesh, string.Empty); SetMesh(base.gameObject, mesh); if (mesh.vertexCount != 0) { SetMeshData(); } } private void SetMeshData() { bbox = cachedMesh.bounds; sverts = new Vector3[cachedMesh.vertexCount]; verts = cachedMesh.vertices; uvs = cachedMesh.uv; suvs = new Vector2[cachedMesh.uv.Length]; cols = cachedMesh.colors; mods = GetComponents(); Array.Sort(mods, CompareOrder); for (int i = 0; i < mods.Length; i++) { if (mods[i] != null) { mods[i].SetModMesh(mesh); mods[i].ModStart(this); } } mapping = null; UpdateMesh = -1; } public void ModReset(MegaModifier m) { if (m != null) { m.SetModMesh(cachedMesh); BuildList(); } } private void Update() { GetMesh(false); if ((visible || InvisibleUpdate) && UpdateMode == MegaUpdateMode.Update) { ModifyObjectMT(); } } private void LateUpdate() { if ((visible || InvisibleUpdate) && UpdateMode == MegaUpdateMode.LateUpdate) { ModifyObjectMT(); } } private void OnBecameVisible() { visible = true; } private void OnBecameInvisible() { visible = false; } [ContextMenu("Reset")] public void Reset() { ResetMeshInfo(); } [ContextMenu("Reset Mesh Info")] public void ResetMeshInfo() { if (mods != null) { if (mods.Length > 0) { mesh.vertices = mods[0].verts; } mesh.uv = uvs; if (recalcnorms) { RecalcNormals(); } if (recalcbounds) { mesh.RecalculateBounds(); } } } public void MeshUpdated() { GetMesh(true); MegaModifier[] array = mods; foreach (MegaModifier megaModifier in array) { megaModifier.SetModMesh(cachedMesh); } } public void MeshChanged(Mesh newmesh) { if (!mesh) { return; } mesh.vertices = newmesh.vertices; mesh.normals = newmesh.normals; mesh.uv = newmesh.uv; mesh.uv2 = newmesh.uv2; mesh.uv2 = newmesh.uv2; mesh.colors = newmesh.colors; mesh.tangents = newmesh.tangents; mesh.subMeshCount = newmesh.subMeshCount; for (int i = 0; i < newmesh.subMeshCount; i++) { mesh.SetTriangles(newmesh.GetTriangles(i), i); } bbox = newmesh.bounds; sverts = new Vector3[mesh.vertexCount]; verts = mesh.vertices; uvs = mesh.uv; suvs = new Vector2[mesh.uv.Length]; cols = mesh.colors; mods = GetComponents(); Array.Sort(mods, CompareOrder); MegaModifier[] array = mods; foreach (MegaModifier megaModifier in array) { if (megaModifier != null) { megaModifier.SetModMesh(newmesh); megaModifier.ModStart(this); } } mapping = null; UpdateMesh = -1; } public void SetMesh(GameObject go, Mesh mesh) { if (!go) { return; } Transform[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { MeshFilter component = componentsInChildren[i].GetComponent(); if ((bool)component) { component.sharedMesh = mesh; break; } SkinnedMeshRenderer component2 = componentsInChildren[i].GetComponent(); if ((bool)component2) { component2.sharedMesh = mesh; break; } } } public static Mesh FindMesh(GameObject go, out GameObject obj) { if ((bool)go) { Transform[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { MeshFilter component = componentsInChildren[i].GetComponent(); if ((bool)component) { if (component.gameObject != go) { obj = component.gameObject; } else { obj = null; } return component.sharedMesh; } SkinnedMeshRenderer component2 = componentsInChildren[i].GetComponent(); if ((bool)component2) { if (component2.gameObject != go) { obj = component2.gameObject; } else { obj = null; } return component2.sharedMesh; } } } obj = null; return null; } public static bool SetMeshNew(GameObject go, Mesh m) { if ((bool)go) { Transform[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { MeshFilter component = componentsInChildren[i].GetComponent(); if ((bool)component) { component.sharedMesh = m; return true; } SkinnedMeshRenderer component2 = componentsInChildren[i].GetComponent(); if ((bool)component2) { component2.sharedMesh = m; return true; } } } return false; } }