2using System.Threading.Tasks;
9 private const string ColliderObjectPrefix =
"UCI_";
10 [SerializeField]
private float _divisionUnitLength = 0.5f;
14 var colliderObjectName = $
"{ColliderObjectPrefix}{gameObject.name}";
15 RemoveOldColliders(colliderObjectName);
17 var meshCollider = gameObject.AddComponent<MeshCollider>();
18 var bounds = meshCollider.bounds;
20 Vector3[] gridPositions;
21 int xDivisionCount, yDivisionCount, zDivisionCount;
22 BoundsDivider.Divide(bounds, _divisionUnitLength, out gridPositions, out xDivisionCount,
23 out yDivisionCount, out zDivisionCount);
25 var tmpColliders =
new Collider[1];
26 var positionCount = gridPositions.Length;
27 var hasColliderPosition =
new bool[xDivisionCount * yDivisionCount * zDivisionCount];
28 for (var i = 0; i < positionCount; i++)
30 var position = gridPositions[i];
31 if (Physics.OverlapSphereNonAlloc(position, _divisionUnitLength / 2f, tmpColliders) == 0)
continue;
33 hasColliderPosition[i] =
true;
36 var colliderObject =
new GameObject(colliderObjectName);
37 colliderObject.transform.SetParent(transform);
38 var numberofcollidersnow = 0;
39 while (hasColliderPosition.Any(p => p))
43 var combineCountMax =
int.MinValue;
44 var xCombineEdgeCount = 0;
45 var yCombineEdgeCount = 0;
46 var zCombineEdgeCount = 0;
47 for (var i = 0; i < positionCount; i++)
49 if (!hasColliderPosition[i])
continue;
53 while (checkIndex >= 0 && checkIndex < positionCount && hasColliderPosition[checkIndex])
55 checkIndex += zDivisionCount * yDivisionCount;
58 if (checkIndex % (zDivisionCount * yDivisionCount) == 0)
break;
63 while (checkIndex >= 0 && checkIndex < positionCount && hasColliderPosition[checkIndex])
65 checkIndex += zDivisionCount;
68 if (checkIndex % (zDivisionCount * yDivisionCount) / zDivisionCount == 0)
break;
73 while (checkIndex >= 0 && checkIndex < positionCount && hasColliderPosition[checkIndex])
78 if (checkIndex % zDivisionCount == 0)
break;
85 for (var x = 1; x <= xEdgeCount; x++)
86 for (var y = 1; y <= yEdgeCount; y++)
87 for (var z = 1; z <= zEdgeCount; z++)
89 if (!IsValidCubes(hasColliderPosition, i, x, y, z, yDivisionCount, zDivisionCount))
continue;
91 var count = x * y * z;
92 if (count < c)
continue;
100 xEdgeCount = resultX;
101 yEdgeCount = resultY;
102 zEdgeCount = resultZ;
104 var margeCount = xEdgeCount * yEdgeCount * zEdgeCount;
105 if (margeCount <= combineCountMax)
continue;
108 xCombineEdgeCount = xEdgeCount;
109 yCombineEdgeCount = yEdgeCount;
110 zCombineEdgeCount = zEdgeCount;
111 combineCountMax = margeCount;
114 for (var x = 0; x < xCombineEdgeCount; x++)
115 for (var y = 0; y < yCombineEdgeCount; y++)
116 for (var z = 0; z < zCombineEdgeCount; z++)
118 var index = combineIndex + zDivisionCount * yDivisionCount * x + zDivisionCount * y + z;
119 hasColliderPosition[index] =
false;
122 var collider = colliderObject.AddComponent<BoxCollider>();
123 collider.center = gridPositions[combineIndex] +
124 new Vector3(xCombineEdgeCount, yCombineEdgeCount, zCombineEdgeCount) *
125 _divisionUnitLength / 2f - Vector3.one * _divisionUnitLength / 2f;
126 collider.size =
new Vector3(xCombineEdgeCount, yCombineEdgeCount, zCombineEdgeCount) *
128 numberofcollidersnow++;
129 if (numberofcollidersnow >= 31)
131 colliderObject =
new GameObject(colliderObjectName + $
"_{numberofcollidersnow}");
132 colliderObject.transform.SetParent(transform);
133 numberofcollidersnow = 0;
137 DestroyImmediate(meshCollider);
140 void RemoveOldColliders(
string colliderObjectName)
142 var child = transform.Find(colliderObjectName);
143 if (child !=
null) DestroyImmediate(child.gameObject);
146 bool IsValidCubes(
bool[] hasCollider,
int index,
int xEdgeCount,
int yEdgeCount,
int zEdgeCount,
147 int yDivisionCount,
int zDivisionCount)
149 for (var x = 0; x < xEdgeCount; x++)
150 for (var y = 0; y < yEdgeCount; y++)
151 for (var z = 0; z < zEdgeCount; z++)
153 var i = index + x * yDivisionCount * zDivisionCount + y * zDivisionCount + z;
154 if (hasCollider[i])
continue;