2024-03-04 18:45:21 +08:00
|
|
|
using System;
|
2024-01-23 02:56:26 +08:00
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
|
|
namespace BITKit
|
|
|
|
{
|
|
|
|
public interface IClosePoint
|
|
|
|
{
|
|
|
|
bool TryGetClosePoint(out Vector3 vector3);
|
|
|
|
}
|
|
|
|
[System.Serializable]
|
|
|
|
public class GetClosePointFromCollider : IClosePoint
|
|
|
|
{
|
|
|
|
public Transform root;
|
|
|
|
public LayerMask layerMask;
|
|
|
|
public float distance;
|
|
|
|
public bool TryGetClosePoint(out Vector3 vector3)
|
|
|
|
{
|
|
|
|
vector3 = default;
|
|
|
|
if (UnityEngine.Physics.Raycast(root.position, root.forward, out var raycastHit, distance, layerMask))
|
|
|
|
{
|
|
|
|
var collider = raycastHit.collider;
|
|
|
|
switch (collider)
|
|
|
|
{
|
|
|
|
case MeshCollider meshCollider:
|
|
|
|
if (meshCollider.convex is false)
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
vector3 = collider.ClosestPoint(root.position + Vector3.up);
|
|
|
|
var top = collider.bounds.center + collider.bounds.extents;
|
|
|
|
|
|
|
|
if (Mathf.Abs(vector3.y - top.y) > 0.16f) return false;
|
|
|
|
|
|
|
|
if (UnityEngine.Physics.Linecast(root.position, vector3, out var raycastHit2, layerMask))
|
|
|
|
{
|
|
|
|
if(raycastHit2.collider != collider)
|
|
|
|
return false;
|
|
|
|
};
|
2024-03-04 18:45:21 +08:00
|
|
|
foreach(var hit in UnityEngine.Physics.OverlapSphere(vector3, 0.1f, layerMask))
|
|
|
|
{
|
|
|
|
if(hit!= collider)
|
|
|
|
return false;
|
|
|
|
}
|
2024-01-23 02:56:26 +08:00
|
|
|
return true;
|
|
|
|
//return vector3.y >= collider.bounds.center.y + collider.bounds.extents.y;
|
|
|
|
//return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2024-03-04 18:45:21 +08:00
|
|
|
/// <summary>
|
|
|
|
/// 获取碰撞点可以翻越后的点
|
|
|
|
/// </summary>
|
|
|
|
[Serializable]
|
|
|
|
public class GetVaultPointFromCollider : IClosePoint
|
|
|
|
{
|
|
|
|
public Transform root;
|
|
|
|
public Transform groundReference;
|
|
|
|
public LayerMask layerMask;
|
|
|
|
public float maxHeight = 1.2f;
|
|
|
|
public float maxVaultDistance=1;
|
|
|
|
public float radius;
|
|
|
|
public float distance;
|
|
|
|
|
|
|
|
public Vector3 StartPosition;
|
|
|
|
public Vector3 EndPosition;
|
|
|
|
|
|
|
|
public bool TryGetClosePoint(out Vector3 vector3)
|
|
|
|
{
|
|
|
|
var reportBuilder = new System.Text.StringBuilder();
|
|
|
|
|
|
|
|
var forward = root.forward;
|
|
|
|
var startPosition = groundReference.position;
|
|
|
|
startPosition.y = root.position.y;
|
|
|
|
|
|
|
|
var collider = UnityEngine.Physics.OverlapSphere(startPosition, radius, layerMask);
|
|
|
|
|
|
|
|
reportBuilder.AppendLine($"检测到了{collider.Length}个碰撞体");
|
|
|
|
|
|
|
|
foreach (var hit in collider)
|
|
|
|
{
|
|
|
|
reportBuilder.AppendLine();
|
|
|
|
|
|
|
|
var top = hit.bounds.center + hit.bounds.extents;
|
|
|
|
|
|
|
|
if(top.y>groundReference.transform.position.y+maxHeight)
|
|
|
|
{
|
|
|
|
reportBuilder.AppendLine("高度超出可翻越高度");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
var start = startPosition+forward*distance;
|
|
|
|
//start.y = hit.bounds.center.y;
|
|
|
|
|
|
|
|
var ray = new Ray(start, -forward);
|
|
|
|
|
|
|
|
if (hit.Raycast(ray, out var colliderHit, 8) is false)
|
|
|
|
{
|
|
|
|
reportBuilder.AppendLine("未检测到背面,算法错误");
|
|
|
|
|
|
|
|
Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
EndPosition = colliderHit.point + colliderHit.normal*0.4f;
|
|
|
|
EndPosition.y = top.y;
|
|
|
|
|
|
|
|
Debug.DrawLine(ray.origin, colliderHit.point, Color.green, 8);
|
|
|
|
var lineDistance = Vector3.Distance(start, colliderHit.point);
|
|
|
|
if(lineDistance > maxVaultDistance)
|
|
|
|
{
|
|
|
|
reportBuilder.AppendLine("长度超出可翻越距离");
|
|
|
|
|
|
|
|
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
var fixdPosition = colliderHit.point;
|
|
|
|
fixdPosition.y=hit.bounds.center.y;
|
|
|
|
var start2 = fixdPosition;
|
|
|
|
start2.y += 0.1f;
|
|
|
|
var end2 = fixdPosition;
|
|
|
|
end2.y -= 0.1f;
|
|
|
|
if(UnityEngine.Physics.Linecast(start2,end2,out var downHit,layerMask))
|
|
|
|
{
|
|
|
|
reportBuilder.AppendLine($"检测到了障碍物{downHit.collider.name}");
|
|
|
|
|
|
|
|
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = startPosition;
|
|
|
|
|
|
|
|
start.y = hit.bounds.center.y;
|
|
|
|
ray = new Ray(start, forward);
|
|
|
|
if(hit.Raycast(ray,out colliderHit,8) is false)
|
|
|
|
{
|
|
|
|
reportBuilder.AppendLine("未检测到正面,算法错误");
|
|
|
|
Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
StartPosition = colliderHit.point;
|
|
|
|
StartPosition.y = top.y;
|
|
|
|
StartPosition += colliderHit.normal * 0.4f;
|
|
|
|
|
|
|
|
vector3 = colliderHit.point;
|
|
|
|
|
|
|
|
|
|
|
|
vector3.y = top.y;
|
|
|
|
|
|
|
|
vector3 += colliderHit.normal * 0.4f;
|
|
|
|
|
|
|
|
reportBuilder.AppendLine();
|
|
|
|
|
|
|
|
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
reportBuilder.AppendLine($"failed");
|
|
|
|
|
|
|
|
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
|
|
|
|
|
|
|
vector3 = default;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2024-01-23 02:56:26 +08:00
|
|
|
}
|