Example #1
0
    private IEnumerator TrackTactic(Track track)
    {
        GuidanceModule guidance = GetComponent <GuidanceModule>();

        if (guidance != null)
        {
            while (track != null && track.isLost == false && track.identification != TrackId.Neutrual)
            {
                // If original track is lost or missing, we will change our target.
                // If original track is identified as neutral (counter-measures will all be neutral).
                // If the new track is very close to the original track, the missile might consider that as the true target.
                if (guidance.targetTrack == null || guidance.targetTrack.isLost || guidance.targetTrack.identification == TrackId.Neutrual ||
                    (UnityEngine.Random.Range(0f, 100f) > 25f && Vector3.Distance(guidance.targetTrack.predictedPosition, track.predictedPosition) < 200f))
                {
                    if (guidance.guidanceParameter != null)
                    {
                        Vector3 predictedPosition = (Vector3)guidance.guidanceParameter;
                        float   positionError     = Vector3.Distance(predictedPosition, track.predictedPosition);
                        yield return(new WaitForSeconds(Mathf.Min(positionError * 0.0002f, 5.0f)));

                        if (guidance.targetTrack == null || guidance.targetTrack.isLost || guidance.targetTrack.identification == TrackId.Neutrual)
                        {
                            guidance.SetupGuidance(track, null);
                            WarheadModule warhead = GetComponent <WarheadModule>();
                            if (warhead != null)
                            {
                                warhead.SetupTarget(track);
                            }
                            yield return(new WaitForSeconds(4f));

                            yield return(null);
                        }
                    }
                    else
                    {
                        guidance.SetupGuidance(track, null);
                        WarheadModule warhead = GetComponent <WarheadModule>();
                        if (warhead != null)
                        {
                            warhead.SetupTarget(track);
                        }
                        yield return(new WaitForSeconds(4f));

                        yield return(null);
                    }
                }
                else
                {
                    yield return(new WaitForSeconds(1f));
                }
                yield return(null);
            }
        }
    }
