This commit is contained in:
CortexCore
2024-05-31 01:23:15 +08:00
parent c798b224be
commit 299082fe27
164 changed files with 3604 additions and 2018 deletions

View File

@@ -3,59 +3,140 @@ using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using UnityEngine;
namespace BITKit
{
public interface IClosePoint
{
Vector3 CurrentPoint { get; }
Collider Collider { get; }
bool TryGetClosePoint(out Vector3 vector3);
}
[System.Serializable]
[Serializable]
public class GetClosePointFromCollider : IClosePoint
{
public Transform root;
public LayerMask layerMask;
public float distance;
[SerializeField] private string name;
[SerializeField] private Transform transform;
[SerializeField] private Vector3 offset = Vector3.one;
[SerializeField] private LayerMask layerMask;
[SerializeField] private float distance;
[SerializeField] private float minHeight=0.32f;
[SerializeField] private float maxHeight = 1f;
public Vector3 CurrentPoint { get; set; }
public Collider Collider { get; set; }
private Collider[] _colliders=new Collider[8];
private Collider[] _mainCollider=new Collider[8];
public bool TryGetClosePoint(out Vector3 vector3)
{
vector3 = default;
if (UnityEngine.Physics.Raycast(root.position, root.forward, out var raycastHit, distance, layerMask))
StringBuilder reportBuilder = new();
reportBuilder.AppendLine($"检测任务:{name}");
var position = transform.position + transform.rotation * offset;
var detectedLength = Physics.OverlapSphereNonAlloc(position, distance, _mainCollider, layerMask);
reportBuilder.AppendLine($"检测到了{detectedLength}个碰撞体");
foreach (var collider in _mainCollider.Take(detectedLength).OrderBy(ByTop).Reverse())
//for (var i = 0; i <detectedLength ; i++)
{
var collider = raycastHit.collider;
if (collider.isTrigger) return false;
//reportBuilder.AppendLine($"----------------------------检测到了碰撞体{_mainCollider[i].name}");
//var collider = _mainCollider[i];
if (collider.isTrigger)
{
reportBuilder?.AppendLine("碰撞体是触发器");
continue;
}
switch (collider)
{
case MeshCollider meshCollider:
if (meshCollider.convex is false)
return false;
{
reportBuilder?.AppendLine("MeshCollider未勾选Convex");
continue;
}
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))
var bounds = collider.bounds;
vector3 = collider.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)
{
if(raycastHit2.collider != collider)
return false;
};
foreach(var hit in UnityEngine.Physics.OverlapSphere(vector3, 0.1f, layerMask))
{
if(hit!= collider)
return false;
reportBuilder?.AppendLine("高度不足");
continue;
}
var nextPos = position;
nextPos.y = collider.bounds.center.y;
if (collider.Raycast(new Ray(nextPos, transform.forward), out _, distance) is false)
{
reportBuilder?.AppendLine("未检测到前方");
continue;
}
var height = Mathf.Abs(top - transform.position.y);
if (height > maxHeight)
{
reportBuilder?.AppendLine($"高度差距过大:{height}");
continue;
}
if (Physics.Linecast(transform.position, vector3, out var raycastHit2, layerMask))
{
if (raycastHit2.collider != collider)
{
reportBuilder?.AppendLine($"检测到了其他碰撞体:{raycastHit2.transform.name}");
continue;
}
}
;
var length = Physics.OverlapSphereNonAlloc(vector3, 0.01f, _colliders, layerMask);
switch (length)
{
case 1:
if (_colliders[0] != collider)
{
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;
}
Collider = collider;
vector3.y = top;
CurrentPoint = vector3;
reportBuilder.AppendLine("<color=green>成功</color>");
//BIT4Log.Log<GetClosePointFromCollider>(reportBuilder.ToString());
return true;
//return vector3.y >= collider.bounds.center.y + collider.bounds.extents.y;
//return true;
}
//BIT4Log.Log<GetClosePointFromCollider>(reportBuilder.ToString());
return false;
}
private float ByTop(Collider arg)
{
return arg.bounds.center.y + arg.bounds.extents.y;
}
}
/// <summary>
/// 获取碰撞点可以翻越后的点
@@ -74,6 +155,7 @@ namespace BITKit
public Vector3 StartPosition;
public Vector3 EndPosition;
public Vector3 CurrentPoint { get; set; }
public Collider Collider { get; set; }
private Rigidbody rigidbody;
@@ -92,7 +174,8 @@ namespace BITKit
if (rigidbody.velocity.GetLength() < 0.1f) return false;
}
var reportBuilder = new System.Text.StringBuilder();
//var reportBuilder = new System.Text.StringBuilder();
StringBuilder reportBuilder=null;
var forward = root.forward;
var sourceStartPosition = groundReference.position;
@@ -101,7 +184,7 @@ namespace BITKit
var collider = UnityEngine.Physics.OverlapSphere(startPosition, radius, layerMask);
reportBuilder.AppendLine($"检测到了{collider.Length}个碰撞体");
reportBuilder?.AppendLine($"检测到了{collider.Length}个碰撞体");
foreach (var hit in collider)
{
@@ -112,12 +195,12 @@ namespace BITKit
continue;
}
reportBuilder.AppendLine();
reportBuilder.AppendLine($">{hit.name}");
reportBuilder?.AppendLine();
reportBuilder?.AppendLine($">{hit.name}");
if(top.y>groundReference.transform.position.y+maxHeight)
{
reportBuilder.AppendLine("高度超出可翻越高度");
reportBuilder?.AppendLine("高度超出可翻越高度");
continue;
}
@@ -128,9 +211,9 @@ namespace BITKit
if (hit.Raycast(ray, out var colliderHit, 8) is false)
{
reportBuilder.AppendLine("未检测到背面,算法错误");
reportBuilder?.AppendLine("未检测到背面,算法错误");
Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
//Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
continue;
}
@@ -151,15 +234,15 @@ namespace BITKit
}
catch (OperationCanceledException e)
{
reportBuilder.AppendLine(e.Message);
reportBuilder?.AppendLine(e.Message);
continue;
}
if(UnityEngine.Physics.Raycast(EndPosition,Vector3.down,out _,1.6f,layerMask) is false)
{
Debug.DrawRay(EndPosition, Vector3.down*1.6f, Color.red, 8);
reportBuilder.AppendLine("未检测到地面,跳过");
//Debug.DrawRay(EndPosition, Vector3.down*1.6f, Color.red, 8);
reportBuilder?.AppendLine("未检测到地面,跳过");
continue;
//Debug.DrawRay(EndPosition, Vector3.down, Color.red, 8);
}
@@ -174,7 +257,7 @@ namespace BITKit
end2.y -= 0.1f;
if(UnityEngine.Physics.Linecast(start2,end2,out var downHit,layerMask))
{
reportBuilder.AppendLine($"检测到了障碍物{downHit.collider.name}");
reportBuilder?.AppendLine($"检测到了障碍物{downHit.collider.name}");
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
continue;
@@ -186,8 +269,8 @@ namespace BITKit
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);
reportBuilder?.AppendLine("未检测到正面,算法错误");
//Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
continue;
}
@@ -200,14 +283,26 @@ namespace BITKit
var lineDistance = Vector3.Distance(closeStart, closeEnd);
if(lineDistance > maxVaultDistance)
{
reportBuilder.AppendLine($"长度{lineDistance}超出可翻越距离{maxVaultDistance}");
reportBuilder?.AppendLine($"长度{lineDistance}超出可翻越距离{maxVaultDistance}");
Debug.DrawLine(closeStart,closeEnd, Color.yellow, 4);
//Debug.DrawLine(closeStart,closeEnd, Color.yellow, 4);
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
continue;
}
if(Physics.Linecast(closeStart+Vector3.up*0.1f,closeEnd+Vector3.up*0.1f,out var _hit,layerMask))
{
//Debug.DrawLine(closeStart+Vector3.up*0.1f,_hit.point, Color.red, 4);
reportBuilder?.AppendLine("检测到了障碍物");
continue;
}
else
{
//Debug.DrawLine(closeStart+Vector3.up*0.1f,closeEnd+Vector3.up*0.1f, Color.green, 4);
}
vector3 = colliderHit.point;
@@ -215,14 +310,19 @@ namespace BITKit
vector3 += colliderHit.normal * 0.4f;
reportBuilder.AppendLine();
reportBuilder?.AppendLine();
if(reportBuilder is not null)
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
CurrentPoint = vector3;
Collider = hit;
return true;
}
reportBuilder.AppendLine($"failed");
reportBuilder?.AppendLine($"failed");
if(reportBuilder is not null)
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
vector3 = default;