/// <summary>
        /// Reference for Predictive Aiming:
        ///     https://www.gamasutra.com/blogs/KainShin/20090515/83954/Predictive_Aim_Mathematics_for_AI_Targeting.php
        /// </summary>
        protected Vector3 GetPredictiveAimDirection(NpcController npc)
        {
            if (npc == null)
            {
                return(new Vector3());
            }

            var bulletSpeed             = HandController.GetProjectileSpeed();
            var bulletSpeedSq           = bulletSpeed * bulletSpeed;
            var bulletOrigin            = HandController.GetWeaponPosition();
            var enemyInitialPosition    = npc.transform.root.position;
            var enemyVelocity           = npc.GetVelocity();
            var enemySpeed              = enemyVelocity.magnitude;
            var enemySpeedSq            = enemySpeed * enemySpeed;
            var enemyToBullet           = bulletOrigin - enemyInitialPosition;
            var enemyToBulletDistance   = enemyToBullet.magnitude;
            var enemyToBulletDistanceSq = enemyToBulletDistance * enemyToBulletDistance;
            var enemyToBulletDirection  = enemyToBullet.normalized;
            var enemyVelocityDirection  = enemyVelocity.normalized;

            //Law of Cosines: A*A + B*B - 2*A*B*cos(theta) = C*C
            //A is distance from bullet to enemy (known value: enemyToBulletDistance)
            //B is distance traveled by enemy until impact (enemySpeed * t (time))
            //C is distance traveled by bullet until impact (bulletSpeed * t (time))
            var cosTheta = Vector3.Dot(enemyToBulletDirection, enemyVelocityDirection);

            var a            = bulletSpeedSq - enemySpeedSq;
            var b            = 2.0f * enemyToBulletDistance * enemySpeed * cosTheta;
            var c            = -enemyToBulletDistanceSq;
            var discriminant = b * b - 4.0f * a * c;

            var uglyNumber = Mathf.Sqrt(discriminant);
            var t0         = 0.5f * (-b + uglyNumber) / a;
            var t1         = 0.5f * (-b - uglyNumber) / a;

            var time = Mathf.Min(t0, t1);

            if (time < Mathf.Epsilon)
            {
                time = Mathf.Max(t0, t1);
            }

            var bulletVelocity = enemyVelocity + -enemyToBullet / time;

            return(bulletVelocity);
        }