Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /*****************************************
  2.  * This file is part of Impulse Framework.
  3.  
  4.     Impulse Framework is free software: you can redistribute it and/or modify
  5.     it under the terms of the GNU Lesser General Public License as published by
  6.     the Free Software Foundation, either version 3 of the License, or
  7.     any later version.
  8.  
  9.     Impulse Framework is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU Lesser General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU Lesser General Public License
  15.     along with Impulse Framework.  If not, see <http://www.gnu.org/licenses/>.
  16. *****************************************/
  17.  
  18. using UnityEngine;
  19. using System.Collections;
  20.  
  21. /// <summary>
  22. /// Spawns objects randomly from a list.
  23. /// The spawning bounds are the bounds of the Box Collider.
  24. /// </summary>
  25. [RequireComponent(typeof(BoxCollider))]
  26. public class ObjectSpawner : MonoBehaviour
  27. {
  28.     // Objects to spawn.
  29.     [SerializeField]
  30.     GameObject[] ObjectSpawnPrefabs;
  31.  
  32.     // Number of objects to spawn.
  33.     [SerializeField]
  34.     [Range(1, 100)]
  35.     int NumberToSpawn = 10;
  36.  
  37.     // The minimum distance between each spawned object.
  38.     [SerializeField]
  39.     [Range(0, 10000)]
  40.     float minDistanceBetweenSpawnedObjects = 10.0f;
  41.  
  42.     // The object that culling distance will be compared to. This object must have a Collider AND a Rigidbody.
  43.     // Ex: If you want objects to be hidden until they are within a certain range of the player, set the player object here.
  44.     [SerializeField]
  45.     Collider CullingTarget;
  46.  
  47.     // The distance from the culling target in which further objects should be hidden.
  48.     [SerializeField]
  49.     [Range(10, 10000)]
  50.     float hideSpawnedObjectDistance = 50.0f;
  51.  
  52.     // The currently spawned game objects. For internal tracking.
  53.     protected GameObject[] CurrentSpawnedObjects;
  54.  
  55.     // Our Box Collider.
  56.     BoxCollider Bounds;
  57.  
  58.     /// <summary>
  59.     /// Spawns random objects within the box collider bounds.
  60.     /// </summary>
  61.     public void SpawnObjects()
  62.     {
  63.         CurrentSpawnedObjects = new GameObject[NumberToSpawn];
  64.         Bounds = GetComponent<BoxCollider>();
  65.  
  66.         for (int i = 0; i < NumberToSpawn; i++)
  67.         {
  68.             // Get random position within this transform.
  69.             Vector3 rndPosWithin = new Vector3(Random.Range(-1f, 1f) * Bounds.size.x / 2,
  70.                                                Random.Range(-1f, 1f) * Bounds.size.x / 2,
  71.                                                Random.Range(-1f, 1f) * Bounds.size.z / 2);
  72.             rndPosWithin += transform.position;
  73.  
  74.             if (!isObjectTooClose(rndPosWithin))
  75.             {
  76.                 GameObject spawnedObject = (GameObject)Instantiate(ObjectSpawnPrefabs[Random.Range(0, ObjectSpawnPrefabs.Length)], rndPosWithin, Quaternion.identity);
  77.                 CurrentSpawnedObjects[i] = spawnedObject;
  78.                 CurrentSpawnedObjects[i].transform.parent = transform;
  79.  
  80.                 // Create a child game object, which we will attach the culling sphere to.
  81.                 GameObject cullingSphere = new GameObject("Culling Sphere");
  82.                 cullingSphere.transform.position = rndPosWithin;
  83.                 cullingSphere.transform.parent = spawnedObject.transform;
  84.  
  85.                 // We use a sphere collider to determine whether the object should be rendered.
  86.                 SphereCollider spawnCollider = cullingSphere.AddComponent<SphereCollider>();
  87.                 spawnCollider.radius = hideSpawnedObjectDistance;
  88.  
  89.                 // The CullObject script determines whether to show or hide the object.
  90.                 CullObject spawnCuller = cullingSphere.AddComponent<CullObject>();
  91.                 spawnCuller.CullingTarget = CullingTarget;
  92.  
  93.             }
  94.         }
  95.     }
  96.  
  97.     /// <summary>
  98.     /// Check if we have an object too close to another object.
  99.     /// </summary>
  100.     /// <param name="targetPosition"></param>
  101.     /// <returns></returns>
  102.     bool isObjectTooClose(Vector3 targetPosition)
  103.     {
  104.         for (int i = 0; i < CurrentSpawnedObjects.Length; i++)
  105.         {
  106.             if (CurrentSpawnedObjects[i] != null)
  107.             {
  108.                 if (Vector3.Distance(targetPosition, CurrentSpawnedObjects[i].transform.position) <= minDistanceBetweenSpawnedObjects)
  109.                 {
  110.                     return true;
  111.                 }
  112.             }
  113.         }
  114.         return false;
  115.     }
  116.  
  117. }