Example #2
0
    private IEnumerator TrackTactic(Track track)
    {
        GuidanceModule guidance = GetComponent <GuidanceModule>();

        if (guidance != null)
        {
            while (track != null && track.isLost == false && track.identification != TrackId.Neutrual)
            {
                // If original track is lost or missing, we will change our target.
                // If original track is identified as neutral (counter-measures will all be neutral).
                // If the new track is very close to the original track, the missile might consider that as the true target.
                if (guidance.targetTrack == null || guidance.targetTrack.isLost || guidance.targetTrack.identification == TrackId.Neutrual)
                {
                    if (guidance.targetTrack != null)
                    {
                        // Sort priority by distance error.
                        yield return(new WaitForSeconds(Mathf.Min(Vector3.Distance(guidance.targetTrack.predictedPosition, track.predictedPosition) * 0.0004f, 4f)));
                    }
                    if (guidance.targetTrack == null || guidance.targetTrack.isLost || guidance.targetTrack.identification == TrackId.Neutrual)
                    {
                        if (UnityEngine.Random.Range(0f, 100f) > 20f)
                        {
                            guidance.SetupGuidance(track, null);
                            WarheadModule warhead = GetComponent <WarheadModule>();
                            if (warhead != null)
                            {
                                warhead.SetupTarget(track);
                            }
                            yield return(new WaitForSeconds(0.2f));
                        }
                    }
                }
                yield return(new WaitForSeconds(UnityEngine.Random.Range(0.2f, 0.5f)));
            }
        }
    }
    public override void OnFixedUpdate(float deltaTime)
    {
        if (hasInitiallyDisabled == false)
        {
            self.sensorCtrl.ToggleAll(false, true);
            hasInitiallyDisabled = true;
        }

        if (targetTrack != null && targetTrack.isLost == false)
        {
            if (lastActualDistance == -1f)
            {
                lastActualDistance = Vector3.Distance(targetTrack.target.position, self.position);
            }

            float actualDistance = Vector3.Distance(targetTrack.target.position, self.position);

            float distance = Vector3.Distance(targetTrack.predictedPosition, self.position);
            if (distance < enableDistance)
            {
                if (hasEnabled == false)
                {
                    self.sensorCtrl.ToggleAll(true, true);
                    hasEnabled = true;
                }
            }

            float eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(0)) / (self.fuel > 0 ? self.maxSpeed : self.speed);
            eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(eta)) / (self.fuel > 0 ? self.maxSpeed : self.speed);
            eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(eta)) / (self.fuel > 0 ? self.maxSpeed : self.speed);
            eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(eta)) / (self.fuel > 0 ? self.maxSpeed : self.speed);

            Vector3 predictedPosition  = targetTrack.predictedPositionAtTime(eta);
            float   horizontalDistance = Mathf.Sqrt(Mathf.Pow(predictedPosition.z - self.position.z, 2) + Mathf.Pow(predictedPosition.x - self.position.x, 2));
            predictedPosition.y += loftCoefficient * horizontalDistance * horizontalDistance / Vehicle.sVehicleRanges[self.typeName];

            // Pitch Guidance.
            float expectedPitch = Mathf.Rad2Deg * Mathf.Atan2(predictedPosition.y - self.position.y, horizontalDistance);
            self.locomotor.orderedPitch = expectedPitch;

            // Yaw Guidance.
            float expectedCourse = Mathf.Rad2Deg * Mathf.Atan2(predictedPosition.x - self.position.x, predictedPosition.z - self.position.z);
            self.locomotor.orderedCourse = expectedCourse;

            WarheadModule warhead = self.GetComponent <WarheadModule>();
            if (lastActualDistance < actualDistance && Time.time - warhead.timeOfLaunch > warhead.safetyTimer && distance < warhead.proximityRange * 100f)
            {
                if (lastActualDistance < warhead.damageRadius * 5f || UnityEngine.Random.Range(0, 100) > 75)
                {
                    self.GetComponent <WarheadModule>().Ignite();
                }
                else
                {
                    self.GetComponent <WarheadModule>().Shutdown();
                }
            }
            else if (self.fuel <= 0 && self.speed < targetTrack.velocity.magnitude * 0.9f)
            {
                self.GetComponent <WarheadModule>().Shutdown();
            }

            lastActualDistance = actualDistance;
        }
        else if (guidanceParameter != null)
        {
            Vector3 predictedPosition = (Vector3)guidanceParameter;
            if (lastPredictDistance == -1f)
            {
                lastPredictDistance = Vector3.Distance(predictedPosition, self.position);
            }

            float horizontalDistance = Mathf.Sqrt(Mathf.Pow(predictedPosition.z - self.position.z, 2) + Mathf.Pow(predictedPosition.x - self.position.x, 2));
            predictedPosition.y += loftCoefficient * horizontalDistance * horizontalDistance / Vehicle.sVehicleRanges[self.typeName];

            // Pitch Guidance.
            float expectedPitch = Mathf.Rad2Deg * Mathf.Atan2(predictedPosition.y - self.position.y, horizontalDistance);
            self.locomotor.orderedPitch = expectedPitch;

            // Yaw Guidance.
            float expectedCourse = Mathf.Rad2Deg * Mathf.Atan2(predictedPosition.x - self.position.x, predictedPosition.z - self.position.z);
            self.locomotor.orderedCourse = expectedCourse;

            float predictDistance = Vector3.Distance(predictedPosition, self.position);
            if (predictDistance < enableDistance)
            {
                if (hasEnabled == false)
                {
                    self.sensorCtrl.ToggleAll(true, true);
                    hasEnabled = true;
                }
            }
            if (lastPredictDistance < predictDistance && predictDistance < self.speed)
            {
                if (selfDestructAfterMissingTarget)
                {
                    self.GetComponent <WarheadModule>().Ignite();
                }
            }
            lastPredictDistance = predictDistance;
        }
        else
        {
            if (selfDestructAfterLostTrack || targetTrack == null)
            {
                if (selfDestructCounter == 0)
                {
                    self.GetComponent <WarheadModule>().Shutdown();
                }
                else
                {
                    selfDestructCounter--;
                }
            }
            else
            {
                // We have a track but it's lost so we just keep moving towards the predicted rendezvous point.
                float eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(0)) / (self.fuel > 0 ? self.maxSpeed : self.speed);
                eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(eta)) / (self.fuel > 0 ? self.maxSpeed : self.speed);
                eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(eta)) / (self.fuel > 0 ? self.maxSpeed : self.speed);
                eta = Vector3.Distance(self.position, targetTrack.predictedPositionAtTime(eta)) / (self.fuel > 0 ? self.maxSpeed : self.speed);

                SetupGuidance(null, targetTrack.predictedPositionAtTime(eta));
            }
        }
    }
