Beispiel #1
0
        public override void OnLaunch()
        {
            if (projectiles.Count > 0)
            {
                foreach (ProjectileData d in projectiles)
                {
                    if (d.proj != null)
                    {
                        ForceDestroyProjectile(d.proj);
                    }
                }
            }

            projectiles.Clear();

            DeleteCastingEffect();

            GameObject activeProjectile;

            for (int i = 0; i < projectilesCount; i++)
            {
                activeProjectile = CreateSkillProjectile("projectile_00", true);
                if (activeProjectile != null)
                {
                    Rigidbody2D rb = activeProjectile.GetComponent <Rigidbody2D>();

                    rb.velocity = (GetOwnerData().GetForwardVector((Random.Range(-randomAngle, randomAngle) + CalcAngleForProjectile(i, projectilesCount, projectilesAngle))) * force);

                    Object.Destroy(activeProjectile, GetProjectileLifetime(force));

                    if (SaveProjectiles())
                    {
                        ProjectileData data = new ProjectileData();
                        data.proj                = activeProjectile;
                        data.target              = null;
                        data.interpolTimer       = 0;
                        data.rb                  = rb;
                        data.penetratedTargets   = 0;
                        data.maxPenetrateTargets = maxPenetratedTargets;

                        if (maxPenetratedTargets > 0)
                        {
                            data.hits = new GameObject[maxPenetratedTargets];
                        }

                        if (returnBack)
                        {
                            data.waypoints.Push(Owner.GetData().GetBody().transform.position);
                        }

                        projectiles.Add(data);
                        MonoUpdate(rb.gameObject, true);
                    }
                }
            }
        }
Beispiel #2
0
        public override void DestroyProjectile(GameObject proj, float delay = 1)
        {
            if (!returnBack)
            {
                base.DestroyProjectile(proj, delay);
            }
            else
            {
                returningBack = true;

                ProjectileData d = GetProjectileData(proj);

                if (d != null)
                {
                    AdjustToTarget(d);
                }
            }
        }
Beispiel #3
0
        public override void MonoUpdate(GameObject gameObject, bool fixedUpdate)
        {
            bool saveProjectiles = projectilesAim || selectTargetOnLaunch || maxPenetratedTargets > 0;

            if (saveProjectiles && fixedUpdate)
            {
                // updates: 10/sec
                if (System.Environment.TickCount % 10 == 0)
                {
                    ProjectileData d = GetData(gameObject);
                    if (d == null || d.proj == null)
                    {
                        return;
                    }

                    if (d.target == null && projectilesAim)
                    {
                        float angle = d.proj.transform.rotation.eulerAngles.z;
                        foreach (RaycastHit2D hit in Physics2D.BoxCastAll(d.proj.transform.position, new Vector2(aimArea, aimArea), angle, d.rb.velocity, aimArea))
                        {
                            if (hit.collider.gameObject.Equals(d.proj))
                            {
                                continue;
                            }

                            Character targetCh = hit.collider.gameObject.GetChar();
                            if (targetCh == null || !Owner.CanAttack(targetCh))
                            {
                                continue;
                            }

                            d.target = targetCh;
                            break;
                        }
                    }

                    if (d.target != null)
                    {
                        AdjustToTarget(d);
                    }
                }
            }
        }
Beispiel #4
0
        private void AdjustToTarget(ProjectileData data)
        {
            if (data.target.Status.IsDead)
            {
                data.target = null;
                return;
            }

            Vector3 currentVelocity = data.rb.velocity.normalized;
            Vector3 targetDir       = Utils.GetDirectionVector(data.target.GetData().GetBody().transform.position, data.proj.transform.position).normalized;

            data.interpolTimer += interpolAdd;

            if (data.interpolTimer > 1)
            {
                data.interpolTimer = 1f;
            }

            Vector3 newDir = Vector3.Lerp(currentVelocity, targetDir, data.interpolTimer);

            data.rb.velocity = newDir * force;
        }
