using System.Collections.Generic; using UnityEngine; [AddComponentMenu("Modifiers/Conform Multi")] public class MegaConformMulti : MegaModifier { public List targets = new List(); public List conformColliders = new List(); public float[] offsets; public Bounds bounds; public float[] last; 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 override string ModName() { return "Conform Multi"; } public override string GetHelpURL() { return "?page_id=4547"; } public void BuildColliderList() { conformColliders.Clear(); for (int i = 0; i < targets.Count; i++) { if (!targets[i].target) { continue; } if (targets[i].children) { Collider[] componentsInChildren = targets[i].target.GetComponentsInChildren(); for (int j = 0; j < componentsInChildren.Length; j++) { conformColliders.Add(componentsInChildren[j]); } } else { Collider component = targets[i].target.GetComponent(); if ((bool)component) { conformColliders.Add(component); } } } } public override Vector3 Map(int i, Vector3 p) { return p; } private bool DoRayCast(Ray ray, ref Vector3 pos, float raydist) { bool result = false; float num = float.MaxValue; for (int i = 0; i < conformColliders.Count; i++) { if (conformColliders[i].Raycast(ray, out hit, raydist)) { result = true; if (hit.distance < num) { num = hit.distance; pos = hit.point; } } } return result; } public override void Modify(MegaModifiers mc) { if (conformColliders.Count > 0) { int index = (int)axis; Vector3 pos = Vector3.zero; for (int i = 0; i < verts.Length; i++) { Vector3 origin = ctm.MultiplyPoint(verts[i]); origin.y += raystartoff; ray.origin = origin; ray.direction = Vector3.down; sverts[i] = verts[i]; if (DoRayCast(ray, ref pos, raydist)) { Vector3 vector = cinvtm.MultiplyPoint(pos); sverts[i][index] = Mathf.Lerp(verts[i][index], vector[index] + offsets[i] + offset, conformAmount); last[i] = sverts[i][index]; } else { Vector3 origin2 = ray.origin; origin2.y -= raydist; sverts[i][index] = last[i]; } } } else { verts.CopyTo(sverts, 0); } } public override bool ModLateUpdate(MegaModContext mc) { return Prepare(mc); } public override bool Prepare(MegaModContext mc) { if (targets.Count > 0) { if (conformColliders.Count == 0) { 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]; } } loctoworld = base.transform.localToWorldMatrix; ctm = loctoworld; cinvtm = base.transform.worldToLocalMatrix; } return true; } }