Example #4
0
    public bool Launch(string vehicleName, Track target)
    {
        if (enabled == false)
        {
            return(false);
        }
        if (isLoaded == false && currentSalvoCount == 0)
        {
            return(false);
        }
        if (vehicleNames.Contains(vehicleName) == false)
        {
            return(false);
        }
        if (vehicleCounts[vehicleNames.IndexOf(vehicleName)] <= 0)
        {
            return(false);
        }
        GameObject vehicle = ResourceManager.LoadPrefab(Vehicle.sVehiclePrefabPaths[vehicleName]);

        float eta = Vector3.Distance(this.transform.position, target.predictedPositionAtTime(0)) / Vehicle.sVehicleMaxSpeed[vehicleName] / 0.9f;

        eta = Vector3.Distance(this.transform.position, target.predictedPositionAtTime(eta)) / Vehicle.sVehicleMaxSpeed[vehicleName] / 0.9f;
        eta = Vector3.Distance(this.transform.position, target.predictedPositionAtTime(eta)) / Vehicle.sVehicleMaxSpeed[vehicleName] / 0.9f;

        GuidanceModule guidance = vehicle.GetComponent <GuidanceModule>();

        if (guidance == null)
        {
            Debug.Log("Vehicle that can be launched should have GuidanceModule.");
        }
        else
        {
            if (guidance.requiresLockBeforeFiring == true)
            {
                guidance.SetupGuidance(target, null);

                if (vehicle.GetComponent <Vehicle>().sensorCtrl != null)
                {
                    vehicle.GetComponent <Vehicle>().sensorCtrl.AddTrack(target);
                }

                WarheadModule warhead = vehicle.GetComponent <WarheadModule>();
                if (warhead != null)
                {
                    warhead.SetupTarget(target);
                }

                // Fill track information via data-link if possible.
                // (even if this weapon already requires locking, which means the track information will be provided by the launcher).
                if (vehicle.GetComponent <DatalinkModule>() != null)
                {
                    if (vehicle.GetComponent <DatalinkModule>().isDuplex)
                    {
                        vehicle.GetComponent <DatalinkModule>().AddReceiver(self);
                    }

                    foreach (DatalinkModule dl in self.GetComponents <DatalinkModule>())
                    {
                        if (dl.limitTrackedVehicleType == false || dl.trackedVehicleType == Vehicle.sVehicleTypes[target.vehicleTypeName])
                        {
                            dl.AddReceiver(vehicle.GetComponent <Vehicle>());
                        }
                    }
                }
            }
            else
            {
                GameObject.Destroy(vehicle);

                bool isLaunched = Launch(vehicleName, target.predictedPositionAtTime(eta), target);
                if (isLaunched)
                {
                    Vehicle launchedVehicle = SceneManager.instance.vehicles[SceneManager.instance.vehicles.Count - 1];
                    launchedVehicle.GetComponent <WarheadModule>().SetupTarget(target);

                    // Fill track information via data-link if possible.
                    if (launchedVehicle.GetComponent <DatalinkModule>() != null)
                    {
                        Track launchedVehicleOwnTrack = new Track(launchedVehicle, target.target, TrackId.Unknown);
                        launchedVehicleOwnTrack.UpdateTrack(target.position, target.velocity, target.timeOfLastUpdate, target.identification);
                        launchedVehicle.sensorCtrl.AddTrack(launchedVehicleOwnTrack);
                        launchedVehicle.OnNewTrack(launchedVehicleOwnTrack, "Fire Control");

                        if (launchedVehicle.GetComponent <DatalinkModule>().isDuplex)
                        {
                            launchedVehicle.GetComponent <DatalinkModule>().AddReceiver(self);
                        }

                        foreach (DatalinkModule dl in self.GetComponents <DatalinkModule>())
                        {
                            if (dl.limitTrackedVehicleType == false || dl.trackedVehicleType == Vehicle.sVehicleTypes[target.vehicleTypeName])
                            {
                                dl.AddReceiver(launchedVehicle);
                            }
                        }
                    }
                }
                return(isLaunched);
            }
        }

        Vector3 launcherDirection;
        float   angleDiff;

        if (isPitchFixed == false && isYawFixed == true)
        {
            float directCourse = Mathf.Rad2Deg * Mathf.Atan2(target.predictedPositionAtTime(eta).x - vehicle.transform.localPosition.x, target.predictedPositionAtTime(eta).z - vehicle.transform.localPosition.z);
            angleDiff = directCourse - (self.course + fixedDirection.y);
        }
        else if (isPitchFixed == true && isYawFixed == false)
        {
            float directPitch = Mathf.Rad2Deg * Mathf.Atan2(target.predictedPositionAtTime(eta).y - vehicle.transform.localPosition.y, Mathf.Sqrt(Mathf.Pow(target.predictedPositionAtTime(eta).z - vehicle.transform.localPosition.z, 2) + Mathf.Pow(target.predictedPositionAtTime(eta).x - vehicle.transform.localPosition.x, 2)));
            angleDiff = directPitch - (self.pitch + fixedDirection.x);
        }
        else if (isPitchFixed == true && isYawFixed == true)
        {
            launcherDirection = this.transform.forward;
            Quaternion rotation = Quaternion.Euler(new Vector3(-fixedDirection.x, fixedDirection.y, 0f));
            launcherDirection = rotation * launcherDirection;
            angleDiff         = Vector3.Angle(target.predictedPositionAtTime(eta) - this.transform.position, launcherDirection);
        }
        else
        {
            angleDiff = 0f;
        }

        if (angleDiff > launchHalfAngle)
        {
            // Launcher half angle constraint not met.
            GameObject.Destroy(vehicle);
            return(false);
        }

        if (guidance.requiresFireControl)
        {
            if (fireControlChannels.Count < maxFireControlChannels)
            {
                vehicle.transform.parent   = SceneManager.instance.transform.Find("Side " + self.side.ToString());
                vehicle.transform.position = this.transform.position;

                float expectedCourse = Mathf.Rad2Deg * Mathf.Atan2(target.predictedPositionAtTime(eta).x - vehicle.transform.localPosition.x, target.predictedPositionAtTime(eta).z - vehicle.transform.localPosition.z);
                vehicle.GetComponent <Locomotor>().orderedCourse = expectedCourse;
                if (this.isYawFixed)
                {
                    vehicle.GetComponent <Vehicle>().course = this.transform.eulerAngles.y + fixedDirection.y;
                }
                else
                {
                    vehicle.GetComponent <Vehicle>().course = expectedCourse;
                }

                float expectedPitch = Mathf.Rad2Deg * Mathf.Atan2(target.predictedPositionAtTime(eta).y - vehicle.transform.localPosition.y, Mathf.Sqrt(Mathf.Pow(target.predictedPositionAtTime(eta).z - vehicle.transform.localPosition.z, 2) + Mathf.Pow(target.predictedPositionAtTime(eta).x - vehicle.transform.localPosition.x, 2)));
                vehicle.GetComponent <Locomotor>().orderedPitch = Mathf.Max(0f, expectedPitch);
                if (this.isPitchFixed)
                {
                    vehicle.GetComponent <Vehicle>().pitch = this.transform.eulerAngles.x + fixedDirection.x;
                }
                else
                {
                    vehicle.GetComponent <Vehicle>().pitch = expectedPitch;
                }

                vehicle.GetComponent <Vehicle>().speed = self.speed;

                vehicle.GetComponent <Locomotor>().orderedSpeed = vehicle.GetComponent <Vehicle>().maxSpeed;
                vehicle.GetComponent <Vehicle>().position       = this.transform.position;

                SceneManager.instance.vehicles.Add(vehicle.GetComponent <Vehicle>());
                vehicle.GetComponent <Vehicle>().side = self.side;
                fireControlChannels.Add(new FireControlChannel(vehicle.GetComponent <Vehicle>(), target));
                lastTimeOfFiring = Time.time;
                vehicleCounts[vehicleNames.IndexOf(vehicleName)]--;

                currentSalvoCount++;
                if (muzzleFX != null)
                {
                    if (currentSalvoCount == 1)
                    {
                        GameObject muzzleFXInstance = (GameObject)GameObject.Instantiate(muzzleFX);
                        muzzleFXInstance.transform.parent   = SceneManager.instance.transform;
                        muzzleFXInstance.transform.position = this.transform.position;
                        muzzleFXInstance.GetComponent <ParticleSystem>().Play(true);
                    }
                }
                if (currentSalvoCount == salvoCount)
                {
                    currentSalvoCount = 0;
                }
                else
                {
                    StartCoroutine(DelayedLaunch(vehicleName, target, salvoInterval));
                }

                return(true);
            }
            else
            {
                // Fire Control Channels are full.
                GameObject.Destroy(vehicle);
                return(false);
            }
        }
        else
        {
            vehicle.transform.parent   = SceneManager.instance.transform.Find("Side " + self.side.ToString());
            vehicle.transform.position = this.transform.position;

            float expectedCourse = Mathf.Rad2Deg * Mathf.Atan2(target.predictedPositionAtTime(eta).x - vehicle.transform.localPosition.x, target.predictedPositionAtTime(eta).z - vehicle.transform.localPosition.z);
            vehicle.GetComponent <Locomotor>().orderedCourse = expectedCourse;
            if (this.isYawFixed)
            {
                vehicle.GetComponent <Vehicle>().course = self.course + fixedDirection.y;
            }
            else
            {
                vehicle.GetComponent <Vehicle>().course = expectedCourse;
            }

            float expectedPitch = Mathf.Rad2Deg * Mathf.Atan2(target.predictedPositionAtTime(eta).y - vehicle.transform.localPosition.y, Mathf.Sqrt(Mathf.Pow(target.predictedPositionAtTime(eta).z - vehicle.transform.localPosition.z, 2) + Mathf.Pow(target.predictedPositionAtTime(eta).x - vehicle.transform.localPosition.x, 2)));
            vehicle.GetComponent <Locomotor>().orderedPitch = Mathf.Max(0f, expectedPitch);
            if (this.isPitchFixed)
            {
                vehicle.GetComponent <Vehicle>().pitch = self.pitch + fixedDirection.x;
            }
            else
            {
                vehicle.GetComponent <Vehicle>().pitch = expectedPitch;
            }

            vehicle.GetComponent <Vehicle>().speed = self.speed;

            vehicle.GetComponent <Locomotor>().orderedSpeed = vehicle.GetComponent <Vehicle>().maxSpeed;
            vehicle.GetComponent <Vehicle>().position       = this.transform.position;

            SceneManager.instance.vehicles.Add(vehicle.GetComponent <Vehicle>());
            vehicle.GetComponent <Vehicle>().side = self.side;
            lastTimeOfFiring = Time.time;
            vehicleCounts[vehicleNames.IndexOf(vehicleName)]--;

            currentSalvoCount++;
            if (muzzleFX != null)
            {
                if (currentSalvoCount == 1)
                {
                    GameObject muzzleFXInstance = (GameObject)GameObject.Instantiate(muzzleFX);
                    muzzleFXInstance.transform.parent   = SceneManager.instance.transform;
                    muzzleFXInstance.transform.position = this.transform.position;
                    muzzleFXInstance.GetComponent <ParticleSystem>().Play(true);
                }
            }
            if (currentSalvoCount == salvoCount)
            {
                currentSalvoCount = 0;
            }
            else
            {
                StartCoroutine(DelayedLaunch(vehicleName, target, salvoInterval));
            }
            return(true);
        }
    }
