Advertisement
gginj

Avoidance through saving last turn

Sep 23rd, 2022
758
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.53 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.     private int AvoidanceNum = 0;
  44.     private string lastTurn = "";
  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.     }
  73.    
  74.     public void OnDisable() {
  75.         CancelInvoke();
  76.         _spawner._activeChildren--;
  77.     }
  78.    
  79.     public void OnEnable() {
  80.         if(_instantiated){
  81.             _spawner._activeChildren++;
  82.             if(_landing){
  83.                 _model.GetComponent<Animation>().Play(_spawner._idleAnimation);
  84.             }else{
  85.                 _model.GetComponent<Animation>().Play(_spawner._flapAnimation);
  86.             }      
  87.         }
  88.     }
  89.    
  90.     public void FindRequiredComponents(){
  91.         if(_thisT == null)      _thisT = transform;
  92.         if(_model == null)      _model = _thisT.Find("Model").gameObject;  
  93.         if(_modelT == null) _modelT = _model.transform;
  94.     }
  95.    
  96.     public void RandomizeStartAnimationFrame(){
  97.         foreach(AnimationState state in _model.GetComponent<Animation>()) {
  98.             state.time = Random.value * state.length;
  99.         }
  100.     }
  101.    
  102.     public void InitAvoidanceValues(){
  103.         _avoidValue = Random.Range(.3f, .1f);  
  104.         if(_spawner._birdAvoidDistanceMax != _spawner._birdAvoidDistanceMin){
  105.             _avoidDistance = Random.Range(_spawner._birdAvoidDistanceMax , _spawner._birdAvoidDistanceMin);
  106.             return;
  107.         }
  108.         _avoidDistance = _spawner._birdAvoidDistanceMin;
  109.     }
  110.    
  111.     public void SetRandomScale(){
  112.         float sc = Random.Range(_spawner._minScale, _spawner._maxScale);
  113.         _thisT.localScale=new Vector3(sc,sc,sc);
  114.     }
  115.    
  116.     //Soar Timeout - Limits how long a bird can soar
  117.     public void SoarTimeLimit(){   
  118.         if(this._soar && _spawner._soarMaxTime > 0){       
  119.             if(_soarTimer > _spawner._soarMaxTime){
  120.                 this.Flap();
  121.                 _soarTimer = 0.0f;
  122.             }else {
  123.                 _soarTimer+=_spawner._newDelta;
  124.             }
  125.         }
  126.     }
  127.    
  128.     public void CheckForDistanceToWaypoint(){
  129.         if(!_landing && (_thisT.position - _wayPoint).magnitude < _spawner._waypointDistance+_stuckCounter){
  130.             Wander(0.0f);
  131.             _stuckCounter=0.0f;
  132.         }else if(!_landing){
  133.             _stuckCounter+=_spawner._newDelta;
  134.         }else{
  135.             _stuckCounter=0.0f;
  136.         }
  137.     }
  138.    
  139.     public void RotationBasedOnWaypointOrAvoidance(){
  140.        
  141.         Vector3 lookit = _wayPoint - _thisT.position;
  142.         if(_targetSpeed > -1 && lookit != Vector3.zero){
  143.         Quaternion rotation = Quaternion.LookRotation(lookit);
  144.        
  145.         _thisT.rotation = Quaternion.Slerp(_thisT.rotation, rotation, _spawner._newDelta * _damping);
  146.         }
  147.        
  148.         if(_spawner._childTriggerPos){
  149.             if((_thisT.position - _spawner._posBuffer).magnitude < 1){
  150.                 _spawner.SetFlockRandomPosition();
  151.             }
  152.         }
  153.         _speed = Mathf.Lerp(_speed, _targetSpeed, _spawner._newDelta* 2.5f);
  154.         //Position forward based on object rotation
  155.         if(_move){
  156.             _thisT.position += _thisT.forward*_speed*_spawner._newDelta;
  157.             if(_avoid && _spawner._birdAvoid)
  158.                 Avoidance();
  159.         }
  160.     }
  161.    
  162.     public void Avoidance() {
  163.         AvoidanceNum +=1;
  164.         RaycastHit hit = new RaycastHit();
  165.         Vector3 fwd = _modelT.forward;
  166.         Quaternion rot = Quaternion.identity;
  167.         Vector3 rotE = Vector3.zero;
  168.         Vector3 pos = Vector3.zero;
  169.         pos = _thisT.position;
  170.         rot = _thisT.rotation;
  171.         rotE = _thisT.rotation.eulerAngles;
  172.         bool RightRay = Physics.Raycast(_thisT.position, fwd+(_modelT.right*_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask);
  173.         bool LeftRay = Physics.Raycast(_thisT.position, fwd+(_modelT.right*-_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask);
  174.         bool ForwardRay = Physics.Raycast(_thisT.position, fwd+(_modelT.forward*_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask);
  175.         bool BackRay = Physics.Raycast(_thisT.position, fwd+(_modelT.forward*-_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask);
  176.         bool DownRay = (_spawner._birdAvoidDown && !this._landing && Physics.Raycast(_thisT.position, -Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask));     
  177.         bool UpRay = (_spawner._birdAvoidUp && !this._landing && Physics.Raycast(_thisT.position, Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask));
  178.  
  179.         /*if (RightRay || LeftRay)
  180.         {
  181.             if (DownRay)
  182.             {
  183.                 rotE.x += _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  184.                 rot.eulerAngles = rotE;
  185.                 Debug.Log(AvoidanceNum + "down");
  186.                 _thisT.rotation = rot;
  187.                 pos.y -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  188.                 _thisT.position = pos;
  189.                 r= true;
  190.             }
  191.             else
  192.             {
  193.                 rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  194.                 rot.eulerAngles = rotE;
  195.                 Debug.Log(AvoidanceNum + "up");
  196.  
  197.                 _thisT.rotation = rot;             
  198.                 pos.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  199.                 _thisT.position = pos;
  200.                 r= true;
  201.             }
  202.         }*/
  203.  
  204.         if (ForwardRay)
  205.         {
  206.             if (LeftRay)
  207.             {
  208.                 if (RightRay)
  209.                 {
  210.                     if ((DownRay)&&(lastTurn != "down"))
  211.                     {
  212.                         lastTurn= "down";
  213.                        
  214.                         rotE.x += _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  215.                         rot.eulerAngles = rotE;
  216.                         Debug.Log(AvoidanceNum + "down");
  217.                         _thisT.rotation = rot;
  218.                         pos.y -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  219.                         _thisT.position = pos;
  220.                     }
  221.                     else if (lastTurn != "up")
  222.                     {
  223.                         lastTurn= "up";
  224.                         rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  225.                         rot.eulerAngles = rotE;
  226.                         Debug.Log(AvoidanceNum + "up");
  227.  
  228.                         _thisT.rotation = rot;             
  229.                         pos.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  230.                         _thisT.position = pos;
  231.                     }
  232.                 }
  233.                 else if (lastTurn!= "left")
  234.                 {
  235.                     lastTurn= "left";
  236.                     rotE.y += _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  237.                     rot.eulerAngles = rotE;
  238.                     Debug.Log(AvoidanceNum + "left");
  239.                     _thisT.rotation = rot;
  240.                 }
  241.             }
  242.             else if ((RightRay) && (lastTurn== "right"))
  243.             {
  244.                 lastTurn= "right";
  245.                 rotE.y -= _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  246.                 rot.eulerAngles = rotE;
  247.                 Debug.Log(AvoidanceNum + "right");
  248.                 _thisT.rotation = rot;
  249.             }
  250.         }
  251.         else
  252.             lastTurn= "";
  253.        
  254.         /*if (RightRay && LeftRay)
  255.         {
  256.             if (DownRay)
  257.             {
  258.                 rotE.x += _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  259.                 rot.eulerAngles = rotE;
  260.                 //Debug.Log(AvoidanceNum + "down");
  261.                 _thisT.rotation = rot;
  262.                 pos.y -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  263.                 _thisT.position = pos;
  264.                 r= true;
  265.             }
  266.             else
  267.             {
  268.                 rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  269.                 rot.eulerAngles = rotE;
  270.                 //Debug.Log(AvoidanceNum + "up");
  271.  
  272.                 _thisT.rotation = rot;             
  273.                 pos.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  274.                 _thisT.position = pos;
  275.                 r= true;
  276.             }
  277.         }
  278.         else if (RightRay)
  279.         {
  280.             rotE.y -= _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  281.             rot.eulerAngles = rotE;
  282.             //Debug.Log(AvoidanceNum + "right");
  283.             _thisT.rotation = rot;
  284.             r= true;
  285.         }
  286.         else if (LeftRay)
  287.         {
  288.             rotE.y += _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  289.             rot.eulerAngles = rotE;
  290.             //Debug.Log(AvoidanceNum + "left");
  291.             _thisT.rotation = rot;
  292.             r= true;   
  293.         }*/
  294. /*
  295.         if (Physics.Raycast(_thisT.position, fwd+(_modelT.right*_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask)){  
  296.             rotE.y -= _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  297.             rot.eulerAngles = rotE;
  298.             Debug.Log(AvoidanceNum + "right");
  299.             _thisT.rotation = rot;
  300.             r= true;
  301.         }else if (Physics.Raycast(_thisT.position, fwd+(_modelT.right*-_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask)){
  302.             rotE.y += _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
  303.             rot.eulerAngles = rotE;
  304.             Debug.Log(AvoidanceNum + "left");
  305.             _thisT.rotation = rot;
  306.             r= true;       
  307.         }
  308.         if (_spawner._birdAvoidDown && !this._landing && Physics.Raycast(_thisT.position, -Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask)){         
  309.             rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  310.             rot.eulerAngles = rotE;
  311.             Debug.Log(AvoidanceNum + "down");
  312.  
  313.             _thisT.rotation = rot;             
  314.             pos.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  315.             _thisT.position = pos;
  316.             r= true;           
  317.         }else if (_spawner._birdAvoidUp && !this._landing && Physics.Raycast(_thisT.position, Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask)){          
  318.             rotE.x += _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
  319.             rot.eulerAngles = rotE;
  320.             Debug.Log(AvoidanceNum + "up");
  321.             _thisT.rotation = rot;
  322.             pos.y -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
  323.             _thisT.position = pos;
  324.             r= true;           
  325.         }*/
  326.     }
  327.    
  328.     public void LimitRotationOfModel(){
  329.         Quaternion rot = Quaternion.identity;
  330.         Vector3 rotE = Vector3.zero;
  331.         rot = _modelT.localRotation;
  332.         rotE = rot.eulerAngles;
  333.         if((_soar && _spawner._flatSoar|| _spawner._flatFly && !_soar)&& _wayPoint.y > _thisT.position.y||_landing){   
  334.             rotE.x = Mathf.LerpAngle(_modelT.localEulerAngles.x, -_thisT.localEulerAngles.x, _spawner._newDelta * 1.75f);
  335.             rot.eulerAngles = rotE;
  336.             _modelT.localRotation = rot;
  337.         }else{ 
  338.             rotE.x = Mathf.LerpAngle(_modelT.localEulerAngles.x, 0.0f, _spawner._newDelta * 1.75f);
  339.             rot.eulerAngles = rotE;
  340.             _modelT.localRotation = rot;
  341.         }
  342.     }
  343.    
  344.     public void Wander(float delay){
  345.         if(!_landing){
  346.             _damping = Random.Range(_spawner._minDamping, _spawner._maxDamping);      
  347.             _targetSpeed = Random.Range(_spawner._minSpeed, _spawner._maxSpeed);
  348.             Invoke("SetRandomMode", delay);
  349.         }
  350.     }
  351.    
  352.     public void SetRandomMode(){
  353.         CancelInvoke("SetRandomMode");
  354.         if(!_dived && Random.value < _spawner._soarFrequency){
  355.                 Soar();
  356.             }else if(!_dived && Random.value < _spawner._diveFrequency){   
  357.                 Dive();
  358.             }else{ 
  359.                 Flap();
  360.             }
  361.     }
  362.    
  363.     public void Flap(){
  364.         if(_move){
  365.             if(this._model != null) _model.GetComponent<Animation>().CrossFade(_spawner._flapAnimation, .5f);
  366.             _soar=false;
  367.             animationSpeed();
  368.             _wayPoint = findWaypoint();
  369.             _dived = false;
  370.         }
  371.     }
  372.    
  373.     public Vector3 findWaypoint(){
  374.         Vector3 t = Vector3.zero;
  375.         t.x = Random.Range(-_spawner._spawnSphere, _spawner._spawnSphere) + _spawner._posBuffer.x;
  376.         t.z = Random.Range(-_spawner._spawnSphereDepth, _spawner._spawnSphereDepth) + _spawner._posBuffer.z;
  377.         t.y = Random.Range(-_spawner._spawnSphereHeight, _spawner._spawnSphereHeight) + _spawner._posBuffer.y;
  378.         return t;
  379.     }
  380.    
  381.     public void Soar(){
  382.         if(_move){
  383.              _model.GetComponent<Animation>().CrossFade(_spawner._soarAnimation, 1.5f);
  384.             _wayPoint= findWaypoint();
  385.             _soar = true;
  386.         }
  387.     }
  388.    
  389.     public void Dive(){
  390.         if(_spawner._soarAnimation!=null){
  391.             _model.GetComponent<Animation>().CrossFade(_spawner._soarAnimation, 1.5f);
  392.         }else{
  393.             foreach(AnimationState state in _model.GetComponent<Animation>()) {
  394.                 if(_thisT.position.y < _wayPoint.y +25){
  395.                     state.speed = 0.1f;
  396.                 }
  397.             }
  398.         }
  399.         _wayPoint= findWaypoint();
  400.         _wayPoint.y -= _spawner._diveValue;
  401.         _dived = true;
  402.     }
  403.    
  404.     public void animationSpeed(){
  405.         foreach(AnimationState state in _model.GetComponent<Animation>()) {
  406.             if(!_dived && !_landing){
  407.                 state.speed = Random.Range(_spawner._minAnimationSpeed, _spawner._maxAnimationSpeed);
  408.             }else{
  409.                 state.speed = _spawner._maxAnimationSpeed;
  410.             }  
  411.         }
  412.     }
  413. }
  414.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement