Calculating BulletProjectile Wrong?

Hi Hugo, great course, I am learning a lot about code architecture this week!

I have a quick concern regarding how you are calculating the BulletProjectile’s distance to target. I think the way you wrote it still allows for overshooting of the target. For example, if distanceBeforeMoving = 150 units, then the projectile will be moved 200 units this frame, and distanceAfterMoving will be 50 units, but in the wrong direction past our target. However, distanceBeforeMoving will be greater than distanceAfterMoving on that frame in this scenario, and will therefor shoot past our target.

I observed some overshooting sometimes when I implemented your code, then sat down and thought about it, and that’s the conclusion I came up with. Apologies in advance if I am missing something!

I have slightly refactored your code to stop the projectile by checking the remaining distance to target and forgoing the concept of overshooting altogether:

    private void Update()
    {
        Vector3 moveDirection = (targetPosition - transform.position).normalized;

        float distanceFromTarget = Vector3.Distance(transform.position, targetPosition);

        float moveSpeed = 200f;

        if (distanceFromTarget <= moveSpeed)
        {
            transform.position = targetPosition;

            trailRenderer.transform.SetParent(null);

            Destroy(this);

            Instantiate(bulletHitVFXPrefab, transform.position, Quaternion.identity);
        }
        else
        {
            transform.position += moveDirection * moveSpeed * Time.deltaTime;
        }
    }

Cheers,
-Chris

4 Likes

I also wasn’t happy with this. What I did was to calculate the new position, then check if the new position will overshoot the target, then adjust the new position to not overshoot. then apply the new position

    private void Update()
    {
        if (!_inFlight) return;

        var toTarget = (_targetPoint - transform.position);
        var moveDirection = toTarget.normalized;
        var distanceToTarget = Vector3.Distance(transform.position, _targetPoint);

        var moveSpeed = 200f;
        var moveDist = moveDirection * moveSpeed * Time.deltaTime;
        if (moveDist.magnitude > distanceToTarget) moveDist = toTarget;

        transform.position += moveDist;

        if (Vector3.Distance(transform.position, _targetPoint) < 0.1f)
            DoBulletHitVisual();
    }
2 Likes

Indeed, the video’s code only works for half of the cases. In the other half, the bullet will overshoot by one frame, and then the working case will catch it on the next frame, and destroy it. This looks like an overshoot every so often, about 50% of the time, and fairly random due to varying frame rates.

This is fundamentally the same problem as seen with the moving “glitch”. A good solution was presented here: An alternative to reach the destination

Near-identical code works here and solves the problem:

    private void Update()
    {
        var toTarget = _targetPosition - transform.position;
        var dist = toTarget.magnitude;

        if (dist > 0)
        {
            var move = toTarget.normalized * (moveSpeed * Time.deltaTime);
            if (move.magnitude > dist)
            {
                move = toTarget;
            }
            transform.position += move;
        }
        else
        {
            Destroy(gameObject);
        }
    }
2 Likes

Tried your solution and sure enough it works, thanks!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms