Advertisement
gginj

down

Sep 28th, 2022
640
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.67 KB | None | 0 0
  1. /**************************************                                
  2.     Copyright Unluck Software  
  3.     www.chemicalbliss.com                              
  4. ***************************************/
  5.  
  6. using UnityEngine;
  7.  
  8. public class FlockChild:MonoBehaviour{
  9.     [HideInInspector]
  10.     public FlockController _spawner;            //Reference to the flock controller that spawned this bird
  11.     [HideInInspector]
  12.     public Vector3 _wayPoint;               //Waypoint used to steer towards
  13.     public float _speed;                        //Current speed of bird
  14.     [HideInInspector]      
  15.     public bool _dived =true;               //Indicates if this bird has recently performed a dive movement
  16.     [HideInInspector]
  17.     public float _stuckCounter;             //prevents looping around a waypoint by increasing minimum distance to waypoint
  18.     [HideInInspector]
  19.     public float _damping;                      //Damping used for steering (steer speed)
  20.     [HideInInspector]
  21.     public bool _soar = true;               // Indicates if this is soaring
  22.     [HideInInspector]
  23.     public bool _landing;                   // Indicates if bird is landing or sitting idle
  24.     [HideInInspector]
  25.     public float _targetSpeed;                  // Max bird speed
  26.     [HideInInspector]
  27.     public bool _move = true;               // Indicates if bird can fly
  28.     public GameObject _model;                   // Reference to bird model
  29.     public Transform _modelT;                   // Reference to bird model transform (caching tranform to avoid any extra getComponent calls)
  30.     [HideInInspector]
  31.     public float _avoidValue;                   //Random value used to check for obstacles. Randomized to lessen uniformed behaviour when avoiding
  32.     [HideInInspector]
  33.     public float _avoidDistance;                //How far from an obstacle this can be before starting to avoid it
  34.     float _soarTimer;  
  35.     bool _instantiated;
  36.     static int _updateNextSeed = 0;    
  37.     int _updateSeed = -1;
  38.     [HideInInspector]
  39.     public bool _avoid = true;
  40.     public Transform _thisT;                    //Reference to the transform component
  41.  
  42.     public Vector3 _landingPosOffset;
  43.     //[HideInInspector]
  44.     public bool Obstacle = false;
  45.  
  46.     public void Start(){
  47.         FindRequiredComponents();           //Check if references to transform and model are set (These should be set in the prefab to avoid doind this once a bird is spawned, click "Fill" button in prefab)
  48.         Wander(0.0f);
  49.         SetRandomScale();
  50.         _thisT.position = findWaypoint();  
  51.         RandomizeStartAnimationFrame();
  52.         InitAvoidanceValues();
  53.         _speed = _spawner._minSpeed;
  54.         _spawner._activeChildren++;
  55.         _instantiated = true;
  56.         if(_spawner._updateDivisor > 1){
  57.             int _updateSeedCap = _spawner._updateDivisor -1;
  58.             _updateNextSeed++;
  59.             this._updateSeed = _updateNextSeed;
  60.             _updateNextSeed = _updateNextSeed % _updateSeedCap;
  61.         }
  62.     }
  63.    
  64.     public void Update() {
  65.         //Skip frames
  66.         if (_spawner._updateDivisor <=1 || _spawner._updateCounter == _updateSeed){
  67.             SoarTimeLimit();
  68.             CheckForDistanceToWaypoint();
  69.             RotationBasedOnWaypointOrAvoidance();
  70.             LimitRotationOfModel();
  71.         }
  72.         if ((_wayPoint.y+_thisT.parent.transform.position.y) <= 0)
  73.         {
  74.             Debug.Log("under the terrain");
  75.         }
  76.     }
  77.    
  78.     public void OnDisable() {
  79.         CancelInvoke();
  80.         _spawner._activeChildren--;
  81.     }
  82.    
  83.     public void OnEnable() {
  84.         if(_instantiated){
  85.             _spawner._activeChildren++;
  86.             if(_landing){
  87.                 _model.GetComponent<Animation>().Play(_spawner._idleAnimation);
  88.             }else{
  89.                 _model.GetComponent<Animation>().Play(_spawner._flapAnimation);
  90.             }      
  91.         }
  92.     }
  93.    
  94.     public void FindRequiredComponents(){
  95.         if(_thisT == null)      _thisT = transform;
  96.         if(_model == null)      _model = _thisT.Find("Model").gameObject;  
  97.         if(_modelT == null) _modelT = _model.transform;
  98.     }
  99.    
  100.     public void RandomizeStartAnimationFrame(){
  101.         foreach(AnimationState state in _model.GetComponent<Animation>()) {
  102.             state.time = Random.value * state.length;
  103.         }
  104.     }
  105.    
  106.     public void InitAvoidanceValues(){
  107.         _avoidValue = Random.Range(.3f, .1f);  
  108.         if(_spawner._birdAvoidDistanceMax != _spawner._birdAvoidDistanceMin){
  109.             _avoidDistance = Random.Range(_spawner._birdAvoidDistanceMax , _spawner._birdAvoidDistanceMin);
  110.             return;
  111.         }
  112.         _avoidDistance = _spawner._birdAvoidDistanceMin;
  113.     }
  114.    
  115.     public void SetRandomScale(){
  116.         float sc = Random.Range(_spawner._minScale, _spawner._maxScale);
  117.         _thisT.localScale=new Vector3(sc,sc,sc);
  118.     }
  119.    
  120.     //Soar Timeout - Limits how long a bird can soar
  121.     public void SoarTimeLimit(){   
  122.         if(this._soar && _spawner._soarMaxTime > 0){       
  123.             if(_soarTimer > _spawner._soarMaxTime){
  124.                 this.Flap();
  125.                 _soarTimer = 0.0f;
  126.             }else {
  127.                 _soarTimer+=_spawner._newDelta;
  128.             }
  129.         }
  130.     }
  131.    
  132.     public void CheckForDistanceToWaypoint(){
  133.         if(!_landing && (_thisT.position - _wayPoint).magnitude < _spawner._waypointDistance+_stuckCounter){
  134.             Wander(0.0f);
  135.             _stuckCounter=0.0f;
  136.         }else if(!_landing){
  137.             _stuckCounter+=_spawner._newDelta;
  138.         }else{
  139.             _stuckCounter=0.0f;
  140.         }
  141.     }
  142.    
  143.     public void RotationBasedOnWaypointOrAvoidance(){
  144.  
  145.         Vector3 lookit = _wayPoint - _thisT.position;
  146.         if(_targetSpeed > -1 && lookit != Vector3.zero){
  147.         Quaternion rotation = Quaternion.LookRotation(lookit);
  148.        
  149.         _thisT.rotation = Quaternion.Slerp(_thisT.rotation, rotation, _spawner._newDelta * _damping);
  150.         }
  151.        
  152.         if(_spawner._childTriggerPos){
  153.             if((_thisT.position - _spawner._posBuffer).magnitude < 1){
  154.                 _spawner.SetFlockRandomPosition();
  155.             }
  156.         }
  157.         _speed = Mathf.Lerp(_speed, _targetSpeed, _spawner._newDelta* 2.5f);
  158.         //Position forward based on object rotation
  159.         if(_move){
  160.             _thisT.position += _thisT.forward*_speed*_spawner._newDelta;
  161.             if(_avoid && _spawner._birdAvoid)
  162.             {
  163.                 Avoidance();
  164.             }
  165.         }
  166.     }
  167.    
  168.     public void Avoidance() {
  169.         RaycastHit hitF = new RaycastHit();
  170.         RaycastHit hitD = new RaycastHit();
  171.         Vector3 fwd = _modelT.forward;
  172.         Quaternion rot = Quaternion.identity;
  173.         Vector3 rotE = Vector3.zero;
  174.         Vector3 pos = Vector3.zero;
  175.         pos = _thisT.position;
  176.         rot = _thisT.rotation;
  177.         rotE = _thisT.rotation.eulerAngles;
  178.         bool ForwardRay = Physics.Raycast(_modelT.position, (_wayPoint-_modelT.position), out hitF, _avoidDistance, _spawner._avoidanceMask);
  179.         if (ForwardRay)
  180.         {
  181.             //Debug.Log(!this._landing);
  182.  
  183.             Obstacle = true;
  184.             //Debug.Log(_wayPoint.y + " " + _thisT.position.y);
  185.             if (_wayPoint.y < _thisT.position.y)
  186.             //if (DownRay) //(_wayPoint.y < _thisT.localPosition.y)
  187.             {
  188.                 if (Physics.Raycast(_modelT.position, -Vector3.up, out hitD, _avoidDistance, _spawner._avoidanceMask))
  189.                 {
  190.                     rotE.x += _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping*0.1f;
  191.                     rotE.z += _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping*0.1f;
  192.                     rot.eulerAngles = rotE;
  193.                     Debug.Log("down");
  194.                     _thisT.rotation = rot;
  195.                     _wayPoint.y -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  196.                 }
  197.                 else //if (!this._landing)
  198.                 {          
  199.                     rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping*0.5f;
  200.                     rotE.z -= _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping*0.5f;
  201.                     rot.eulerAngles = rotE;
  202.                     //Debug.Log("up");
  203.                     _thisT.rotation = rot;             
  204.                     _wayPoint.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  205.                 }
  206.             }
  207.  
  208.             /*else if (this._landing)
  209.             {
  210.                 rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping*.1f;
  211.                 rotE.y += _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping*.1f;
  212.                 rot.eulerAngles = rotE;
  213.                 Debug.Log("left");
  214.                 _thisT.rotation = rot;
  215.             }*/
  216.  
  217.             else //if (!this._landing)
  218.             {          
  219.                 rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping*0.5f;
  220.                 rotE.z -= _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping*0.5f;
  221.                 rot.eulerAngles = rotE;
  222.                 //Debug.Log("up");
  223.                 _thisT.rotation = rot;             
  224.                 _wayPoint.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  225.             }
  226.  
  227.  
  228.         }
  229.         else
  230.         {
  231.             Obstacle = false;
  232.         }
  233. /*
  234.         if (Physics.Raycast(_thisT.position, fwd+(_modelT.right*_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask)){  
  235.             rotE.y -= _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  236.             rot.eulerAngles = rotE;
  237.             Debug.Log(AvoidanceNum + "right");
  238.             _thisT.rotation = rot;
  239.             r= true;
  240.         }else if (Physics.Raycast(_thisT.position, fwd+(_modelT.right*-_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask)){
  241.             rotE.y += _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  242.             rot.eulerAngles = rotE;
  243.             Debug.Log(AvoidanceNum + "left");
  244.             _thisT.rotation = rot;
  245.             r= true;       
  246.         }
  247.         if (_spawner._birdAvoidDown && !this._landing && Physics.Raycast(_thisT.position, -Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask)){         
  248.             rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  249.             rot.eulerAngles = rotE;
  250.             Debug.Log(AvoidanceNum + "down");
  251.  
  252.             _thisT.rotation = rot;             
  253.             pos.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  254.             _thisT.position = pos;
  255.             r= true;           
  256.         }else if (_spawner._birdAvoidUp && !this._landing && Physics.Raycast(_thisT.position, Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask)){          
  257.             rotE.x += _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  258.             rot.eulerAngles = rotE;
  259.             Debug.Log(AvoidanceNum + "up");
  260.             _thisT.rotation = rot;
  261.             pos.y -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  262.             _thisT.position = pos;
  263.             r= true;           
  264.         }*/
  265.     }
  266.    
  267.     public void LimitRotationOfModel(){
  268.         Quaternion rot = Quaternion.identity;
  269.         Vector3 rotE = Vector3.zero;
  270.         rot = _modelT.localRotation;
  271.         rotE = rot.eulerAngles;
  272.         if((_soar && _spawner._flatSoar|| _spawner._flatFly && !_soar)&& _wayPoint.y > _thisT.position.y||_landing){   
  273.             rotE.x = Mathf.LerpAngle(_modelT.localEulerAngles.x, -_thisT.localEulerAngles.x, _spawner._newDelta * 1.75f);
  274.             rot.eulerAngles = rotE;
  275.             _modelT.localRotation = rot;
  276.         }else{ 
  277.             rotE.x = Mathf.LerpAngle(_modelT.localEulerAngles.x, 0.0f, _spawner._newDelta * 1.75f);
  278.             rot.eulerAngles = rotE;
  279.             _modelT.localRotation = rot;
  280.         }
  281.     }
  282.    
  283.     public void Wander(float delay){
  284.         if((!_landing) && (!Obstacle)){
  285.             _damping = Random.Range(_spawner._minDamping, _spawner._maxDamping);      
  286.             _targetSpeed = Random.Range(_spawner._minSpeed, _spawner._maxSpeed);
  287.             Invoke("SetRandomMode", delay);
  288.         }
  289.     }
  290.    
  291.     public void SetRandomMode(){
  292.         CancelInvoke("SetRandomMode");
  293.         if(!_dived && Random.value < _spawner._soarFrequency){
  294.                 Soar();
  295.             }else if(!_dived && Random.value < _spawner._diveFrequency){   
  296.                 Dive();
  297.             }else{ 
  298.                 Flap();
  299.             }
  300.     }
  301.    
  302.     public void Flap(){
  303.         if(_move){
  304.             if(this._model != null) _model.GetComponent<Animation>().CrossFade(_spawner._flapAnimation, .5f);
  305.             _soar=false;
  306.             animationSpeed();
  307.             _wayPoint = findWaypoint();
  308.             if (_wayPoint.y < 0) _wayPoint.y = 0f;
  309.             _dived = false;
  310.         }
  311.     }
  312.    
  313.     public Vector3 findWaypoint(){
  314.         Vector3 t = Vector3.zero;
  315.         t.x = Random.Range(-_spawner._spawnSphere, _spawner._spawnSphere) + _spawner._posBuffer.x;
  316.         t.z = Random.Range(-_spawner._spawnSphereDepth, _spawner._spawnSphereDepth) + _spawner._posBuffer.z;
  317.         t.y = Random.Range(-_spawner._spawnSphereHeight, _spawner._spawnSphereHeight) + _spawner._posBuffer.y;
  318.         return t;
  319.     }
  320.    
  321.     public void Soar(){
  322.         if(_move){
  323.              _model.GetComponent<Animation>().CrossFade(_spawner._soarAnimation, 1.5f);
  324.             _wayPoint= findWaypoint();
  325.             _soar = true;
  326.         }
  327.     }
  328.    
  329.     public void Dive(){
  330.         if(_spawner._soarAnimation!=null){
  331.             _model.GetComponent<Animation>().CrossFade(_spawner._soarAnimation, 1.5f);
  332.         }else{
  333.             foreach(AnimationState state in _model.GetComponent<Animation>()) {
  334.                 if(_thisT.position.y < _wayPoint.y +25){
  335.                     state.speed = 0.1f;
  336.                 }
  337.             }
  338.         }
  339.         _wayPoint= findWaypoint();
  340.         _wayPoint.y -= _spawner._diveValue;
  341.         _dived = true;
  342.     }
  343.    
  344.     public void animationSpeed(){
  345.         foreach(AnimationState state in _model.GetComponent<Animation>()) {
  346.             if(!_dived && !_landing){
  347.                 state.speed = Random.Range(_spawner._minAnimationSpeed, _spawner._maxAnimationSpeed);
  348.             }else{
  349.                 state.speed = _spawner._maxAnimationSpeed;
  350.             }  
  351.         }
  352.     }
  353. }
  354.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement