Пример #1
0
        private static void ConfigureDespawnable(GameObject gameObject, ProjectileSpawnData projectileSpawnData)
        {
            // configure despawnable component of the projectile
            Despawnable despawnable = gameObject.GetComponent <Despawnable>();

            despawnable.TimeAtSpawn = projectileSpawnData.TimeAtSpawn;
        }
Пример #2
0
        private static void ConfigureProjectile(GameObject gameObject, ProjectileSpawnData projectileSpawnData)
        {
            // configure projectile component of the projectile
            Projectile projectile = gameObject.gameObject.GetComponent <Projectile>();

            projectile.PreviousPosition = gameObject.transform.position;
            Rigidbody rigidbody = gameObject.GetComponent <Rigidbody>();

            rigidbody.AddForce(projectileSpawnData.Direction * projectileSpawnData.Force, ForceMode.Impulse);
        }
Пример #3
0
        private static void TurretSpawnProjectile(Turret turret, Shooter shooter,
                                                  ProjectileSpawnData projectileSpawnData, ObjectPooler pooler)
        {
            GameObject shellObject = pooler.Get(EPoolType.EmptyShell);
            GameObject projectileObject;

            if (projectileSpawnData.Type == EProjectileType.DirectImpact)
            {
                projectileObject = pooler.Get(EPoolType.DirectImpactProjectile);
            }
            else if (projectileSpawnData.Type == EProjectileType.Explosive)
            {
                projectileObject = pooler.Get(EPoolType.ExplosiveProjectile);
            }
            else
            {
                // TODO:
                // handle other projectile types if any
                Debug.Log("Attempted to spawn an unsupported projectile type.");
                return;
            }

            // set objects active
            shellObject.SetActive(true);
            projectileObject.SetActive(true);

            projectileObject.transform.parent = ProjectileParent;
            shellObject.transform.parent      = ProjectileParent;

            Vector3 spawnPos = turret.Gun.transform.position;

            shellObject.transform.position = spawnPos;
            // spawn the projectile in front of the gun (to avoid colision right away)
            projectileObject.transform.position = spawnPos + turret.Gun.transform.forward * 2;
            projectileObject.transform.rotation = Quaternion.LookRotation(turret.Gun.transform.forward);

            ConfigureShellForce(shellObject);
            ConfigureDespawnable(shellObject, projectileSpawnData);
            ConfigureDespawnable(projectileObject, projectileSpawnData);
            ConfigureProjectile(projectileObject, projectileSpawnData);
        }
