protected virtual IEnumerator Generate_Bullet()
        {
            // Generate the muzzle fire.
            if (MuzzleFire_Object)
            {
                Instantiate(MuzzleFire_Object, thisTransform.position, thisTransform.rotation, thisTransform);
            }

            // Generate the bullet.
            GameObject bulletObject;
            float      attackPoint = 0;

            switch (currentBulletType)
            {
            case 0:     // AP
                if (AP_Bullet_Prefab == null)
                {
                    Debug.LogError("'AP_Bullet_Prefab' is not assigned in the 'Bullet_Generator'.");
                    yield break;
                }
                bulletObject = Instantiate(AP_Bullet_Prefab, thisTransform.position + (thisTransform.forward * Offset), thisTransform.rotation) as GameObject;
                attackPoint  = Attack_Point;
                break;

            case 1:     // HE
                if (HE_Bullet_Prefab == null)
                {
                    Debug.LogError("'HE_Bullet_Prefab' is not assigned in the 'Bullet_Generator'.");
                    yield break;
                }
                bulletObject = Instantiate(HE_Bullet_Prefab, thisTransform.position + (thisTransform.forward * Offset), thisTransform.rotation) as GameObject;
                attackPoint  = Attack_Point_HE;
                break;

            case 2:
                if (AP_Projectile_Prefab == null)
                {
                    Debug.LogError("'AP_Projectile_Prefab' is not assigned in the 'Bullet_Generator'.");
                    yield break;
                }

                bulletObject = Instantiate(AP_Projectile_Prefab);

                Vector3 startPosition  = thisTransform.position;
                Vector3 startDirection = thisTransform.forward;

                bulletObject.GetComponent <MoveBullet>().SetStartValues(startPosition, startDirection);

                yield break;

            default:
                yield break;
            }

            // Set values of "Bullet_Control_CS" in the bullet.
            Bullet_Control_CS bulletScript = bulletObject.GetComponent <Bullet_Control_CS>();

            bulletScript.Attack_Point      = attackPoint;
            bulletScript.Initial_Velocity  = Current_Bullet_Velocity;
            bulletScript.Life_Time         = Life_Time;
            bulletScript.Attack_Multiplier = Attack_Multiplier;
            bulletScript.Debug_Flag        = Debug_Flag;

            // Set the tag.
            bulletObject.tag = "Finish"; // (Note.) The ray cast for aiming does not hit any object with "Finish" tag.

            // Set the layer.
            bulletObject.layer = Layer_Settings_CS.Bullet_Layer;

            // Shoot.
            yield return(new WaitForFixedUpdate());

            Rigidbody rigidbody       = bulletObject.GetComponent <Rigidbody>();
            Vector3   currentVelocity = bulletObject.transform.forward * Current_Bullet_Velocity;

            rigidbody.velocity = currentVelocity;
        }
        IEnumerator Create_Shells(Transform targetTransform, int totalShellCount)
        {
            isFiring = true;

            var shellCount      = 0;
            var timeCount       = 0.0f;
            var currentInterval = Random.Range(Interval_Min, Interval_Max);
            var initialPos      = targetTransform.position;

            while (shellCount <= totalShellCount)
            {
                timeCount += Time.deltaTime;
                if (timeCount < currentInterval)
                {
                    yield return(null);

                    continue;
                }

                // Create the gameobject.
                GameObject shellObject = new GameObject("Artillery_Shell");

                // Set position.
                Vector3 targetPos;
                if (targetTransform)
                { // The target exists.
                    targetPos = targetTransform.position;
                }
                else
                { // The target might be removed from the scene.
                    targetPos = initialPos;
                }
                targetPos.x += Random.Range(0.0f, Radius) * Mathf.Cos(Random.Range(0.0f, 2.0f * Mathf.PI));
                targetPos.z += Random.Range(0.0f, Radius) * Mathf.Sin(Random.Range(0.0f, 2.0f * Mathf.PI));
                targetPos.y += Height;
                shellObject.transform.position = targetPos;

                // Add component.
                Rigidbody rigidbody = shellObject.AddComponent <Rigidbody>();
                rigidbody.mass = Mass;
                shellObject.AddComponent <SphereCollider>();

                // Add Scripts
                Bullet_Control_CS bulletScript = shellObject.AddComponent <Bullet_Control_CS>();
                bulletScript.Type             = 1; // HE
                bulletScript.Life_Time        = Life_Time;
                bulletScript.Attack_Point     = Attack_Point;
                bulletScript.Explosion_Force  = Explosion_Force;
                bulletScript.Explosion_Radius = Explosion_Radius;
                bulletScript.Explosion_Object = Explosion_Object;

                // Set the tag.
                shellObject.tag = "Finish"; // (Note.) The ray cast for aiming does not hit any object with "Finish" tag.

                // Set the layer.
                shellObject.layer = Layer_Settings_CS.Bullet_Layer;

                // Update.
                shellCount     += 1;
                currentInterval = Random.Range(Interval_Min, Interval_Max);
                timeCount       = 0.0f;
            }

            isFiring = false;
        }
        public Collision collision;          // Data about the collision.

        public ImpactData(float impactAngle, Bullet_Control_CS bulletType, Collision collision)
        {
            this.impactAngle = impactAngle;
            this.bulletType  = bulletType;
            this.collision   = collision;
        }