FlockController.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /****************************************
  2. Copyright 2016 Unluck Software
  3. www.chemicalbliss.com
  4. *****************************************/
  5. using UnityEngine;
  6. using System.Collections.Generic;
  7. public class FlockController:MonoBehaviour{
  8. public FlockChild _childPrefab; // Assign prefab with FlockChild script attached
  9. public int _childAmount = 250; // Number of objects
  10. public bool _slowSpawn; // Birds will not be instantiated all at once at start
  11. public float _spawnSphere = 3.0f; // Range around the spawner waypoints will created
  12. public float _spawnSphereHeight = 3.0f; // Height of the spawn sphere
  13. public float _spawnSphereDepth = -1.0f;
  14. public float _minSpeed = 6.0f; // minimum random speed
  15. public float _maxSpeed = 10.0f; // maximum random speed
  16. public float _minScale = .7f; // minimum random size
  17. public float _maxScale = 1.0f; // maximum random size
  18. public float _soarFrequency = 0.0f; // How often soar is initiated 1 = always 0 = never
  19. public string _soarAnimation="Soar"; // Animation -required- for soar functionality
  20. public string _flapAnimation="Flap"; // Animation used for flapping
  21. public string _idleAnimation="Idle"; // Animation -required- for sitting idle functionality
  22. public float _diveValue = 7.0f; // Dive depth
  23. public float _diveFrequency = 0.5f; // How often dive 1 = always 0 = never
  24. public float _minDamping = 1.0f; // Rotation tween damping, lower number = smooth/slow rotation (if this get stuck in a loop, increase this value)
  25. public float _maxDamping = 2.0f;
  26. public float _waypointDistance = 1.0f; // How close this can get to waypoint before creating a new waypoint (also fixes stuck in a loop)
  27. public float _minAnimationSpeed = 2.0f; // Minimum animation speed
  28. public float _maxAnimationSpeed = 4.0f; // Maximum animation speed
  29. public float _randomPositionTimer = 10.0f; // ***
  30. public float _positionSphere = 25.0f; // If _randomPositionTimer is bigger than zero the controller will be moved to a random position within this sphere
  31. public float _positionSphereHeight = 25.0f; // Overides height of sphere for more controll
  32. public float _positionSphereDepth = -1.0f;
  33. public bool _childTriggerPos; // Runs the random position function when a child reaches the controller
  34. public bool _forceChildWaypoints; // Forces all children to change waypoints when this changes position
  35. public float _forcedRandomDelay = 1.5f; // Random delay added before forcing new waypoint
  36. public bool _flatFly; // Birds will not rotate upwards as much when flapping
  37. public bool _flatSoar; // Birds will not rotate upwards as much when soaring
  38. public bool _birdAvoid; // Avoid colliders left and right
  39. public int _birdAvoidHorizontalForce = 1000; // How much a bird will react to avoid collision left and right
  40. public bool _birdAvoidDown; // Avoid colliders below
  41. public bool _birdAvoidUp; // Avoid colliders above bird
  42. public int _birdAvoidVerticalForce = 300; // How much a bird will react to avoid collision down and up
  43. public float _birdAvoidDistanceMax = 4.5f; // Maximum distance to check for collision to avoid
  44. public float _birdAvoidDistanceMin = 5.0f; // Minimum distance to check for collision to avoid
  45. public float _soarMaxTime; // Stops soaring after x seconds, use to avoid birds soaring for too long
  46. public LayerMask _avoidanceMask = (LayerMask)(-1); // Avoidance collider mask
  47. public List<FlockChild> _roamers;
  48. public Vector3 _posBuffer;
  49. public int _updateDivisor = 1; //Skip update every N frames (Higher numbers might give choppy results, 3 - 4 on 60fps , 2 - 3 on 30 fps)
  50. public float _newDelta;
  51. public int _updateCounter;
  52. public float _activeChildren;
  53. public bool _groupChildToNewTransform; // Parents fish transform to school transform
  54. public Transform _groupTransform; //
  55. public string _groupName = ""; //
  56. public bool _groupChildToFlock; // Parents fish transform to school transform
  57. public Vector3 _startPosOffset;
  58. public Transform _thisT; // Reference to the transform component
  59. public void Start() {
  60. _thisT = transform;
  61. ///FIX FOR UPDATING FROM OLDER VERSION
  62. if(_positionSphereDepth == -1){
  63. _positionSphereDepth = _positionSphere;
  64. }
  65. if(_spawnSphereDepth == -1){
  66. _spawnSphereDepth = _spawnSphere;
  67. }
  68. ///FIX
  69. _posBuffer = _thisT.position+_startPosOffset;
  70. if(!_slowSpawn){
  71. AddChild(_childAmount);
  72. }
  73. if(_randomPositionTimer > 0) InvokeRepeating("SetFlockRandomPosition", _randomPositionTimer, _randomPositionTimer); // > C
  74. }
  75. public void AddChild(int amount){
  76. if(_groupChildToNewTransform)InstantiateGroup();
  77. for(int i=0;i<amount;i++){
  78. FlockChild obj = (FlockChild)Instantiate(_childPrefab);
  79. obj._spawner = this;
  80. _roamers.Add(obj);
  81. AddChildToParent(obj.transform);
  82. }
  83. }
  84. public void AddChildToParent(Transform obj){
  85. if(_groupChildToFlock){
  86. obj.parent = transform;
  87. return;
  88. }
  89. if(_groupChildToNewTransform){
  90. obj.parent = _groupTransform;
  91. return;
  92. }
  93. }
  94. public void RemoveChild(int amount){
  95. for(int i=0;i<amount;i++){
  96. FlockChild dObj = _roamers[_roamers.Count-1];
  97. _roamers.RemoveAt(_roamers.Count-1);
  98. Destroy(dObj.gameObject);
  99. }
  100. }
  101. public void Update() {
  102. if(_activeChildren > 0){
  103. if(_updateDivisor > 1){
  104. _updateCounter++;
  105. _updateCounter = _updateCounter % _updateDivisor;
  106. _newDelta = Time.deltaTime*_updateDivisor;
  107. }else{
  108. _newDelta = Time.deltaTime;
  109. }
  110. }
  111. UpdateChildAmount();
  112. }
  113. public void InstantiateGroup(){
  114. if(_groupTransform != null) return;
  115. GameObject g = new GameObject();
  116. _groupTransform = g.transform;
  117. _groupTransform.position = _thisT.position;
  118. if(_groupName != ""){
  119. g.name = _groupName;
  120. return;
  121. }
  122. g.name = _thisT.name + " Fish Container";
  123. }
  124. public void UpdateChildAmount(){
  125. if(_childAmount>= 0 && _childAmount < _roamers.Count){
  126. RemoveChild(1);
  127. return;
  128. }
  129. if (_childAmount > _roamers.Count){
  130. AddChild(1);
  131. }
  132. }
  133. public void OnDrawGizmos() {
  134. if(_thisT == null) _thisT = transform;
  135. if(!Application.isPlaying && _posBuffer != _thisT.position+_startPosOffset){
  136. _posBuffer = _thisT.position+_startPosOffset;
  137. }
  138. if(_positionSphereDepth == -1){
  139. _positionSphereDepth = _positionSphere;
  140. }
  141. if(_spawnSphereDepth == -1){
  142. _spawnSphereDepth = _spawnSphere;
  143. }
  144. Gizmos.color = Color.blue;
  145. Gizmos.DrawWireCube (_posBuffer, new Vector3(_spawnSphere*2, _spawnSphereHeight*2 ,_spawnSphereDepth*2));
  146. Gizmos.color = Color.cyan;
  147. Gizmos.DrawWireCube (_thisT.position, new Vector3((_positionSphere*2)+_spawnSphere*2, (_positionSphereHeight*2)+_spawnSphereHeight*2 ,(_positionSphereDepth*2)+_spawnSphereDepth*2));
  148. }
  149. //Set waypoint randomly inside box
  150. public void SetFlockRandomPosition() {
  151. Vector3 t = Vector3.zero;
  152. t.x = Random.Range(-_positionSphere, _positionSphere) + _thisT.position.x;
  153. t.z = Random.Range(-_positionSphereDepth, _positionSphereDepth) + _thisT.position.z;
  154. t.y = Random.Range(-_positionSphereHeight, _positionSphereHeight) + _thisT.position.y;
  155. // var hit : RaycastHit;
  156. // if (Physics.Raycast(_posBuffer, t, hit, Vector3.Distance(_posBuffer, t))){
  157. // _posBuffer.LookAt(hit.point);
  158. // t = hit.point - (_thisT.forward*-3);
  159. // }
  160. _posBuffer = t;
  161. if(_forceChildWaypoints){
  162. for(int i = 0; i < _roamers.Count; i++) {
  163. (_roamers[i]).Wander(Random.value*_forcedRandomDelay);
  164. }
  165. }
  166. }
  167. //Instantly destroys all birds
  168. public void destroyBirds() {
  169. for(int i = 0; i < _roamers.Count; i++) {
  170. Destroy((_roamers[i]).gameObject);
  171. }
  172. _childAmount = 0;
  173. _roamers.Clear();
  174. }
  175. }