// Alert player while no planes are active IEnumerator FindARPlanesAlert() { // Remove enemy if things become disoriented if (enemySpawnObject != null) { Destroy(enemySpawnObject); } string alertMessage = ""; if (arPlanesTracking.Count > 0) { alertMessage = ""; AlertLog.write(alertMessage); yield return(new WaitForSeconds(0)); StartCoroutine(SpawnEnemiesAR()); } else { alertMessage = "LOOK AROUND SLOWLY FOR TANK PORTALS"; AlertLog.write(alertMessage); yield return(new WaitForSeconds(0.5f)); alertMessage = ""; AlertLog.write(alertMessage); yield return(new WaitForSeconds(0.5f)); StartCoroutine(FindARPlanesAlert()); } }
// Spawn tanks onto planes during the scene IEnumerator SpawnEnemiesAR() { // If there are reliable AR planes if (arPlanesTracking.Count > 0) { // If there is no current enemy spawn if (enemySpawnObject == null) { // Clear alert box string alertMessage = ""; AlertLog.write(alertMessage); // Buffer next spawn yield return(new WaitForSeconds(3)); // Determine current enemy tier int currentScore = PlayerPrefs.GetInt("PlayerScore"); while (enemyTier < spawnScores.Count() - 1 && currentScore >= spawnScores[enemyTier + 1]) { enemyTier++; } // Random seed System.Random randomSeed = new System.Random(); // Get random enemy from available tiers int randomEnemyIndex = randomSeed.Next(0, enemyTier + 1); // Get spawn position // If AR plane spawn if ((randomEnemyIndex == 0 || randomEnemyIndex == 2) && spawnOnARPlanes) { // If we lost our plane, start looking again if (!(arPlanesTracking.Count > 0)) { yield return(new WaitForSeconds(0.25f)); StartCoroutine(FindARPlanesAlert()); } // Get a random AR plane int randomPlaneIndex = randomSeed.Next(0, arPlanesTracking.Count); ARPlane arPlane = arPlanesTracking[randomPlaneIndex]; // Random x, z offset from center of AR plane // May sometimes not be above actual plane Vector3 min = arPlane.GetComponent <MeshFilter>().mesh.bounds.min; Vector3 max = arPlane.GetComponent <MeshFilter>().mesh.bounds.max; double randXDouble = (randomSeed.NextDouble() * ((double)max.x - (double)min.x)) + (double)min.x; float randX = (float)randXDouble; double randZDouble = (randomSeed.NextDouble() * ((double)max.z - (double)min.z)) + (double)min.z; float randZ = (float)randZDouble; // Store random AR spawn location spawnARPosition = new Vector3(arPlane.center.x + randX, arPlane.center.y + 0.05f, arPlane.center.z + randZ); // If the random point was not within the bounds, just place in center of the plane if (!Physics.Raycast(spawnARPosition, Vector3.down, 0.1f)) { spawnARPosition = new Vector3(arPlane.center.x, arPlane.center.y + 0.05f, arPlane.center.z); } // If below a different plane, lift tank up to highest plane Vector3 spawnSkyPosition = new Vector3(spawnARPosition.x, spawnARPosition.y + 100.0f, spawnARPosition.z); RaycastHit[] allSkyHits = Physics.RaycastAll(spawnSkyPosition, Vector3.down); Vector3 highestARPlanePos = new Vector3(spawnARPosition.x, -999.9f, spawnARPosition.z); // Find highest plane foreach (var hit in allSkyHits) { if (hit.collider.name.Substring(0, 7) == "ARPlane" && highestARPlanePos.y < hit.point.y) { highestARPlanePos = new Vector3(transform.position.x, hit.point.y, transform.position.z); } } // Place a bit above highest plane if one is found if (spawnARPosition.y < highestARPlanePos.y) { spawnARPosition.y = highestARPlanePos.y + 0.05f; } // Store player location information in reference to AR plane target = GameObject.FindWithTag("MainCamera"); targetVectorGround = new Vector3(target.transform.position.x, spawnARPosition.y, target.transform.position.z); // Store spawn position spawnPosition = spawnARPosition; } // If non-AR plane spawn else if (randomEnemyIndex == 1 || !spawnOnARPlanes) { // Get a random spawn location from given positions int randomSpawnIndex = randomSeed.Next(0, enemySpawnPoints.Count()); Transform enemySpawnPoint = enemySpawnPoints[randomSpawnIndex]; spawnPosition = new Vector3(enemySpawnPoint.position.x, enemySpawnPoint.position.y, enemySpawnPoint.position.z); } // Place enemy at spawn point enemySpawnObject = Instantiate(enemyPrefabs[randomEnemyIndex], spawnPosition, Quaternion.identity); // If AR spawn, rotate to face player if (randomEnemyIndex == 0) { // Spawn with random direction enemySpawnObject.transform.rotation = Quaternion.Euler(0, randomSeed.Next(0, 360), 0); } else if (randomEnemyIndex == 1) { // Let the missile go for 8 seconds int missileTimer = 8; while (enemySpawnObject != null && missileTimer > 0) { yield return(new WaitForSeconds(1f)); missileTimer--; } // If the missile was not destoryed after given time, // destory the missile if (enemySpawnObject != null) { Destroy(enemySpawnObject); } } else if (randomEnemyIndex == 2) { // Spawn facing player enemySpawnObject.transform.LookAt(targetVectorGround); } } // Wait some time then start again if (arPlanesTracking.Count > 0) { yield return(new WaitForSeconds(0.5f)); StartCoroutine(SpawnEnemiesAR()); } else { yield return(new WaitForSeconds(0)); StartCoroutine(FindARPlanesAlert()); } } // If there are no reliable AR planes else { yield return(new WaitForSeconds(0)); StartCoroutine(FindARPlanesAlert()); } }
void FixedUpdate() { if (Vector3.Distance(transform.position, target.transform.position) < 1.8f) { randomTurns = false; directTarget = true; } if (Vector3.Distance(transform.position, target.transform.position) < 0.2f) { directTarget = false; stopRotation = true; } if (!stopRotation) { if (directTarget) { transform.LookAt(target.transform); } if (randomTurns) { if (Vector3.Distance(transform.position, target.transform.position) > 7f) { transform.LookAt(target.transform); } else if (Time.time > nextTurnTime) { // Get next turn time System.Random randomSeed = new System.Random(); double timeRange = (double)turnIntervalMax - (double)(turnIntervalMin); double sampleTime = randomSeed.NextDouble(); double scaledTime = (sampleTime * timeRange) + (turnIntervalMin); float randomTime = (float)scaledTime; nextTurnTime = Time.time + randomTime; // Turn random direction double turnRange = (double)turnRangeMax - (double)(turnRangeMin); double sampleTurn = randomSeed.NextDouble(); double scaledTurn = (sampleTurn * turnRange) + (turnRangeMin); float turnDegree = (float)scaledTurn; transform.LookAt(target.transform); transform.Rotate(0.0f, turnDegree, 0.0f); } } } transform.position += transform.forward * moveSpeed * Time.deltaTime; string enemyAlert = ""; // Determine where the target is in reference to the player Vector3 enemyPos = Quaternion.Inverse(target.transform.rotation) * (transform.position - target.transform.position); bool easilyViewable = false; Vector3 screenPoint = camera.WorldToViewportPoint(transform.position); if (screenPoint.z > 0 && screenPoint.x > 0.1 && screenPoint.x < 0.9 && screenPoint.y > 0.1 && screenPoint.y < 0.9) { easilyViewable = true; } else { easilyViewable = false; } if (Vector3.Distance(target.transform.position, transform.position) < 3f) { enemyAlert += "ENEMY IN RANGE"; } if (!easilyViewable) { if (enemyPos.z < 0) { enemyAlert += "\n\nENEMY TO REAR"; } else if (enemyPos.x > 0.5f) { enemyAlert += "\n\nENEMY TO RIGHT"; } else if (enemyPos.x < -0.5f) { enemyAlert += "\n\nENEMY TO LEFT"; } else if (enemyPos.y < 0) { enemyAlert += "\n\nENEMY BELOW"; } } AlertLog.write(enemyAlert); }
// Update is called once per frame void Update() { // Check if there is a plane above the enemy Vector3 enemySkyPosition = new Vector3(transform.position.x, transform.position.y + 100.0f, transform.position.z); RaycastHit[] allSkyHits = Physics.RaycastAll(enemySkyPosition, Vector3.down); Vector3 highestARPlanePos = new Vector3(transform.position.x, -999.9f, transform.position.z); Vector3 highestARPlaneCenter = new Vector3(transform.position.x, -999.9f, transform.position.z); Vector3 highestARPlaneCenterGround = new Vector3(transform.position.x, transform.position.y, transform.position.z); foreach (var hit in allSkyHits) { print(hit.collider.name); if (hit.collider.name.Length > 7 && hit.collider.name.Substring(0, 7) == "ARPlane" && highestARPlanePos.y < hit.point.y) { highestARPlanePos = new Vector3(hit.point.x, hit.point.y, hit.point.z); highestARPlaneCenter = new Vector3( hit.collider.transform.position.x, hit.collider.transform.position.y, hit.collider.transform.position.z ); highestARPlaneCenterGround = new Vector3(highestARPlaneCenter.x, transform.position.y, highestARPlaneCenter.z); } } // There is a plane above the enemy if (allSkyHits.Count() > 0 && transform.position.y < highestARPlanePos.y) { if ((highestARPlanePos.y - transform.position.y) > .3 || facingClimbHeight == true) { float angle = 1; if (Vector3.Angle(transform.forward, highestARPlaneCenterGround - transform.position) > angle && facingClimbCenter == false) { Quaternion groundRotation = Quaternion.LookRotation(highestARPlaneCenterGround - transform.position); transform.rotation = Quaternion.RotateTowards(transform.rotation, groundRotation, turnSpeed * 1.2f * Time.deltaTime); } else { // Save original rotation if (facingClimbCenter == false) { originalRotation = transform.rotation; facingClimbCenter = true; } if (Vector3.Angle(transform.forward, highestARPlaneCenter - transform.position) > angle && facingClimbHeight == false) { Vector3 climbTo = new Vector3(highestARPlaneCenter.x, highestARPlaneCenter.y + 0.05f, highestARPlaneCenter.z); Quaternion climbRotation = Quaternion.LookRotation(climbTo - transform.position); transform.rotation = Quaternion.RotateTowards(transform.rotation, climbRotation, turnSpeed * 1.2f * Time.deltaTime); } // Looking up to plane, start climbing else { facingClimbHeight = true; transform.position += transform.forward * moveSpeed * 1.2f * Time.deltaTime; } } } else { transform.position = new Vector3(highestARPlanePos.x, highestARPlanePos.y + 0.05f, highestARPlanePos.z); } } // Climbed above plane or was already above // Check to make sure enemy is flat again else { // Level enemy if not leveled from climbing float angle = 0.1f; if (facingClimbHeight == true && transform.rotation != originalRotation) { transform.rotation = Quaternion.RotateTowards(transform.rotation, originalRotation, turnSpeed * 1.2f * Time.deltaTime); } else { facingClimbHeight = false; facingClimbCenter = false; target = GameObject.FindWithTag("MainCamera"); targetVectorARGround = new Vector3(target.transform.position.x, transform.position.y, target.transform.position.z); // This makes the enemy tank "look" at the player in regard to the x, z axis float turnAngle = 15; float stopAngle = 1; if (Vector3.Angle(transform.forward, targetVectorARGround - transform.position) > turnAngle) { turning = true; } if (Vector3.Angle(transform.forward, targetVectorARGround - transform.position) < stopAngle) { turning = false; } // Either turn towards player or move towards player if (turning == true) { Quaternion targetRotation = Quaternion.LookRotation(targetVectorARGround - transform.position); transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed * Time.deltaTime); } else if (Vector3.Distance(targetVectorARGround, transform.position) > 0.5f && (Physics.Raycast(transform.position, Vector3.down, 0.1f))) { transform.position += transform.forward * moveSpeed * Time.deltaTime; } } } string enemyAlert = ""; // Determine where the target is in reference to the player Vector3 enemyPos = Quaternion.Inverse(target.transform.rotation) * (transform.position - target.transform.position); bool easilyViewable = false; Vector3 screenPoint = camera.WorldToViewportPoint(transform.position); if (screenPoint.z > 0 && screenPoint.x > 0.1 && screenPoint.x < 0.9 && screenPoint.y > 0.1 && screenPoint.y < 0.9) { easilyViewable = true; } else { easilyViewable = false; } if (Vector3.Distance(targetVectorARGround, transform.position) < 2f) { enemyAlert += "ENEMY IN RANGE"; } print(enemyPos.ToString()); if (!easilyViewable) { if (enemyPos.z < 0) { enemyAlert += "\n\nENEMY TO REAR"; } else if (enemyPos.x > 0.5f) { enemyAlert += "\n\nENEMY TO RIGHT"; } else if (enemyPos.x < -0.5f) { enemyAlert += "\n\nENEMY TO LEFT"; } else if (enemyPos.y < 0) { enemyAlert += "\n\nENEMY BELOW"; } } AlertLog.write(enemyAlert); }