Beispiel #5
0
        public override void MonoTriggerEnter(GameObject gameObject, Collider2D coll)
        {
            if (coll.gameObject.Equals(GetOwnerData().GetBody()))
            {
                return;
            }

            Character ch = coll.gameObject.GetChar();

            ProjectileData d = GetProjectileData(gameObject);

            // if projectile was saved, it means special effects are to be applied
            if (d != null)
            {
                if (penetrateFriendly)
                {
                    if (ch == null)
                    {
                        Destroyable des = coll.gameObject.GetComponent <Destroyable>();
                        if (des != null && !Owner.CanAttack(des))
                        {
                            return;
                        }
                    }
                    else if (!Owner.CanAttack(ch))
                    {
                        return;
                    }
                }

                // missile hit target
                if (d.target != null)
                {
                    if (coll.gameObject.Equals(d.target.GetData().GetBody()))
                    {
                        d.target = null;
                    }
                }

                if (penetrateTargets > 0 && d.penetratedTargets > 0 && (penetrateChangeDamage < 0 || penetrateChangeDamage > 0))
                {
                    ApplyEffects(Owner, coll.gameObject, false, d.penetratedTargets);
                }
                else
                {
                    ApplyEffects(Owner, coll.gameObject);
                }

                bool destroy = false;

                if (penetrateTargets > 0)
                {
                    // check if penetrated too many
                    d.penetratedTargets++;
                    if (d.penetratedTargets >= penetrateTargets)
                    {
                        destroy = true;
                    }

                    // find next target
                    if (!destroy && navigateChangeTargetAfterHit)
                    {
                        float angle = d.proj.transform.rotation.eulerAngles.z;
                        if (!navigateLookOnlyForward)
                        {
                            /*foreach (Collider2D hit in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                             * {
                             *      if (hit.gameObject.Equals(d.proj))
                             *              continue;
                             *
                             *      Character targetCh = hit.gameObject.GetChar();
                             *      if (targetCh == null || !Owner.CanAttack(targetCh) || hit.gameObject.Equals(coll.gameObject))
                             *              continue;
                             *
                             *      d.target = targetCh;
                             *      AdjustToTarget(d);
                             *      break;
                             * }*/

                            foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                            {
                                if (c.gameObject.Equals(d.proj))
                                {
                                    continue;
                                }

                                Character targetCh = c.gameObject.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh) || c.gameObject.Equals(coll.gameObject))
                                {
                                    continue;
                                }

                                d.target = targetCh;
                                AdjustToTarget(d);
                                break;
                            }
                        }
                        else
                        {
                            Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y);
                            Vector3 perpend   = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position);

                            foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f)))
                            {
                                if (c.gameObject.Equals(d.proj))
                                {
                                    continue;
                                }

                                Character targetCh = c.gameObject.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh) || c.gameObject.Equals(coll.gameObject))
                                {
                                    continue;
                                }

                                d.target = targetCh;
                                AdjustToTarget(d);
                                break;
                            }
                        }
                    }
                }

                if (penetrateTargets == 0 || destroy)
                {
                    if (explodeEffect)
                    {
                        GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position);
                        explosion.GetComponent <ParticleSystem>().Play();
                        Object.Destroy(explosion, 2f);
                    }

                    DestroyProjectile(gameObject);
                }
            }
            else
            {
                if (penetrateFriendly)
                {
                    if (ch == null)
                    {
                        Destroyable des = coll.gameObject.GetComponent <Destroyable>();
                        if (des != null && !Owner.CanAttack(des))
                        {
                            return;
                        }
                    }
                    else if (!Owner.CanAttack(ch))
                    {
                        return;
                    }
                }

                if (explodeEffect)
                {
                    GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position);
                    explosion.GetComponent <ParticleSystem>().Play();
                    Object.Destroy(explosion, 2f);
                }

                ApplyEffects(Owner, coll.gameObject);
                DestroyProjectile(gameObject);
            }
        }
Beispiel #6
0
        public override void MonoUpdate(GameObject gameObject, bool fixedUpdate)
        {
            if (navigateToTarget)
            {
                if (fixedUpdate)
                {
                    if (lastUpdate + updateInterval <= Time.time)
                    {
                        ProjectileData d = GetProjectileData(gameObject);
                        if (d == null || d.proj == null)
                        {
                            return;
                        }

                        lastUpdate = Time.time;

                        // find new target
                        if (d.target == null)
                        {
                            if (d.lastChooseTarget + chooseTargetInterval < Time.time)
                            {
                                d.lastChooseTarget = Time.time;

                                if (!navigateLookOnlyForward)
                                {
                                    float angle = d.proj.transform.rotation.eulerAngles.z;

                                    foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                                    {
                                        if (c.gameObject.Equals(d.proj))
                                        {
                                            continue;
                                        }

                                        Character targetCh = c.gameObject.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        d.target = targetCh;
                                        break;
                                    }
                                }
                                else                                 // scan only forward targets
                                {
                                    float angle = d.proj.transform.rotation.eulerAngles.z;

                                    Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y);
                                    Vector3 perpend   = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position);

                                    Debug.DrawRay(d.proj.transform.position, perpend * 10, Color.red, 1f);

                                    Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, Color.green, 1f);
                                    Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * (-navigateAimArea / 2f), Color.blue, 1f);

                                    foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f)))
                                    {
                                        if (c.gameObject.Equals(d.proj))
                                        {
                                            continue;
                                        }

                                        Character targetCh = c.gameObject.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        d.target = targetCh;
                                        break;
                                    }
                                }
                            }
                        }

                        if (d.target != null)
                        {
                            AdjustToTarget(d);
                        }
                    }
                }
            }
        }
