/// <summary> /// Spawns the number of asteroids needed to reach maxAsteroids /// </summary> /// <param name='atSpawnDistance'> /// true = spawn on sphere at distanceSpawn * range (used for respawning asteroids) /// false = spawn in sphere within distanceSpawn * range (used for brand new asteroid fields) /// </param> void SpawnAsteroids(bool atSpawnDistance) { // Spawn new asteroids at a distance if count is below maxAsteroids (e.g. asteroids were destroyed outside of this script) while (_asteroidsTransforms.Count < maxAsteroids) { // Select a random asteroid from the prefab array GameObject _newAsteroidPrefab = prefabAsteroids[Random.Range(0, prefabAsteroids.Length)]; Vector3 _newPosition = Vector3.zero; if (atSpawnDistance) { // Spawn asteroid at spawn distance (this is used for existing asteroid fields so it spawns out of visible range) _newPosition = _transform.position + Random.onUnitSphere * _distanceToSpawn; } else { // Spawn asteroid anywhere within range (this is used for new asteroid fields before it becomes visible) _newPosition = _transform.position + Random.insideUnitSphere * _distanceToSpawn; } // Instantiate the new asteroid at a random location GameObject _newAsteroid = Instantiate(_newAsteroidPrefab, _newPosition, _transform.rotation); Renderer _renderer = _newAsteroid.GetComponent <Renderer>(); SU_Asteroid _asteroid = _newAsteroid.GetComponent <SU_Asteroid>(); // Add the asteroid to a list used to keep track of them _asteroidsTransforms.Add(_newAsteroid.transform); // Set a random material of the asteroid based on the weighted probabilty list switch (WeightedRandom(_materialList)) { case "VeryCommon": _renderer.sharedMaterial = materialVeryCommon[Random.Range(0, materialVeryCommon.Length)]; break; case "Common": _renderer.sharedMaterial = materialCommon[Random.Range(0, materialCommon.Length)]; break; case "Rare": _renderer.sharedMaterial = materialRare[Random.Range(0, materialRare.Length)]; break; case "VeryRare": _renderer.sharedMaterial = materialVeryRare[Random.Range(0, materialVeryRare.Length)]; break; } // Add the asteroid to a list used to keep track of them _asteroidsTransforms.Add(_newAsteroid.transform); // If the asteroid has the Asteroid script attached to it... if (_asteroid != null) { // Set the mesh of the asteroid based on chosen polycount _asteroid.SetPolyCount(polyCount); // If the asteroid has a collider... if (_newAsteroid.GetComponent <Collider>() != null) { _asteroid.SetPolyCount(polyCountCollider, true); } } // Set scale of asteroid within min/max scale * scaleMultiplier float _newScale = Random.Range(minAsteroidScale, maxAsteroidScale) * scaleMultiplier; _newAsteroid.transform.localScale = new Vector3(_newScale, _newScale, _newScale); // Set a random orientation of the asteroid _newAsteroid.transform.eulerAngles = new Vector3(Random.Range(0, 360), Random.Range(0, 360), Random.Range(0, 360)); Rigidbody _rigidbody = _newAsteroid.GetComponent <Rigidbody>(); if (isRigidbody) { // RIGIDBODY ASTEROIDS // If the asteroid prefab has a rigidbody... if (_rigidbody != null) { // Set the mass to mass specified in AsteroidField mutiplied by scale _rigidbody.mass = mass * _newScale; // Set the velocity (speed) of the rigidbody to within the min/max velocity range multiplier by velocityMultiplier _rigidbody.velocity = _newAsteroid.transform.forward * Random.Range(minAsteroidVelocity, maxAsteroidVelocity) * velocityMultiplier; // Set the angular velocity (rotational speed) of the rigidbody to within the min/max velocity range multiplier by velocityMultiplier _rigidbody.angularVelocity = new Vector3(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)) * Random.Range(minAsteroidAngularVelocity, maxAsteroidAngularVelocity) * angularVelocityMultiplier; } else { Debug.LogWarning("AsteroidField is set to spawn rigidbody asterodids but one or more asteroid prefabs do not have rigidbody component attached."); } } else { // NON-RIGIDBODY ASTEROIDS // If the asteroid prefab has a rigidbody... if (_rigidbody != null) { // Destroy the rigidbody since the asteroid field is spawning non-rigidbody asteroids Destroy(_rigidbody); } // If the asteroid has the Asteroid script attached to it... if (_asteroid != null) { // Set rotation and drift axis and speed _asteroid.rotationSpeed = Random.Range(minAsteroidRotationSpeed, maxAsteroidRotationSpeed); _asteroid.rotationalAxis = new Vector3(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); _asteroid.driftSpeed = Random.Range(minAsteroidDriftSpeed, maxAsteroidDriftSpeed); _asteroid.driftAxis = new Vector3(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); } } } }
void OnEnable() { // Cache reference to transform to increase performance _transform = transform; // Calculate the actual spawn _distanceToSpawn = range * distanceSpawn; // Populate the material list based on probabilty of materials if (_materialList.Count == 0) { if (materialVeryRare.Length > 0) { _materialList.Add(5, "VeryRare"); } if (materialRare.Length > 0) { _materialList.Add(5 + 15, "Rare"); } if (materialCommon.Length > 0) { _materialList.Add(5 + 15 + 30, "Common"); } if (materialVeryCommon.Length != 0) { _materialList.Add(5 + 15 + 30 + 50, "VeryCommon"); } else { Debug.LogError("Asteroid Field must have at least one Material in the 'Material Very Common' Array."); } } // Check if there are any asteroid objects that was spawned prior to this script being disabled // If there are asteroids in the list, activate the gameObject again. for (int i = 0; i < _asteroidsTransforms.Count; i++) { _asteroidsTransforms[i].gameObject.SetActive(true); } // Spawn new asteroids in the entire sphere (not just at spawn range, hence the "false" parameter) SpawnAsteroids(false); // Use transform as origin (center) of asteroid field. If null, use this transform. if (asteroidFieldOriginTransform == null) { asteroidFieldOriginTransform = transform; } // Set the parameters for each asteroid for fading/scaling for (int i = 0; i < _asteroidsTransforms.Count; i++) { SU_Asteroid _a = _asteroidsTransforms[i].GetComponent <SU_Asteroid>(); if (_a != null) { // When spawning asteroids, set the parameters for the shader based on parameters of this asteroid field _a.fadeAsteroids = fadeAsteroids; _a.fadeAsteroidsFalloffExponent = 1f; // fadeAsteroidsFalloffExponent; _a.distanceFade = distanceFade; _a.visibilityRange = range; } } }