/// <summary>
        /// Get component references once the network is initialized.
        /// </summary>
        public override void OnStartClient()
        {
            GameObject parentObj = ClientScene.FindLocalObject(parentId);

            spawner     = parentObj.GetComponent <ObjectSpawner>();
            spawner.obj = gameObject;
        }
Exemple #2
0
        private void FindPowerupUpdate()
        {
            SelectTarget(false);

            if (m_Target)
            {
                ChangeState(AIState.ActivelyAttack);
                return;
            }

            if (!m_PowerUp || !m_PowerUp.obj || (!tankPlayer.agent.hasPath && !tankPlayer.agent.pathPending) || tankPlayer.agent.pathStatus == NavMeshPathStatus.PathInvalid)
            {
                m_PowerUp = SelectPowerup();

                if (!m_PowerUp)
                {
                    ChangeState(AIState.ActivelyAttack);
                    return;
                }

                tankPlayer.MoveTo(m_PowerUp.transform.position);
            }
        }
Exemple #3
0
        private ObjectSpawner SelectPowerup()
        {
            if (m_SheildSpawner && tankPlayer.shield < m_ShieldAmount)
            {
                float timeBeforeShieldSpawn = m_NextSpawnTime - Time.time;
                NavMesh.CalculatePath(tankPlayer.Position, m_SheildSpawner.transform.position, NavMesh.AllAreas, m_PathBuffer);

                float timeToShieldSpawner = PathLength(m_PathBuffer) / m_TankSpeed;

                if (Mathf.Abs(timeBeforeShieldSpawn - timeToShieldSpawner) <= 2f)
                {
                    return(m_SheildSpawner);
                }
            }

            Collectible[] collectibles = CheckSurroundingObjectsByType(m_ItemSensorRadius,
                                                                       (Collectible c) => c.gameObject.activeSelf);

            if (collectibles.Length > 0)
            {
                //SortByDist<Collectible> comparer = new SortByDist<Collectible>(tankPlayer);
                SortByAStarDist <Collectible> comparer = new SortByAStarDist <Collectible>(tankPlayer);

                //low health, prioritize finding health and sheild
                if (tankPlayer.health / (float)tankPlayer.maxHealth < 0.5)
                {
                    Collectible[] healthBoosts = Array.FindAll(collectibles, (Collectible c) => c.GetType() == typeof(PowerupHealth));
                    Collectible   shield       = Array.Find(collectibles, (Collectible c) => c.GetType() == typeof(PowerupShield));

                    if (healthBoosts.Length > 0)
                    {
                        Array.Sort(healthBoosts, comparer);

                        if (shield)
                        {
                            return(comparer.Compare(shield, healthBoosts[0]) < 0 ? shield.spawner : healthBoosts[0].spawner);
                        }
                        else
                        {
                            return(healthBoosts[0].spawner);
                        }
                    }
                    else
                    {
                        if (shield)
                        {
                            return(shield.spawner);
                        }
                    }
                }

                Array.Sort(collectibles, comparer);

                List <Collectible> tempList = new List <Collectible>(collectibles.Length);
                int i;
                for (i = 0; i < collectibles.Length; i++)
                {
                    if (collectibles[i].GetType() == typeof(PowerupShield))
                    {
                        PowerupShield shield = (PowerupShield)collectibles[i];
                        if (tankPlayer.shield == m_ShieldAmount)
                        {
                            continue;
                        }

                        if (!m_SheildSpawner)
                        {
                            m_SheildSpawner = shield.spawner;
                        }

                        //always prioritize sheild
                        return(shield.spawner);
                    }

                    //prevent getting stuck trying to pick up a health item when on full health
                    if (collectibles[i].GetType() == typeof(PowerupHealth) && tankPlayer.health == tankPlayer.maxHealth)
                    {
                        continue;
                    }

                    //prevent getting stuck trying to pick up an item the tank already has
                    if (collectibles[i].GetType() == typeof(PowerupBullet)) //TODO: hardcoded 1
                    {
                        PowerupBullet powerupBullet = (PowerupBullet)collectibles[i];

                        if (tankPlayer.ammo == powerupBullet.amount && tankPlayer.currentBullet == powerupBullet.bulletIndex)
                        {
                            continue;
                        }
                    }

                    tempList.Add(collectibles[i]);
                }

                return(tempList.Count > 0 ? tempList[0].spawner : null);
            }
            else
            {
                return(null);
            }
        }