Beispiel #7
0
        public override void MonoTriggerEnter(GameObject gameObject, Collider2D coll)
        {
            if (coll.gameObject.Equals(GetOwnerData().GetBody()))
            {
                return;
            }

            ProjectileData d = GetData(gameObject);

            if (d != null && d.target != null)
            {
                if (coll.gameObject.Equals(d.target.GetData().GetBody()))
                {
                    d.target = null;
                }
            }

            if (d != null && maxPenetratedTargets > 0 && d.penetratedTargets > 0 && secondDamage > 0)
            {
                ApplyEffects(Owner, coll.gameObject, false, 1);
            }
            else
            {
                if (!areaEffect)
                {
                    ApplyEffects(Owner, coll.gameObject);
                }
                else
                {
                    Collider2D[] colls = Physics2D.OverlapCircleAll(gameObject.transform.position, areaEffectRange);

                    // explosion effect
                    GameObject explosion = CreateParticleEffect("AreaTargetExplosion", false, gameObject.transform.position);
                    explosion.GetComponent <ParticleSystem>().Play();
                    Object.Destroy(explosion, 2f);

                    // give damages
                    foreach (Collider2D col in colls)
                    {
                        if (col != null && col.gameObject != null)
                        {
                            Character targetCh = col.gameObject.GetChar();

                            if (targetCh != null)
                            {
                                if (Owner.CanAttack(targetCh))
                                {
                                    ApplyEffects(Owner, col.gameObject);
                                }
                            }
                        }
                    }
                }
            }

            bool destroy = false;

            if (penetrateTargets)
            {
                if (d != null)
                {
                    // check if penetrated too many
                    if (maxPenetratedTargets > 0)
                    {
                        d.penetratedTargets++;
                        if (d.penetratedTargets >= maxPenetratedTargets)
                        {
                            destroy = true;
                        }
                    }

                    if (!destroy && navigateAfterPenetration)
                    {
                        float angle = d.proj.transform.rotation.eulerAngles.z;
                        foreach (Collider2D hit in Physics2D.OverlapCircleAll(d.proj.transform.position, aimArea))
                        {
                            if (hit.gameObject.Equals(d.proj))
                            {
                                continue;
                            }

                            Character targetCh = hit.gameObject.GetChar();
                            if (targetCh == null || !Owner.CanAttack(targetCh) || hit.gameObject.Equals(coll.gameObject))
                            {
                                continue;
                            }

                            d.target = targetCh;
                            AdjustToTarget(d);
                            break;
                        }
                    }
                }
            }

            if (!penetrateTargets || destroy)
            {
                if (explodeEffect)
                {
                    GameObject explosion = CreateParticleEffect("Explosion", false, gameObject.transform.position);
                    explosion.GetComponent <ParticleSystem>().Play();
                    Object.Destroy(explosion, 2f);
                }

                DestroyProjectile(gameObject);
            }
        }
