protected virtual void SpawnCategory(SpawnerCategoryInfo category) { if (CanSpawnSingle(category) == false) { return; } // Make sure the category object is active. category.transform.gameObject.SetActive(true); for (int i = 0; i < category.amount.Generate(); i++) { if (Application.isPlaying && category.delay.max > 0f) { StartCoroutine(WaitAndSpawnSingle(category, category.delay.Generate())); } else { SpawnSingle(category); } } if (category.useIntervals && Application.isPlaying) { StartCoroutine(_DoCategoryIntervals(category, category.intervalEmitTimes)); } }
public virtual void DestroySpawnedObjects(SpawnerCategoryInfo category) { for (int i = category.transform.childCount - 1; i >= 0; i--) { objectCreator.DestroyObject(this, category, category.transform.GetChild(i).gameObject); } }
protected IEnumerator WaitAndSpawnSingle(SpawnerCategoryInfo category, float waitTime) { yield return(new WaitForSeconds(waitTime)); if (CanSpawnSingle(category)) { SpawnSingle(category); } }
protected virtual void SnapObjectToGround(SpawnerCategoryInfo category, GameObject spawnedInstance) { RaycastHit hit; // Raycast distance is actually multiplied by 2 because when spawned the object is placed 'maxRaycastDistance' from the ground to ensure it's never stuck below it. if (Physics.Raycast(spawnedInstance.transform.position, -spawnedInstance.transform.up, out hit, spawnerInfo.maxRaycastDistance * 2f, spawnerInfo.layerMask, QueryTriggerInteraction.Ignore)) { spawnedInstance.transform.position = hit.point; } }
protected virtual void InitSpawnedObject(SpawnerCategoryInfo category, GameObject spawnedInstance) { if (spawnerInfo.enableCallbacksOnSpawnedObjects && Application.isPlaying) { spawnedInstance.GetComponents <ISpawnerObjectCallbacks>(_objectsCallbacksCache); foreach (var callback in _objectsCallbacksCache) { callback.OnSpawned(this, category); } } }
public GameObject GetObject(SpawnerBase spawner, SpawnerCategoryInfo category) { GameObjectPool pool; var exists = _pools.TryGetValue(category, out pool); if (exists == false) { pool = new GameObjectPool(category.prefab, spawner.spawnerInfo.poolSize); _pools[category] = pool; } return(pool.Get()); }
public void DestroyObject(SpawnerBase spawner, SpawnerCategoryInfo category, GameObject obj) { #if UNITY_EDITOR if (Application.isPlaying == false) { UnityEngine.Object.DestroyImmediate(obj); } else { UnityEngine.Object.Destroy(obj); } #else UnityEngine.Object.Destroy(obj); #endif }
private IEnumerator _DoCategoryIntervals(SpawnerCategoryInfo category, int intervalsRemaining) { intervalsRemaining--; // Spawn the interval's objects if (CanSpawnSingle(category)) { for (int i = 0; i < category.intervalSpawnAmount.Generate(); i++) { SpawnSingle(category); } } yield return(new WaitForSeconds(category.intervalWaitTime.Generate())); StartCoroutine(_DoCategoryIntervals(category, intervalsRemaining)); }
public Vector3 GetPointInVolume(SpawnerBase spawner, SpawnerCategoryInfo category) { Assert.IsNotNull(distributionTexture, "Distribution texture is null, this isn't allowed!"); Vector2 outValue = new Vector2(); GetRandomValueFromSpatialTreeRecursive(rootCell, distributionTexture.width, distributionTexture.height, ref outValue); // Normalize outValue outValue.x /= rootCell.width; outValue.y /= rootCell.height; outValue.x *= volumeSize.x; outValue.y *= volumeSize.y; outValue.x -= volumeSize.x / 2f; outValue.y -= volumeSize.y / 2f; return(new Vector3(outValue.x, 0f, outValue.y)); }
/// <summary> /// Spawns a single instance and returns the spawned instance. /// </summary> protected virtual GameObject SpawnSingle(SpawnerCategoryInfo category) { var inst = objectCreator.GetObject(this, category); inst.transform.SetParent(category.transform); inst.transform.localPosition = volume.GetPointInVolume(this, category) + Vector3.up * spawnerInfo.maxRaycastDistance; // + some up to avoid it getting stuck in the ground. inst.transform.localRotation = Quaternion.Euler(category.rotation.Generate()); inst.transform.localScale = category.scale.Generate(); if (category.snapToGround) { SnapObjectToGround(category, inst); inst.transform.Translate(category.snapToGroundOffset); } InitSpawnedObject(category, inst); foreach (var c in _callbacksCache) { c.OnSpawnedObject(this, category, inst); } return(inst); }
public void DestroyObject(SpawnerBase spawner, SpawnerCategoryInfo category, GameObject obj) { _pools[category].Destroy(obj); }
public Vector3 GetPointInVolume(SpawnerBase spawner, SpawnerCategoryInfo category) { return(UnityEngine.Random.insideUnitSphere * _radius + Vector3.up * (_radius / 2f)); // + offset to spawn above the lower half of the sphere }
protected virtual bool CanSpawnSingle(SpawnerCategoryInfo category) { return(category.transform.childCount < spawnerInfo.maxObjects); }
public GameObject GetObject(SpawnerBase spawner, SpawnerCategoryInfo category) { return(UnityEngine.Object.Instantiate <GameObject>(category.prefab)); }
public void OnSpawned(SpawnerBase spawner, SpawnerCategoryInfo category) { _animator.Play(_hash); }