3D 게임에서 목표물을 쏘는 알고리즘


11

Descent Freespace를 기억하는 사람들에게는 비 호환 미사일이나 레이저를 쏠 때 적을 조준하는 데 도움이되는 멋진 기능이 있습니다. 표적.

/programming/4107403/ai-algorithm-to-shoot-at-a-target-in-a-2d-game?lq=1 의 답변을 사용해 보았지만 2D 용이므로 시도했습니다. 그것을 적응시키는 것.

먼저 계산을 분해하여 XoZ 평면의 교점을 해결하고 x 및 z 좌표를 저장 한 다음 XoY 평면의 교점을 해결하고 y 좌표를 최종 xyz에 추가 한 다음 클립 공간으로 변환하고 텍스처를 배치했습니다. 좌표. 그러나 물론 그것은 질문을 게시하지 않았거나 그렇지 않은 것처럼 작동하지 않습니다.

XoZ 평면에서 x를 찾은 후 XoY에서 x를 찾은 후 알 수 있듯이 x는 같지 않으므로 무언가 잘못되어야합니다.

    float a = ENG_Math.sqr(targetVelocity.x) + ENG_Math.sqr(targetVelocity.y) -
            ENG_Math.sqr(projectileSpeed);
    float b = 2.0f * (targetVelocity.x * targetPos.x + 
            targetVelocity.y * targetPos.y);
    float c = ENG_Math.sqr(targetPos.x) + ENG_Math.sqr(targetPos.y);
    ENG_Math.solveQuadraticEquation(a, b, c, collisionTime);

처음 targetVelocity.y는 실제로 targetVelocity.z (targetPos와 동일)이고 두 번째는 실제로 targetVelocity.y입니다.

XoZ 이후의 최종 위치는

    crossPosition.set(minTime * finalEntityVelocity.x + finalTargetPos4D.x, 0.0f, 
                minTime * finalEntityVelocity.z + finalTargetPos4D.z);

XoY 이후

    crossPosition.y = minTime * finalEntityVelocity.y + finalTargetPos4D.y;

두 비행기로 분리하고 좋은 계산 방법을 사용합니까? 또는 3D의 경우 완전히 다른 접근법이 있습니까?

  • sqr ()은 sqrt가 아닌 square입니다-혼동을 피하십시오.

1
"목표를 선도"는 당신이 찾고있는 문구 일 수 있습니다.
MichaelHouse

답변:


12

그것을 2 2d 기능으로 나눌 필요가 없습니다. 작업중 인 2 차 방정식은 3D에서도 잘 작동합니다. 다음은 2d 또는 3d에 대한 의사 코드입니다. 그것은 타워 (타워 방어)가 발사체를 쏘고 있음을 의미합니다.

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second 

'aimSpot'은 원하는 벡터 일 수 있습니다.


당신은 천재이고 내 엉덩이를 구했습니다! 젠장, 난
공평하게

@SebastianBugiu 나는 당신을 위해 그것을했다.
AgentFire

@SebastianBugiu 고마워, 나는이 개념을 배웠을 때 기뻤고 그 도움이되어 기쁘다. 그것의 또 다른 우아한 기능은 충돌 감지 알고리즘으로 엉망이 될 필요가 없다는 것입니다. CD 코드를 작성할 필요가 없습니다. 목표 경로와 발사체 경로를 예측할 수 있기 때문에 timeToImpact0으로 카운트 다운 하면 영향이 발생 합니다.
Steve H

1

같은 주제에 관한 좋은 블로그 게시물이 있습니다 : http://playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html . 또한 중력을 포함하는 더 복잡한 샘플도 포함합니다.

저자는 더 단순화하여 코드가 더 간결 해졌습니다.

double time_of_impact(double px, double py, double vx, double vy, double s)
{
    double a = s * s - (vx * vx + vy * vy);
    double b = px * vx + py * vy;
    double c = px * px + py * py;

    double d = b*b + a*c;

    double t = 0;
    if (d >= 0)
    {
        t = (b - sqrt(d)) / a;
        if (t < 0) 
        {
            t = (b + sqrt(d)) / a;
            if (t < 0)
                t = 0;
        }
    }

    return t;
}

업데이트 : 원래 저자는 더 큰 루트만을 고려했습니다. 그러나 루트가 작을수록 음이 아닌 경우 영향 시간이 짧아 지므로 더 나은 솔루션이됩니다. 해당 코드를 업데이트했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.