void UpdateLockFire()
    {
        // Initial lock-on check
        if (Tools.NearlyEqual(weaponCooldownCounter, 0, 0.01f) && buttonDown)
        {
            if (targetedCharacter != null)
            {
                Debug.LogWarning("Got fire-button-down but lock-target is already set, did we miss a fire-button-up event?");
                targetedCharacter = null;
                lockedOnTarget    = false;
            }
            // I'm not a performance expert but it may be best to just iterate over all players and see who's in scope.
            // Any targetable object will have an angle less than 1+maxAngle anyway, so this is like setting it to infinity:
            currentSharpestTargetAngle = 1 + MaxAngleToBeTargeted();
            foreach (Player player in PhotonNetwork.PlayerList)
            {
                if (NetworkCharacter.IsLocalPlayer(player) || !NetworkCharacter.IsPlayerAlive(player))
                {
                    continue;
                }
                TargetableCharacter playerTarget = NetworkCharacter.GetPlayerGameObject(player).GetComponent <TargetableCharacter>();
                SwitchToTargetIfCloserToCenter(playerTarget);
            }
            // If a dummy character is spawned it won't be in the player list but it should be targeted anyway
            if (UserDefinedConstants.spawnDummyPlayer && NetworkManager.DummyPlayer != null)
            {
                TargetableCharacter playerTarget = NetworkManager.DummyPlayer.GetComponent <TargetableCharacter>();
                SwitchToTargetIfCloserToCenter(playerTarget);
            }

            // Lock on to found character, if found
            if (targetedCharacter != null)
            {
                StartTargeting(targetedCharacter);
            }

            // In any case, player will now fire on button release
            fireOnButtonUp = true;
        }

        // Stop targeting if:
        // 1. We are currently targeting and not locked on yet
        // 2. Either the player can no longer be targeted, or we're not pressing the fire button anymore
        if (targetedCharacter != null && !lockedOnTarget && (!CanBeTargeted(targetedCharacter) || !buttonPressed))
        {
            StopTargeting(targetedCharacter);
        }

        // When targeting completes it's handled in the Action passed to StartTargeting

        // If user pressed the button after weapon cooldown and we got button up, now fire
        if (fireOnButtonUp && buttonUp)
        {
            fireOnButtonUp        = false;
            weaponCooldownCounter = UserDefinedConstants.weaponCooldown;
            if (lockedOnTarget)
            {
                FireSeekingProjectile();
            }
            else
            {
                // If we didn't lock on, then we're no longer targeting anyone
                if (targetedCharacter != null)
                {
                    StopTargeting(targetedCharacter);
                }
                FireProjectileMaxImpulse();
            }
            // Either way, locally, we're no longer targeting anyone (don't keep the indicator for the target of a fired projectile)
            LocalStopTargeting();
        }
    }