1
This commit is contained in:
140
Src/Unity/Scripts/Physics/GetClosePointFromCollider.cs
Normal file
140
Src/Unity/Scripts/Physics/GetClosePointFromCollider.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
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 <detectedLength ; i++)
|
||||
{
|
||||
//reportBuilder.AppendLine($"----------------------------检测到了碰撞体{_mainCollider[i].name}");
|
||||
//var collider = _mainCollider[i];
|
||||
if (collider1.isTrigger)
|
||||
{
|
||||
reportBuilder?.AppendLine("碰撞体是触发器");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (collider1)
|
||||
{
|
||||
case MeshCollider meshCollider:
|
||||
if (meshCollider.convex is false)
|
||||
{
|
||||
reportBuilder?.AppendLine("MeshCollider未勾选Convex");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
var bounds = collider1.bounds;
|
||||
vector3 = collider1.ClosestPoint(Transform.position + Vector3.up * 64);
|
||||
var top = bounds.center.y + bounds.extents.y;
|
||||
Debug.DrawLine(Transform.position, Transform.position + Vector3.up * top, Color.blue, 8f);
|
||||
if (Transform.position.y + MinHeight > 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("<color=green>成功</color>");
|
||||
//BIT4Log.Log<GetClosePointFromCollider>(reportBuilder.ToString());
|
||||
return true;
|
||||
}
|
||||
|
||||
collider = null;
|
||||
//BIT4Log.Log<GetClosePointFromCollider>(reportBuilder.ToString());
|
||||
return false;
|
||||
}
|
||||
private float ByTop(Collider arg)
|
||||
{
|
||||
return arg.bounds.center.y + arg.bounds.extents.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user