Beispiel #8
0
        public override void OnLaunch()
        {
            bool saveProjectiles = projectilesAim || selectTargetOnLaunch || maxPenetratedTargets > 0;

            if (saveProjectiles)
            {
                projectiles.Clear();
            }

            DeleteCastingEffect();

            GameObject activeProjectile;

            for (int i = 0; i < projectilesCount; i++)
            {
                activeProjectile = CreateSkillProjectile("projectile_00", true);
                if (activeProjectile != null)
                {
                    Rigidbody2D rb = activeProjectile.GetComponent <Rigidbody2D>();

                    rb.velocity = (GetOwnerData().GetForwardVector((Random.Range(-randomAngle, randomAngle) + CalcAngleForProjectile(i, projectilesCount, 10))) * force);

                    Object.Destroy(activeProjectile, 5f);

                    if (saveProjectiles)
                    {
                        ProjectileData data = new ProjectileData();
                        data.proj              = activeProjectile;
                        data.target            = null;
                        data.interpolTimer     = 0;
                        data.rb                = rb;
                        data.penetratedTargets = 0;

                        projectiles.Add(data);
                    }
                }
            }

            // vybere target pri vypusteni
            if (selectTargetOnLaunch)
            {
                int range = GetRange();

                List <RaycastHit2D> hits    = Utils.CastBoxInDirection(Owner.GetData().GetBody(), GetPlayerData().GetForwardVector(), range, range * 2).ToList();
                List <Character>    targets = new List <Character>();

                for (int i = 0; i < hits.Count; i++)
                {
                    RaycastHit2D hit      = hits[i];
                    Character    targetCh = hit.collider.gameObject.GetChar();
                    if (targetCh == null || !Owner.CanAttack(targetCh))
                    {
                        continue;
                    }

                    targets.Add(targetCh);
                }

                if (targets.Count > 0)
                {
                    foreach (ProjectileData d in projectiles)
                    {
                        if (d.target == null)
                        {
                            int randomIndex = Random.Range(0, targets.Count);
                            d.target = targets[randomIndex];
                        }
                    }
                }
            }
        }
