UNITY小白:(思路向)做子弹穿透检测的
(本文提供只一种思路,没有头绪的同学可以借鉴)
子弹穿透,在很多游戏中都能见到。如武装突袭、CSGO等

这里我们不讨论VAC经历,只来研究子弹穿墙的原理。

如图,我们要求出红色线段的长度。但只有一条直线还不够,因此我们需要在“射线”末端再多加一条直线,反射回射线的起点。

如此,我们只需求那两两对应的穿透点组就行了。
代码如下
public Transform startPoint;
public Transform endPoint;
public LayerMask castLayer;
float standardDistance;
RaycastHit[] Hits;
RaycastHit[] ReHits;
bool haveHit;
// Start is called before the first frame update
void Start()
{
standardDistance = Vector3.Distance(startPoint.position, endPoint.position);
}
// Update is called once per frame
void Update()
{
Hits = Physics.RaycastAll(startPoint.position, endPoint.position - startPoint.position, standardDistance, castLayer);
ReHits = Physics.RaycastAll(endPoint.position, startPoint.position - endPoint.position, standardDistance, castLayer);
haveHit = (Hits.Length > 0);
}
void HaveSameCollider(Collider hitCollider, RaycastHit[] reRaycastHits, out bool haveSameCollider, out Vector3 ReHitPoint)
{
foreach (var hit in reRaycastHits)
{
if (hitCollider == hit.collider)
{
haveSameCollider = true;
ReHitPoint = hit.point;
return; //——————非常重要。此return能终止函数,不然foreach就会一直继续下去,最终结果只能都会是false;
}
}
haveSameCollider = false;
ReHitPoint = Vector3.zero;
} //此方法用于将hits中的hit一个个拎出来,将其的collider与目标集合对比,以达到寻找相同碰撞体的效果
private void OnDrawGizmos()
{
if(haveHit)
{
Gizmos.color = Color.green;
Gizmos.DrawLine(startPoint.position, endPoint.position);
foreach (var hit in Hits)
{
HaveSameCollider(hit.collider, ReHits, out bool haveSameCollider, out Vector3 RehitPoint);
if (haveSameCollider)
{
Gizmos.color = Color.red;
Gizmos.DrawSphere(hit.point, 0.05f);
Gizmos.color = Color.blue;
Gizmos.DrawSphere(RehitPoint, 0.05f);
}
}
}
}
结果如图:

当然,你们也可以在这个基础上自行添加想要的功能。