using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace BITKit.Physics { public class GetClosePointFromCollider : IClosePointProvider { public string Name="Default"; public Transform Transform; public Vector3 Offset = default; public LayerMask LayerMask=LayerMask.NameToLayer("Default"); public float Distance=1.6f; public float MinHeight=0.32f; public float MaxHeight = 1f; private readonly Collider[] _colliders=new Collider[8]; private readonly Collider[] _mainCollider=new Collider[8]; public GetClosePointFromCollider(Transform transform) { Transform = transform; } public bool TryGetValue(out Vector3 position, out Collider collider) { Vector3 vector3 = default; StringBuilder reportBuilder = new(); reportBuilder.AppendLine($"检测任务:{Name}"); position = Transform.position + Transform.rotation * Offset; var detectedLength = UnityEngine.Physics.OverlapSphereNonAlloc(position, Distance, _mainCollider, LayerMask); reportBuilder.AppendLine($"检测到了{detectedLength}个碰撞体"); foreach (var collider1 in _mainCollider.Take(detectedLength).OrderBy(ByTop).Reverse()) //for (var i = 0; i top) { reportBuilder?.AppendLine("高度不足"); continue; } var nextPos = position; nextPos.y = collider1.bounds.center.y; { var ray = new Ray(nextPos, Transform.forward); if (collider1.Raycast(new Ray(nextPos, Transform.forward), out _, Distance) is false) { reportBuilder?.AppendLine("未检测到前方"); Debug.DrawRay(ray.origin,ray.direction,Color.red,Distance); continue; } } var height = Mathf.Abs(top - Transform.position.y); if (height > MaxHeight) { reportBuilder?.AppendLine($"高度差距过大:{height}"); continue; } if (UnityEngine.Physics.Linecast(Transform.position, vector3, out var raycastHit2, LayerMask)) { if (raycastHit2.collider != collider1) { reportBuilder?.AppendLine($"检测到了其他碰撞体:{raycastHit2.transform.name}"); continue; } } var length = UnityEngine.Physics.OverlapSphereNonAlloc(vector3, 0.01f, _colliders, LayerMask); switch (length) { case 1: if (_colliders[0] != collider1) { reportBuilder.AppendLine($"检测到了其他碰撞体{_colliders[0].name}"); continue; } break; case > 1: reportBuilder.AppendLine("检测到了更多碰撞体"); for (var ii = 0; ii < length; ii++) { //Debug.DrawLine(vector3, _colliders[ii].ClosestPoint(vector3), Color.red, 8); reportBuilder.AppendLine($"\t{_colliders[ii].name}"); } continue; } vector3.y = top; position = vector3; collider = collider1; reportBuilder.AppendLine("成功"); //BIT4Log.Log(reportBuilder.ToString()); return true; } collider = null; //BIT4Log.Log(reportBuilder.ToString()); return false; } private float ByTop(Collider arg) { return arg.bounds.center.y + arg.bounds.extents.y; } } }