Moving fast causes physical bullets to spawn at an offset from player

Hey guys,

I’m having an issue where my projectile ridgedbody bullets are spawning away from the ‘bullet spawn point’ that I’ve setup in my game when the player is moving in any direction. ​For example, if the player is moving to the right, bullets will begin to spawn in further and further to the left the faster the player goes.

The bullet spawn point is a child game object attached to the ‘muzzle’ of the gun, and the gun game object is a child attached to the player game object.

I understand that this is ‘technically’ intended behavior, because that’s just how physic vectors work. But as you’ll see in the images below, the issue is more exaggerated than I was hoping for. I’m hoping to find a solution that makes the bullets spawn as close as possible to the gun while moving that’s physically reasonable.

When standing still it works fine, the bullets spawn in the correct position as seen in the image below.​

However, the bullets begin to spawn away from the gun when the player begins to move as seen in the image below.​

The faster the player begins to move, the more the issue exacerbates. The bullets spawn further and further away from the spawn point as seen in the image below.​

I’ve seen other posts regarding this issue and I’ve tried implementing their suggestions but to no avail.

For example:

  • I have bullet spawning is done in LateUpdate() and player movement done in Update()
  • I have also tried adding the players velocity to the bullets velocity when its spawned in.
    • bulletRigidbody.velocity = playerRigidbody.velocity + (transform.forward *speed);

    • Note this caused weird bullet behavior. Initially adding the players velocity to the bullet had basically zero effect, so I increased the weight of the players velocity by adding a x5 multiplier to it. this just cause the bullet to veer off to the left/right when moving.

    • bulletRigidbody.velocity = (playerController.velocity * 5.0f) + (transform.forward *speed);

  • Because the above did not work, I thought maybe the true solution would be to add the players velocity to the bullet spawn point rather than to the bullet itself. This also had basically no effect.

Code snippets:

GameManager Code:

 private void LateUpdate()
{
        playerShoot.updatePlayerShoot();
    }
 
    // MASTER UPDATE LOOP
    private void Update() 
{
        //player stuff
        playerInteractionManager.updateInteractionManager(gamepadConnected);
        weaponPull.weaponPullUpdate(gamepadConnected);
        weaponBob.updateWeaponBob(gamepadConnected);
        weaponSwapButton.updateSwapWeaponsButton();
 
        crosshairManager.updateCrosshair();
        autoAimArm.updateAutoAimArm();
 
        fpc.UpdateFPC(gamepadConnected); //update player turning
        fpc.UpdateFPCControls();         //player movement
 
        //camera effects
        cameraShake.updateCameraShake();
        gunCameraShake.updateCameraShake();
        horazontalCameraFOV.updateHorazontalCameraFOV();
 
        //game Systems
        gameTimerManager.updateIngameTimer();
        gamepadConnected = inputControlsManager.checkIfInputDeviceIsConnected();
 
        //objects and enemies
        enemyAIManager.updateEnemyAI();
        enemySquadManager.updateEnemySquads();
        billboardingManager.updateAllBilboardingScripts();
        videoControllerManager.updateVideoControllers();
    }

BulletSpawner:

private void prepareNextBullet(Transform target, float weaponSpreadRange)
    {
        aimAtTarget(target, weaponSpreadRange);
        newBullet = bulletObjectPool.getNextAvailableObject();
     
        newBullet.transform.rotation = this.transform.rotation;
        newBullet.transform.position = this.transform.position;
    }
 
    public void spawnPlayerBullet(Transform target, float weaponSpreadRange, int i = 0)
    {
        prepareNextBullet(target, weaponSpreadRange);
        bulletObjectPool.getCurrentAvailableAuxObject().setBulletProperties(playerWeaponDataForBullet, layerToHit, attackerReference, this.bulletSpeed, i);
        //Debug.Log("Spawner at: " + this.transform.position);
        newBullet.gameObject.SetActive(true);
    }

BulletProjectile:

// Start is called before the first frame update
    void OnEnable()
    {
        if (selfDestructCoroutine != null)
        {
            StopCoroutine(selfDestructCoroutine);
        }
 
        bulletRigidbody.velocity = transform.forward * speed;
        selfDestructCoroutine = StartCoroutine(selfDestruct());    
    }
 
public void setBulletProperties(S_WeaponData weaponData, int layerToHit, GameObject attacker, float speed, int i = 0)
    {
        resetRidgedBody();
        this.speed = speed;
        this.damage = weaponData.damage;
        this.layerToHit = layerToHit;
        this.attacker = attacker;
        this.playerWeaponDataForBullet = weaponData;
        this.bulletIndex = i;
 
    }

If anyone out there has any further insights into this issue that I could explore I would greatly appreciate it.​