/// <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; }
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); } }
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); } }
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); }