using UnityEngine; [AddComponentMenu("Modifiers/Conform")] public class MegaConformMod : MegaModifier { public GameObject target; public float[] offsets; public Collider conformCollider; public Bounds bounds; public float[] last; public Vector3[] last1; public Vector3[] conformedVerts; public float conformAmount = 1f; public float raystartoff; public float offset; public float raydist = 100f; public MegaAxis axis = MegaAxis.Y; private Matrix4x4 loctoworld; private Matrix4x4 ctm; private Matrix4x4 cinvtm; private Ray ray = default(Ray); private RaycastHit hit; public bool useLocalDown; public bool flipDown = true; public MegaAxis downAxis = MegaAxis.Y; public override string ModName() { return "Conform"; } public override string GetHelpURL() { return "?page_id=4547"; } public void SetTarget(GameObject targ) { target = targ; if ((bool)target) { conformCollider = target.GetComponent(); } } public override Vector3 Map(int i, Vector3 p) { return p; } public override void Modify(MegaModifiers mc) { if ((bool)conformCollider) { if (useLocalDown) { Vector3 vector = Vector3.down; switch (downAxis) { case MegaAxis.X: vector = base.transform.right; break; case MegaAxis.Y: vector = base.transform.up; break; case MegaAxis.Z: vector = base.transform.forward; break; } if (flipDown) { vector = -vector; } ray.direction = vector; Vector3 vector2 = -vector * raystartoff; Vector3 direction = ray.direction; Vector3 vector3 = -base.transform.InverseTransformDirection(direction); for (int i = 0; i < verts.Length; i++) { Vector3 origin = ctm.MultiplyPoint(verts[i]) - vector2; ray.origin = origin; sverts[i] = verts[i]; if (conformCollider.Raycast(ray, out hit, raydist)) { Vector3 vector4 = cinvtm.MultiplyPoint(hit.point); sverts[i] = Vector3.Lerp(verts[i], vector4 + vector3 * (offsets[i] + offset), conformAmount); last1[i] = sverts[i]; } else { sverts[i] = last1[i]; } } return; } int index = (int)axis; for (int j = 0; j < verts.Length; j++) { Vector3 origin2 = ctm.MultiplyPoint(verts[j]); origin2.y += raystartoff; ray.origin = origin2; ray.direction = Vector3.down; sverts[j] = verts[j]; if (conformCollider.Raycast(ray, out hit, raydist)) { Vector3 vector5 = cinvtm.MultiplyPoint(hit.point); sverts[j][index] = Mathf.Lerp(verts[j][index], vector5[index] + offsets[j] + offset, conformAmount); last[j] = sverts[j][index]; } else { sverts[j][index] = last[j]; } } } else { verts.CopyTo(sverts, 0); } } public override bool ModLateUpdate(MegaModContext mc) { return Prepare(mc); } public override bool Prepare(MegaModContext mc) { if ((bool)target) { if (conformCollider != target.GetComponent()) { conformCollider = target.GetComponent(); } if (conformCollider == null) { return false; } if (conformedVerts == null || conformedVerts.Length != mc.mod.verts.Length) { conformedVerts = new Vector3[mc.mod.verts.Length]; offsets = new float[mc.mod.verts.Length]; last = new float[mc.mod.verts.Length]; for (int i = 0; i < mc.mod.verts.Length; i++) { offsets[i] = mc.mod.verts[i][(int)axis] - mc.bbox.min[(int)axis]; } } if (useLocalDown && (last1 == null || last1.Length != last.Length)) { last1 = new Vector3[last.Length]; } loctoworld = base.transform.localToWorldMatrix; ctm = loctoworld; cinvtm = base.transform.worldToLocalMatrix; return true; } conformCollider = null; return true; } public void ChangeAxis() { MegaModifyObject component = GetComponent(); if ((bool)component) { for (int i = 0; i < component.verts.Length; i++) { offsets[i] = component.verts[i][(int)axis] - component.bbox.min[(int)axis]; } } } }