Beispiel #9
0
        public override void MonoTriggerEnter(GameObject gameObject, Collider2D coll)
        {
            if (coll.gameObject.Equals(GetOwnerData().GetBody()))
            {
                return;
            }

            Character ch = coll.gameObject.GetChar();

            ProjectileData d = GetProjectileData(gameObject);

            // if projectile was saved, it means special effects are to be applied
            if (d != null)
            {
                if (ch == null)
                {
                    Destroyable des = coll.gameObject.GetComponent <Destroyable>();

                    if (des == null)
                    {
                        ForceDestroyProjectile(d.proj);
                        return;
                    }

                    if (!Owner.CanAttack(des))
                    {
                        return;
                    }
                }
                else if (!Owner.CanAttack(ch))
                {
                    return;
                }

                // missile hit target
                if (d.target != null)
                {
                    if (coll.gameObject.Equals(d.target.GetData().GetBody()))
                    {
                        d.target = null;
                    }
                }

                if (d.ignore != null && d.ignore.Equals(coll.gameObject))
                {
                    return;
                }

                if (chainEffect && !d.chained)
                {
                    for (int i = 0; i < chainProjectilesCount; i++)
                    {
                        GameObject activeProjectile;

                        activeProjectile = CreateSkillProjectile("projectile_00", true, d.proj.transform);
                        if (activeProjectile != null)
                        {
                            Rigidbody2D rb = activeProjectile.GetComponent <Rigidbody2D>();

                            Vector3 nv = Quaternion.Euler(new Vector3(0, 0, Random.Range(-90, 90))) * d.rb.velocity.normalized;
                            rb.velocity = nv * force;

                            Object.Destroy(activeProjectile, GetProjectileLifetime(force));

                            if (SaveProjectiles())
                            {
                                ProjectileData data = new ProjectileData();
                                data.proj                = activeProjectile;
                                data.target              = null;
                                data.interpolTimer       = 0;
                                data.rb                  = rb;
                                data.penetratedTargets   = 0;
                                data.maxPenetrateTargets = chainPenetrations + 1;
                                data.chained             = true;
                                data.ignore              = coll.gameObject;

                                if (chainPenetrations > 0)
                                {
                                    data.hits = new GameObject[chainPenetrations + 1];
                                }

                                if (returnBack)
                                {
                                    data.waypoints.Push(activeProjectile.transform.position);
                                }

                                data.SaveHit(coll.gameObject);
                                data.penetratedTargets++;
                                projectiles.Add(data);
                                MonoUpdate(rb.gameObject, true);
                            }
                        }
                    }
                }

                if (d.maxPenetrateTargets > 0 && d.penetratedTargets > 0 && (penetrateChangeDamage < 0 || penetrateChangeDamage > 0))
                {
                    ApplyEffects(Owner, coll.gameObject, false, d.penetratedTargets);
                }
                else
                {
                    ApplyEffects(Owner, coll.gameObject);
                }

                bool destroy = false;

                if (maxPenetratedTargets > 0 && d.maxPenetrateTargets > 0)
                {
                    // check if penetrated too many
                    d.penetratedTargets++;
                    if (d.penetratedTargets >= d.maxPenetrateTargets)
                    {
                        destroy = true;
                    }

                    // find next target
                    if (!destroy && navigateChangeTargetAfterHit)
                    {
                        ProjectileHitAnimation(d.proj);

                        float angle = d.proj.transform.rotation.eulerAngles.z;
                        if (!navigateLookOnlyForward)
                        {
                            /*foreach (Collider2D hit in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                             * {
                             *      if (hit.gameObject.Equals(d.proj))
                             *              continue;
                             *
                             *      Character targetCh = hit.gameObject.GetChar();
                             *      if (targetCh == null || !Owner.CanAttack(targetCh) || hit.gameObject.Equals(coll.gameObject))
                             *              continue;
                             *
                             *      d.target = targetCh;
                             *      AdjustToTarget(d);
                             *      break;
                             * }*/

                            List <GameObject> candidates = new List <GameObject>();

                            foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                            {
                                if (c.gameObject.Equals(d.proj))
                                {
                                    continue;
                                }

                                if (d.HasHit(c.gameObject))
                                {
                                    continue;
                                }

                                if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                {
                                    continue;
                                }

                                Character targetCh = c.gameObject.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh))
                                {
                                    continue;
                                }

                                candidates.Add(c.gameObject);
                            }

                            candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                            foreach (GameObject c in candidates)
                            {
                                Character targetCh = c.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh))
                                {
                                    continue;
                                }

                                d.target = targetCh;
                                d.SaveHit(c.gameObject);
                                AdjustToTarget(d);
                                break;
                            }
                        }
                        else
                        {
                            Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y);
                            Vector3 perpend   = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position);

                            List <GameObject> candidates = new List <GameObject>();

                            foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f)))
                            {
                                if (c.gameObject.Equals(d.proj))
                                {
                                    continue;
                                }

                                if (d.HasHit(c.gameObject))
                                {
                                    continue;
                                }

                                if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                {
                                    continue;
                                }

                                candidates.Add(c.gameObject);
                                break;
                            }

                            candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                            foreach (GameObject c in candidates)
                            {
                                Character targetCh = c.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh))
                                {
                                    continue;
                                }

                                d.target = targetCh;
                                d.SaveHit(c.gameObject);
                                AdjustToTarget(d);
                                break;
                            }
                        }
                    }
                }

                if (maxPenetratedTargets == 0 || destroy)
                {
                    if (returnBack)
                    {
                        returningBack = true;
                        AdjustToTarget(d);
                    }
                    else
                    {
                        if (explodeEffect)
                        {
                            GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position);
                            explosion.GetComponent <ParticleSystem>().Play();
                            Object.Destroy(explosion, 2f);
                        }

                        DestroyProjectile(gameObject);
                    }
                }
            }
            else
            {
                if (ch == null)
                {
                    Destroyable des = coll.gameObject.GetComponent <Destroyable>();
                    if (des != null && !Owner.CanAttack(des))
                    {
                        return;
                    }
                }
                else if (!Owner.CanAttack(ch))
                {
                    return;
                }

                ApplyEffects(Owner, coll.gameObject);
                DestroyProjectile(gameObject);
            }
        }
Beispiel #10
0
        private void AdjustToTarget(ProjectileData data)
        {
            if (returningBack)
            {
                if (!data.hasNextWaypoint && data.waypoints.Count > 0)
                {
                    data.nextWaypoint    = data.waypoints.Pop();
                    data.hasNextWaypoint = true;
                }

                if (data.hasNextWaypoint)
                {
                    Vector3 target = data.nextWaypoint;

                    Vector3 currentVelocity = data.rb.velocity.normalized;
                    Vector3 targetDir       = Utils.GetDirectionVector(target, data.proj.transform.position).normalized;

                    data.interpolTimer += navigateAimRate;

                    if (data.interpolTimer > 1)
                    {
                        data.interpolTimer = 1f;
                    }

                    Vector3 newDir = Vector3.Lerp(currentVelocity, targetDir, data.interpolTimer);

                    if (navigateUnreliable)
                    {
                        newDir = Utils.RotateDirectionVector(newDir, Random.Range(-30, 30));
                    }

                    data.rb.velocity = newDir * 15;
                }
            }
            else
            {
                if (data.target.Status.IsDead || (data.ignore != null && data.ignore.Equals(data.target.GetData().GetBody())))
                {
                    data.target = null;
                    return;
                }

                Vector3 currentVelocity = data.rb.velocity.normalized;
                Vector3 targetDir       = Utils.GetDirectionVector(data.target.GetData().GetBody().transform.position, data.proj.transform.position).normalized;

                data.interpolTimer += navigateAimRate;

                if (data.interpolTimer > 1)
                {
                    data.interpolTimer = 1f;
                }

                Vector3 newDir = Vector3.Lerp(currentVelocity, targetDir, data.interpolTimer);

                if (navigateUnreliable)
                {
                    newDir = Utils.RotateDirectionVector(newDir, Random.Range(-30, 30));
                }

                data.rb.velocity = newDir * 15;
            }
        }