Пример #4
0
        protected override void OnUpdate()
        {
            var time      = Time.time;
            var deltaTime = Time.deltaTime;

            var objectPooler = Bootstrapper.ObjectPooler;

            for (int i = 0; i < TurretComponents.Length; i++)
            {
                Transform transform = TurretComponents.Transforms[i];
                Turret    turret    = TurretComponents.Turrets[i];
                Shooter   shooter   = TurretComponents.Shooters[i];

                // find closest target for current tower and update
                {
                    int   closestTarget   = -1;
                    float closestDistance = float.MaxValue;

                    int   closestTargetNoCheck   = -1;
                    float closestDistanceNoCheck = float.MaxValue;

                    for (int j = 0; j < TargetComponents.Length; j++)
                    {
                        Transform target   = TargetComponents.Transforms[j];
                        float     distance = Vector3.Distance(target.position, transform.position);

                        if (distance < closestDistance)
                        {
                            if (HasTargetableTarget(turret, shooter, target.transform))
                            {
                                closestTarget   = j;
                                closestDistance = distance;
                            }
                        }

                        // without checking targetable
                        // needed for aiming at object if its too close, but out of range
                        if (distance < closestDistanceNoCheck)
                        {
                            closestTargetNoCheck   = j;
                            closestDistanceNoCheck = distance;
                        }
                    }

                    turret.TargetObject = null;
                    // update target
                    if (closestTarget == -1)
                    {
                        // do not merge the conditions! they must be separetely tested
                        if (closestTargetNoCheck != -1)
                        {
                            turret.TargetObject = TargetComponents.Transforms[closestTargetNoCheck].gameObject;
                        }
                    }
                    else
                    {
                        turret.TargetObject = TargetComponents.Transforms[closestTarget].gameObject;
                    }
                }

                // animation and aiming control flags
                bool targetInRange = turret.TargetObject != null &&
                                     HasTargetableTarget(turret, shooter, turret.TargetObject.transform);
                bool idleAnimation = !targetInRange;

                turret.TargetPos = targetInRange ? turret.TargetObject.transform.position : turret.TargetPos;

                Vector3    toTarget           = turret.TargetPos - turret.Gun.transform.position;
                Quaternion toTargetQuaternion = Quaternion.LookRotation(toTarget);

                bool  targetLock    = false;
                float angleDeltaCrt = Vector3.Angle(toTarget, turret.Gun.transform.forward);
                if (angleDeltaCrt < shooter.LockonAngle)
                {
                    targetLock = true;
                }

                // TODO: can refactor this to a function
                {
                    // apply rotation

                    float lerpRatio = turret.MaxRotationSpeed / (Mathf.Max(angleDeltaCrt, 0.001f)) * deltaTime;
                    lerpRatio = Mathf.Clamp(lerpRatio, 0f, 1f);

                    // calculate the Quaternion for the rotation
                    var rotGun    = Quaternion.Slerp(turret.Gun.transform.rotation, toTargetQuaternion, lerpRatio);
                    var rotTurret = Quaternion.Slerp(turret.Gun.transform.rotation, toTargetQuaternion, lerpRatio);

                    // Apply the rotation to turret (horizontal: left/right)
                    transform.localRotation    = rotTurret;
                    transform.localEulerAngles = new Vector3(
                        0f, transform.localEulerAngles.y, 0f); // only rotate y

                    // Apply local rotation to gun (vertical: up/down)
                    turret.Gun.transform.localRotation    = rotGun;
                    turret.Gun.transform.localEulerAngles = new Vector3(
                        turret.Gun.transform.localEulerAngles.x, 0f, 0f); // only rotate x
                }

                // update and draw aim assist if enabled
                bool showAimAssist = turret.ShowAimAssist;
//                turret.AimAssist.SetActive(showAimAssist);
                if (showAimAssist)
                {
                    // ray trace from gun straight to see what it is facing
                    Vector3    aimAssistTarget;
                    RaycastHit raycastHit;
                    if (Physics.Raycast(turret.Gun.transform.position, turret.Gun.transform.forward,
                                        out raycastHit, maxDistance: turret.AimAssistMaxRayCastLength))
                    {
                        aimAssistTarget = raycastHit.point;
                    }
                    else
                    {
                        aimAssistTarget = turret.Gun.transform.position +
                                          turret.Gun.transform.forward * turret.AimAssistMaxLength;
                    }

                    var lineRenderer = turret.AimAssist.GetComponent <LineRenderer>();
                    lineRenderer.SetPosition(0, turret.Gun.transform.position);
                    lineRenderer.SetPosition(1, aimAssistTarget);
                }

                // shoot a projectile if
                if (targetInRange && targetLock)
                {
                    // shoot at target
                    if (time - shooter.TimeAtShot >= shooter.SecondsBetweenShots)
                    {
                        var projectileSpawnData = new ProjectileSpawnData()
                        {
                            Position    = turret.Gun.transform.position,
                            Direction   = turret.Gun.transform.forward,
                            TimeAtSpawn = time,
                            Type        = shooter.ProjectileType,
                            Force       = shooter.ProjectileForce,
                        };

                        // TODO; convert to a pool of objects
                        TurretSpawnProjectile(turret, shooter, projectileSpawnData, objectPooler);

                        shooter.TimeAtShot = time;
                    }
                }

                if (idleAnimation && targetLock)
                {
                    // update rotation direction
                    var random = UnityEngine.Random.Range(0f, 1f);
                    if (random < turret.IdleNewDirectionProbability)
                    {
                        // compute a random vector
                        float theta = 2 * Mathf.PI * UnityEngine.Random.Range(0f, 1f); // random angle over circle
                        //                    theta = UnityEngine.Random.Range(0f, 1f) > 0.5 ? Mathf.PI - 1e-3f : 2 * Mathf.PI - 1e-3f; // test
                        Vector3 direction = new Vector3(Mathf.Cos(theta), 0, Mathf.Sin(theta));

                        // compute a random target within fire range
                        turret.TargetPos = transform.parent.position + direction * 10f;
                    }
                }
            }
        }