Example #5
0
    public bool Launch(string vehicleName, Vector3 position, Track actualTrack = null)
    {
        if (enabled == false)
        {
            return(false);
        }
        if (isLoaded == false && currentSalvoCount == 0)
        {
            return(false);
        }
        if (vehicleNames.Contains(vehicleName) == false)
        {
            return(false);
        }
        if (vehicleCounts[vehicleNames.IndexOf(vehicleName)] <= 0)
        {
            return(false);
        }
        GameObject vehicle = ResourceManager.LoadPrefab(Vehicle.sVehiclePrefabPaths[vehicleName]);

        GuidanceModule guidance = vehicle.GetComponent <GuidanceModule>();

        if (guidance == null)
        {
            Debug.Log("Vehicle that can be launched should have GuidanceModule.");
        }


        Vector3 launcherDirection;
        float   angleDiff;

        if (isPitchFixed == false && isYawFixed == true)
        {
            float directCourse = Mathf.Rad2Deg * Mathf.Atan2(position.x - vehicle.transform.localPosition.x, position.z - vehicle.transform.localPosition.z);
            angleDiff = directCourse - (self.course + fixedDirection.y);
        }
        else if (isPitchFixed == true && isYawFixed == false)
        {
            float directPitch = Mathf.Rad2Deg * Mathf.Atan2(position.y - vehicle.transform.localPosition.y, Mathf.Sqrt(Mathf.Pow(position.z - vehicle.transform.localPosition.z, 2) + Mathf.Pow(position.x - vehicle.transform.localPosition.x, 2)));
            angleDiff = directPitch - (self.pitch + fixedDirection.x);
        }
        else if (isPitchFixed == true && isYawFixed == true)
        {
            launcherDirection = this.transform.forward;
            Quaternion rotation = Quaternion.Euler(new Vector3(-fixedDirection.x, fixedDirection.y, 0f));
            launcherDirection = rotation * launcherDirection;
            angleDiff         = Vector3.Angle(position - this.transform.position, launcherDirection);
        }
        else
        {
            angleDiff = 0f;
        }

        if (angleDiff > launchHalfAngle)
        {
            // Launcher half angle constraint not met.
            GameObject.Destroy(vehicle);
            return(false);
        }

        guidance.SetupGuidance(null, position);

        WarheadModule warhead = vehicle.GetComponent <WarheadModule>();

        if (warhead != null)
        {
            warhead.SetupTarget(position);
        }

        vehicle.transform.parent   = SceneManager.instance.transform.Find("Side " + self.side.ToString());
        vehicle.transform.position = this.transform.position;

        float expectedCourse = Mathf.Rad2Deg * Mathf.Atan2(position.x - vehicle.transform.localPosition.x, position.z - vehicle.transform.localPosition.z);

        vehicle.GetComponent <Locomotor>().orderedCourse = expectedCourse;
        if (this.isYawFixed)
        {
            vehicle.GetComponent <Vehicle>().course = self.course + fixedDirection.y;
        }
        else
        {
            vehicle.GetComponent <Vehicle>().course = expectedCourse;
        }

        float expectedPitch = Mathf.Rad2Deg * Mathf.Atan2(position.y - vehicle.transform.localPosition.y, Mathf.Sqrt(Mathf.Pow(position.z - vehicle.transform.localPosition.z, 2) + Mathf.Pow(position.x - vehicle.transform.localPosition.x, 2)));

        vehicle.GetComponent <Locomotor>().orderedPitch = Mathf.Max(0f, expectedPitch);
        if (this.isPitchFixed)
        {
            vehicle.GetComponent <Vehicle>().pitch = self.pitch + fixedDirection.x;
        }
        else
        {
            vehicle.GetComponent <Vehicle>().pitch = expectedPitch;
        }

        vehicle.GetComponent <Vehicle>().speed = self.speed;

        vehicle.GetComponent <Locomotor>().orderedSpeed = vehicle.GetComponent <Vehicle>().maxSpeed;
        vehicle.GetComponent <Vehicle>().position       = this.transform.position;

        SceneManager.instance.vehicles.Add(vehicle.GetComponent <Vehicle>());
        vehicle.GetComponent <Vehicle>().side = self.side;
        lastTimeOfFiring = Time.time;
        vehicleCounts[vehicleNames.IndexOf(vehicleName)]--;

        currentSalvoCount++;
        if (muzzleFX != null)
        {
            if (currentSalvoCount == 1)
            {
                GameObject muzzleFXInstance = (GameObject)GameObject.Instantiate(muzzleFX);
                muzzleFXInstance.transform.parent   = SceneManager.instance.transform;
                muzzleFXInstance.transform.position = this.transform.position;
                muzzleFXInstance.GetComponent <ParticleSystem>().Play(true);
            }
        }
        if (currentSalvoCount == salvoCount)
        {
            currentSalvoCount = 0;
        }
        else
        {
            if (actualTrack == null)
            {
                StartCoroutine(DelayedLaunch(vehicleName, position, salvoInterval));
            }
            else
            {
                StartCoroutine(DelayedLaunch(vehicleName, actualTrack, salvoInterval));
            }
        }

        return(true);
    }