Beispiel #11
0
        public override void MonoUpdate(GameObject gameObject, bool fixedUpdate)
        {
            if (returningBack)
            {
                ProjectileData d = GetProjectileData(gameObject);
                if (d == null || d.proj == null)
                {
                    return;
                }

                if (d.lastUpdateTime + updateInterval <= Time.time)
                {
                    d.lastUpdateTime = Time.time;

                    if (!d.hasNextWaypoint)
                    {
                        AdjustToTarget(d);
                    }

                    if (d.hasNextWaypoint)
                    {
                        float dist = Utils.DistanceSqr(d.nextWaypoint, d.proj.transform.position);
                        if (dist < 2 * 2)
                        {
                            d.hasNextWaypoint = false;
                        }
                    }
                    else
                    {
                        returningBack = false;

                        if (explodeEffect)
                        {
                            GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position);
                            explosion.GetComponent <ParticleSystem>().Play();
                            Object.Destroy(explosion, 2f);
                        }

                        ForceDestroyProjectile(gameObject);
                        return;
                    }
                }
            }

            if (navigateToTarget)
            {
                //if (fixedUpdate)
                {
                    ProjectileData d = GetProjectileData(gameObject);
                    if (d == null || d.proj == null)
                    {
                        return;
                    }

                    if (d.lastUpdateTime + updateInterval <= Time.time)
                    {
                        d.lastUpdateTime = Time.time;

                        // find new target
                        if (d.target == null)
                        {
                            //if (d.lastChooseTarget + chooseTargetInterval < Time.time)
                            {
                                d.lastChooseTarget = Time.time;

                                if (!navigateLookOnlyForward)
                                {
                                    float angle = d.proj.transform.rotation.eulerAngles.z;

                                    List <GameObject> candidates = new List <GameObject>();

                                    foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                                    {
                                        if (c.gameObject.Equals(d.proj))
                                        {
                                            continue;
                                        }

                                        if (d.HasHit(c.gameObject))
                                        {
                                            continue;
                                        }

                                        if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                        {
                                            continue;
                                        }

                                        Character targetCh = c.gameObject.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        candidates.Add(c.gameObject);
                                    }

                                    candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                                    foreach (GameObject c in candidates)
                                    {
                                        Character targetCh = c.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        d.target = targetCh;
                                        d.SaveHit(c.gameObject);
                                        AdjustToTarget(d);
                                        break;
                                    }
                                }
                                else                                 // scan only forward targets
                                {
                                    float angle = d.proj.transform.rotation.eulerAngles.z;

                                    Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y);
                                    Vector3 perpend   = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position);

                                    Debug.DrawRay(d.proj.transform.position, perpend * 10, Color.red, 1f);

                                    Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, Color.green, 1f);
                                    Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * (-navigateAimArea / 2f), Color.blue, 1f);

                                    List <GameObject> candidates = new List <GameObject>();

                                    foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f)))
                                    {
                                        if (c.gameObject.Equals(d.proj))
                                        {
                                            continue;
                                        }

                                        if (d.HasHit(c.gameObject))
                                        {
                                            continue;
                                        }

                                        if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                        {
                                            continue;
                                        }

                                        candidates.Add(c.gameObject);
                                    }

                                    candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                                    foreach (GameObject c in candidates)
                                    {
                                        Character targetCh = c.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        d.target = targetCh;
                                        d.SaveHit(c.gameObject);
                                        AdjustToTarget(d);
                                        break;
                                    }
                                }
                            }
                        }

                        if (d.target != null)
                        {
                            AdjustToTarget(d);
                        }
                    }
                }
            }
        }