Tôi đã triển khai chương trình quét AABBvsAABB 2D vào trò chơi của mình, tuy nhiên, tôi gặp khó khăn khi tính toán mức độ bình thường của lượt quét.
Tôi có hướng quét, cả vị trí AABB a và b và xy min-max, lần đánh đầu tiên và lần cuối để làm việc, nhưng không phải là (các) cạnh va chạm hoặc hướng thông thường. Tôi chỉ không thể khái niệm một giải pháp hiệu quả cho vấn đề cụ thể này. Bất kỳ ý tưởng? :)
*biên tập
Đây là những gì tôi có cho đến nay - chỉ là một triển khai chung của quét AABB của Gomez và Christer Ericson . Không có cú đánh bình thường, vì vậy trong khi tính toán bình thường là một bí ẩn đối với tôi, tôi không thể tạo ra bất kỳ phản ứng va chạm nào cho bộ điều khiển nhân vật của mình.
bool SweepVelAABBvsAABB(AABB a, AABB b, Vector2 v, out Vector2 outVel, out Vector2 norm )
{
outVel = v; //Initialise out velocity
norm = Vector2.zero;
if( AABBvsAABB(a,b) ) return true; //return early if a,b overlap
v = -v;
float hitTime = 0.0f;
float outTime = 1.0f;
if(v.x < 0.0f) //sweep is going right
{
if(b.max.x < a.min.x) return false;
if(a.max.x < b.min.x) hitTime = Mathf.Max( (a.max.x - b.min.x) / v.x, hitTime );
if(b.max.x > a.min.x) outTime = Mathf.Min( (a.min.x - b.max.x) / v.x, outTime );
}
else if(v.x > 0.0f) //sweep is going left
{
if(b.min.x > a.max.x) return false;
if(b.max.x < a.min.x) hitTime = Mathf.Max( (a.min.x - b.max.x) / v.x, hitTime );
if(a.max.x > b.min.x) outTime = Mathf.Min( (a.max.x - b.min.x) / v.x, outTime );
}
if(hitTime > outTime) return false;
//=================================
if(v.y < 0.0f) //sweep is going up
{
if(b.max.y < a.min.y) return false;
if(a.max.y < b.min.y) hitTime = Mathf.Max( (a.max.y - b.min.y) / v.y, hitTime );
if(b.max.y > a.min.y) outTime = Mathf.Min( (a.min.y - b.max.y) / v.y, outTime );
}
else if(v.y > 0.0f) //sweep is going down
{
if(b.min.y > a.max.y) return false;
if(b.max.y < a.min.y) hitTime = Mathf.Max( (a.min.y - b.max.y) / v.y, hitTime );
if(a.max.y > b.min.y) outTime = Mathf.Min( (a.max.y - b.min.y) / v.y, outTime );
}
if(hitTime > outTime) return false;
outVel = -v * hitTime;
return true;
}