using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Serialization; using System; public class ClothCollisionAssigner : MonoBehaviour { [Header("Paired Sphere Colliders")] public SphereCollider[] m_UpperbodyColliders; public SphereCollider[] m_LowerbodyColliders; [Serializable] public class ClothConfig { public Cloth m_ClothToManage; public bool m_UpperBody; public bool m_LowerBody; } [Header("Cloth Collision Assignments")] public ClothConfig[] m_ClothConfigurationList; private void addCollidersToCloth(SphereCollider[] collider_list, Cloth cloth_component) { int collider_size = 0; foreach (SphereCollider sphere_collider in collider_list) { if (sphere_collider != null) { collider_size++; } } if (collider_size % 2 != 0) { collider_size += 1; } int original_size = 0; if (cloth_component.sphereColliders != null) { original_size = cloth_component.sphereColliders.Length; } ClothSphereColliderPair[] colliderpair_list = new ClothSphereColliderPair[original_size + (collider_size / 2)]; if (original_size > 0) { Array.Copy(cloth_component.sphereColliders, colliderpair_list, original_size); } for (int i = 0; i < collider_size / 2; i++) { colliderpair_list[original_size + i].first = collider_list[i * 2]; colliderpair_list[original_size + i].second = collider_list[i * 2 + 1]; } cloth_component.sphereColliders = colliderpair_list; } public void addClothConfig(ClothConfig newConfig) { int new_size = m_ClothConfigurationList.Length + 1; Array.Resize(ref m_ClothConfigurationList, new_size); m_ClothConfigurationList[new_size - 1] = newConfig; } // merge cloth collision rig into rootnode of main figure rig public void mergeRig(Transform destination_rootTransform) { Transform source_rootTransform = this.transform.Find("hip"); List childTransform_stack = new List(); childTransform_stack.Add(source_rootTransform); while (childTransform_stack.Count > 0) { int next_Index = childTransform_stack.Count - 1; Transform child = childTransform_stack[next_Index]; childTransform_stack.RemoveAt(next_Index); if (child == null) continue; // add all children to stack for (int i = 0; i < child.childCount; i++) { Transform grandchild = child.GetChild(i); if (grandchild != null) childTransform_stack.Add(grandchild); } // check if child is a dforce collider if (child.CompareTag("dForceCollider")) { // 1. unroll parent tree to get full path Transform parent = child.parent; String path_name = parent.name; while (parent != null && parent.parent != source_rootTransform) { if (parent.parent == null) break; parent = parent.parent; path_name = parent.name + "/" + path_name; } // 2. find destination parent node var dest_parent = destination_rootTransform.Find(path_name); if (dest_parent != null) { // 3. move child to destination parent, worldspace = false child.transform.SetParent(dest_parent, false); } } } } public void ClearAllAssignments() { foreach (ClothConfig cloth_config in m_ClothConfigurationList) { if (cloth_config == null) continue; // delete existing cloth collisions if (cloth_config.m_ClothToManage != null && cloth_config.m_ClothToManage.sphereColliders != null) cloth_config.m_ClothToManage.sphereColliders = null; } } public void AssignClothCollisionRigs() { foreach (ClothConfig cloth_config in m_ClothConfigurationList) { if (cloth_config == null) continue; if (cloth_config.m_UpperBody) addCollidersToCloth(m_UpperbodyColliders, cloth_config.m_ClothToManage); if (cloth_config.m_LowerBody) addCollidersToCloth(m_LowerbodyColliders, cloth_config.m_ClothToManage); } } // Start is called before the first frame update void Start() { ClearAllAssignments(); AssignClothCollisionRigs(); } // Update is called once per frame void Update() { } }