Exemple #4
0
        private void ActiveAttackUpdate()
        {
            SelectTarget(true);

            if (!m_Target)
            {
                ChangeState(AIState.FindPowerup);
                return;
            }

            ObjectSpawner spawner           = SelectPowerup();
            int           numHitsLeft       = NumOfHits(tankPlayer.health, tankPlayer.shield);
            int           targetNumHitsLeft = NumOfHits(m_Target.health, m_Target.shield);

            if (spawner)
            {
                if (numHitsLeft != 0 && targetNumHitsLeft / numHitsLeft >= 2)
                {
                    m_PowerUp = spawner;
                    tankPlayer.MoveTo(m_PowerUp.transform.position);
                    ChangeState(AIState.SimpleGoToPowerup);
                    return;
                }

                NavMesh.CalculatePath(tankPlayer.Position, spawner.transform.position, NavMesh.AllAreas, m_PathBuffer);
                float lengthToCollectible = PathLength(m_PathBuffer);

                NavMesh.CalculatePath(tankPlayer.Position, m_Target.Position, NavMesh.AllAreas, m_PathBuffer);
                float lengthToTarget = PathLength(m_PathBuffer);

                if ((lengthToTarget >= 10f && targetNumHitsLeft > 1) || lengthToTarget >= 15f)
                {
                    if (lengthToCollectible <= 10f || (spawner == m_SheildSpawner && lengthToCollectible <= 15f))
                    {
                        m_PowerUp = spawner;
                        tankPlayer.MoveTo(m_PowerUp.transform.position);
                        ChangeState(AIState.SimpleGoToPowerup);
                        return;
                    }
                }
            }

            bool  isSightblocked     = CheckObstaclesBetween(m_Target.Position, tankPlayer.Position, 0f);
            float linearDistToTarget = Vector3.Distance(m_Target.Position, tankPlayer.Position);

            //run away
            if (linearDistToTarget < m_EscapeDist && targetNumHitsLeft / numHitsLeft >= 2)
            {
                int steps = 10;

                //used if none of the points are traversible
                float   maxDistFromEnemy = Mathf.Epsilon;
                Vector3 maxDistPoint     = Vector3.zero;
                bool    notBlocked       = false;

                //used for traversible points
                float   minDistToPlayer = Mathf.Infinity;
                Vector3 minDistDir      = Vector3.zero;

                int   i         = steps;
                float angleStep = 360f / steps;

                NavMeshHit hitInfo;
                for (Vector3 dir = tankPlayer.Position - m_Target.Position; i >= 0; i--, dir = Quaternion.Euler(0f, angleStep, 0f) * dir)
                {
                    Vector3 idealpos = m_Target.Position + dir.normalized * m_EscapeDist;
                    if (NavMesh.Raycast(m_Target.Position, idealpos, out hitInfo, NavMesh.AllAreas))
                    {
                        Debug.DrawRay(m_Target.Position, dir, Color.red);
                        //Debug.Break();

                        if (maxDistFromEnemy < hitInfo.distance)
                        {
                            maxDistFromEnemy = hitInfo.distance;
                            maxDistPoint     = hitInfo.position;
                        }
                    }
                    else
                    {
                        Debug.DrawRay(m_Target.Position, dir, Color.blue);
                        //Debug.Break();

                        notBlocked = true;

                        float dist = Vector3.Distance(tankPlayer.Position, idealpos);

                        if (minDistToPlayer > dist)
                        {
                            minDistToPlayer = dist;
                            minDistDir      = dir.normalized;
                        }
                    }
                }

                if (!notBlocked)
                {
                    if (tankPlayer.agent.destination != maxDistPoint)
                    {
                        tankPlayer.agent.ResetPath();
                        //Vector3 dir = maxDistPoint - tankPlayer.Position;
                        //tankPlayer.SimpleMove(new Vector2(dir.x, dir.z));
                        tankPlayer.MoveTo(maxDistPoint);
                    }
                    else
                    {
                        tankPlayer.SimpleMove();
                    }
                }
                else
                {
                    Vector3 dest = m_Target.Position + minDistDir * m_EscapeDist;
                    if (tankPlayer.agent.destination != dest)
                    {
                        tankPlayer.agent.ResetPath();
                        //Vector3 dir = dest - tankPlayer.Position;
                        //tankPlayer.SimpleMove(new Vector2(dir.x, dir.z));
                        tankPlayer.MoveTo(dest);
                    }
                    else
                    {
                        tankPlayer.SimpleMove();
                    }
                }

                return;
            }

            //colliding or too close
            Collider c = m_Target.GetComponent <Collider>();

            if ((c && c.bounds.Intersects(m_Collider.bounds)) ||
                (!isSightblocked && linearDistToTarget < m_CombatDist))
            {
                int steps = 10;

                //used if none of the points are traversible
                float   maxDistFromEnemy = Mathf.Epsilon;
                Vector3 maxDistPoint     = Vector3.zero;
                bool    notBlocked       = false;

                //used for traversible points
                float   minDistToPlayer = Mathf.Infinity;
                Vector3 minDistDir      = Vector3.zero;

                int   i         = steps;
                float angleStep = 360f / steps;

                NavMeshHit hitInfo;
                for (Vector3 dir = tankPlayer.Position - m_Target.Position; i >= 0; i--, dir = Quaternion.Euler(0f, angleStep, 0f) * dir)
                {
                    Vector3 idealpos = m_Target.Position + dir.normalized * m_CombatDist;
                    if (NavMesh.Raycast(m_Target.Position, idealpos, out hitInfo, NavMesh.AllAreas))
                    {
                        Debug.DrawRay(m_Target.Position, dir, Color.red);
                        //Debug.Break();

                        if (maxDistFromEnemy < hitInfo.distance)
                        {
                            maxDistFromEnemy = hitInfo.distance;
                            maxDistPoint     = hitInfo.position;
                        }
                    }
                    else
                    {
                        Debug.DrawRay(m_Target.Position, dir, Color.blue);
                        //Debug.Break();

                        notBlocked = true;

                        float dist = Vector3.Distance(tankPlayer.Position, idealpos);

                        if (minDistToPlayer > dist)
                        {
                            minDistToPlayer = dist;
                            minDistDir      = dir.normalized;
                        }
                    }
                }

                if (!notBlocked)
                {
                    if (tankPlayer.agent.destination != maxDistPoint)
                    {
                        //Vector3 dir = maxDistPoint - tankPlayer.Position;
                        //tankPlayer.SimpleMove(new Vector2(dir.x, dir.z));
                        tankPlayer.MoveTo(maxDistPoint);
                    }
                    else
                    {
                        tankPlayer.SimpleMove();
                    }
                }
                else
                {
                    Vector3 dest = m_Target.Position + minDistDir * m_CombatDist;
                    if (tankPlayer.agent.destination != dest)
                    {
                        //Vector3 dir = dest - tankPlayer.Position;
                        //tankPlayer.SimpleMove(new Vector2(dir.x, dir.z));
                        tankPlayer.MoveTo(dest);
                    }
                    else
                    {
                        tankPlayer.SimpleMove();
                    }
                }

                return;
            }

            tankPlayer.MoveTo(m_Target.Position);
        }