IEnumerator PlaceEnv() { arPlane.GetComponent <LineRenderer>().enabled = false; arPlane.GetComponent <MeshRenderer>().enabled = false; arPlaneManager.enabled = false; yield return(null); EnvPrefab.SetActive(true); yield return(null); buttonText.text = buttonTexts[2]; ScanningButton.onClick.RemoveListener(placeEnvironement); ScanningButton.onClick.AddListener(PlaceDino); yield break; }
// 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()); } }
public override bool GetPlane(out BoundedPlane plane) { RaycastHit hit; if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer("ARGameObject"))) { ARPlane arPlane = hit.transform.GetComponent <ARPlane>(); if (arPlane != null && arPlane.boundedPlane.Alignment == PlaneAlignment.Horizontal) { LineRenderer lineRenderer = arPlane.GetComponent <LineRenderer>(); Vector3 camPos = lineRenderer.transform.InverseTransformPoint(Camera.main.transform.position); Vector2 dir = new Vector2(camPos.x, camPos.z); if (camPos.magnitude == 0) { camPos = Vector2.down; } else { camPos.Normalize(); } Vector3[] boundary = new Vector3[lineRenderer.positionCount]; lineRenderer.GetPositions(boundary); Vector2[] linePos = new Vector2[boundary.Length - 1]; Vector2[] lineDir = new Vector2[boundary.Length - 1]; float[] lineMag = new float[boundary.Length - 1]; for (int i = 0; i < linePos.Length; i++) { linePos[i] = new Vector2(boundary[i].x, boundary[i].z); lineDir[i] = new Vector2(boundary[i + 1].x, boundary[i + 1].z) - linePos[i]; lineMag[i] = lineDir[i].magnitude; lineDir[i].Normalize(); } float shortest = float.MaxValue; for (int d = 0; d < 4; d++) { float ang = (45f + 90f * d) * Mathf.Deg2Rad; Vector2 dirRot = new Vector2(dir.x * Mathf.Cos(ang) - dir.y * Mathf.Sin(ang), dir.x * Mathf.Sin(ang) + dir.y * Mathf.Cos(ang)); for (int i = 0; i < linePos.Length; i++) { Vector2 inter = Divide(-linePos[i], lineDir[i] - dirRot); float interDist = Vector2.Distance(inter, linePos[i]); if (interDist >= 0f && interDist <= lineMag[i]) { float dist = inter.magnitude; if (dist < shortest) { shortest = dist; } break; } } } float size = Mathf.Cos(45f * Mathf.Deg2Rad) * shortest; Vector3 forward = lineRenderer.transform.rotation * new Vector3(dir.x, 0f, dir.y); plane = new BoundedPlane() { Center = lineRenderer.transform.position, Pose = new Pose(lineRenderer.transform.position, Quaternion.LookRotation(forward, lineRenderer.transform.up)), Size = new Vector2(size, size) }; return(true); } } plane = new BoundedPlane(); return(false); }