コード例 #1
0
 // Angular velocity declines faster in Stun state
 private void FasterRotationDecline()
 {
     if (bCanRotate && EnemyMainFSM.Instance().CurrentStateIndex == EMState.Stunned)
     {
         if (fAngularVelocity >= 0f)
         {
             if (fAngularVelocity >= fMinAngularVelocity)
             {
                 fAngularVelocity -= fAngularDeclineFactor * Mathf.Sqrt(Mathf.Abs(fAngularVelocity) * 5f);
             }
         }
         else if (fAngularVelocity < 0f)
         {
             if (fAngularVelocity <= -fMinAngularVelocity)
             {
                 fAngularVelocity += fAngularDeclineFactor * Mathf.Sqrt(Mathf.Abs(fAngularVelocity) * 5f);
             }
         }
         // If the angular velocity is too small, set it to zero
         if (Mathf.Abs(fAngularVelocity) < fMinAngularVelocity / 2f)
         {
             fAngularVelocity = 0f;
         }
     }
 }
コード例 #2
0
    //Extract an Enemy Child Cell from the pool and spawn it to the position given in the perimeter
    public GameObject SpawnFromPool(Vector2 _SpawnPos, bool _Default)
    {
        if (!_Default)
        {
            EMHelper.Instance().StartProduceChild();
        }
        m_nSpawnCount++;

        //Extract the enemy child cell pool from the pool and add it to the enemy child cell list
        if (s_ECPool.Peek() == null)
        {
            return(null);
        }

        GameObject newChild = s_ECPool.Dequeue();

        newChild.transform.position = _SpawnPos;
        MessageDispatcher.Instance.DispatchMessage(this.gameObject, newChild, MessageType.Idle, 0);
        EnemyMainFSM.Instance().ECList.Add(newChild.GetComponent <EnemyChildFSM> ());
        EnemyMainFSM.Instance().AvailableChildNum++;

        if (IsPoolEmpty())
        {
            return(null);
        }

        return(newChild);
    }
コード例 #3
0
    public override void Enter()
    {
        if (m_pcFSM.m_formationCells[0] == m_pcFSM)
        {
            m_bIsLeader = true;
        }

        m_bIsLeaderAlive = true;
        m_nLeaderIndex   = 0;
        m_targetPos      = m_pcFSM.transform; // In case leader doesn't process first.

        if (m_pcFSM.attackMode == PlayerAttackMode.ScatterShot)
        {
            m_targetPos = EnemyMainFSM.Instance().transform;
        }

        if (m_pcFSM.attackMode == PlayerAttackMode.SwarmTarget)
        {
            AudioManager.PlayPMSoundEffectNoOverlap(PlayerMainSFX.Swarm);
        }
        else if (m_pcFSM.attackMode == PlayerAttackMode.ScatterShot)
        {
            AudioManager.PlayPMSoundEffectNoOverlap(PlayerMainSFX.ScatterShot);
        }
    }
コード例 #4
0
    private bool CheckGameEnd()
    {
        if (EnemyMainFSM.Instance() == null ||
            PlayerMain.Instance == null ||
            EMHelper.Instance() == null)
        {
            return(false);
        }

        if (EnemyMainFSM.Instance().CurrentStateIndex == EMState.Die)
        {
            bPlayerWon  = true;
            bGameIsOver = true;
            return(true);
        }
        else if (PlayerMain.Instance.IsAlive == false)
        {
            bPlayerWon  = false;
            bGameIsOver = true;
            return(true);
        }
        else if (EMHelper.Instance().IsEnemyWin == true)
        {
            bPlayerWon  = false;
            bGameIsOver = true;
            return(true);
        }

        return(false);
    }
コード例 #5
0
    public Nutrients GetNearestResource()
    {
        Nutrients[] nutrientsPool   = Nutrients.playerNutrientPool;
        Nutrients   nearestNutrient = null;

        for (int i = 0; i < nutrientsPool.Length; i++)
        {
            // if: The current nutrients is NOT in the pool and NOT being collected by player
            if (!nutrientsPool[i].IsInPool && nutrientsPool[i].IsCollectable)
            {
                // if: This function only returns nutrients that is below the EnemyMain
                if (nutrientsPool[i].transform.position.y < EnemyMainFSM.Instance().transform.position.y - EnemyMainFSM.Instance().transform.lossyScale.y)
                {
                    // if: Target only nutrients that are middle of the playing field
                    if (Mathf.Abs(nutrientsPool[i].transform.position.x) < 4f)
                    {
                        // if: There is no nearest nutrients yet
                        if (nearestNutrient == null)
                        {
                            nearestNutrient = nutrientsPool[i];
                        }
                        // else if: The checking nutrient is nearer than the curent nearest nutrient
                        else if (Vector3.Distance(nearestNutrient.transform.position, PlayerSquadFSM.Instance.transform.position) > Vector3.Distance(nutrientsPool[i].transform.position, PlayerSquadFSM.Instance.transform.position))
                        {
                            nearestNutrient = nutrientsPool[i];
                        }
                    }
                }
            }
        }

        return(nearestNutrient);
    }
コード例 #6
0
 void Start()
 {
     if (instance == null)
     {
         instance = this;
     }
     // Initialization of difficulty and factors
     fHealthDiff           = 1f;
     fHealthWeight         = 1f;
     fNutrientDiff         = 1f;
     fNutrientWeight       = 1f;
     fLevelDiff            = 1f;
     fLevelWeight          = 1f;
     fCurrentDiff          = 1f;
     fMaxHealthInfluence   = .5f;
     fMaxNutrientInfluence = .5f;
     // Initialization of current health and num of nutrient
     if (EnemyMainFSM.Instance().Health != 0)
     {
         nCurrentHealth = EnemyMainFSM.Instance().Health;
     }
     if (EMController.Instance().NutrientNum != 0)
     {
         nCurrentNutrient = EMController.Instance().NutrientNum;
     }
 }
コード例 #7
0
    // Expand animation in Landmine state
    private void LandmineAnimation()
    {
        if (EnemyMainFSM.Instance().CurrentStateIndex == EMState.Landmine)
        {
            if (bIsExpanding)
            {
                if (currentScale.x <= fTargetSize)
                {
                    currentScale.x += fDefaultExpandRate * fLandmineExpandFactor * Mathf.Sqrt(fTargetSize - currentScale.x);
                    currentScale.y += fDefaultExpandRate * fLandmineExpandFactor * Mathf.Sqrt(fTargetSize - currentScale.y);
                }
                else
                {
                    bIsExpanding = false;
                    bIsShrinking = true;
                }
            }
            else if (!bIsExpanding &&
                     bIsShrinking &&
                     currentScale.x >= initialScale.x * Mathf.Sqrt(Mathf.Sqrt(Mathf.Sqrt(Mathf.Pow((float)EnemyMainFSM.Instance().Health, 1.5f)))))
            {
                currentScale.x -= fDefaultExpandRate * fLandmineExpandFactor * Mathf.Sqrt(Mathf.Abs(fTargetSize - currentScale.x));
                currentScale.y -= fDefaultExpandRate * fLandmineExpandFactor * Mathf.Sqrt(Mathf.Abs(fTargetSize - currentScale.y));
            }
            else if (!bIsExpanding &&
                     bIsShrinking &&
                     currentScale.x < initialScale.x * Mathf.Sqrt(Mathf.Sqrt(Mathf.Sqrt(Mathf.Pow((float)EnemyMainFSM.Instance().Health, 1.5f)))))
            {
                bIsShrinking = false;
                bIsExpanding = true;
            }

            transform.localScale = (Vector3)currentScale;
        }
    }
コード例 #8
0
    private Vector2 GetHeadingDirection()
    {
        Vector2 sumVector = Vector2.zero;

        sumVector.x = EnemyMainFSM.Instance().transform.position.x - m_pcFSM.m_formationCells[0].transform.position.x;
        sumVector.y = EnemyMainFSM.Instance().transform.position.y - m_pcFSM.m_formationCells[0].transform.position.y;
        return(sumVector.normalized);
    }
コード例 #9
0
 // Update health factor
 void HealthDiffUpdate()
 {
     // Max fHealthDiff = 1f + fMaxHealthInfluence
     if (EnemyMainFSM.Instance().Health != 0)
     {
         fHealthDiff = 1f + fMaxHealthInfluence / Mathf.Sqrt(Mathf.Sqrt((float)nCurrentHealth));
     }
 }
コード例 #10
0
 void RegainFunction()
 {
     // Production state
     if (EnemyMainFSM.Instance().LearningDictionary [EMState.Production] > 1f || EnemyMainFSM.Instance().LearningDictionary [EMState.Production] < -1f)
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Production] *= 0.95f;
     }
     else
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Production] = 0f;
     }
     // Maintain state
     if (EnemyMainFSM.Instance().LearningDictionary [EMState.Maintain] > 1f || EnemyMainFSM.Instance().LearningDictionary [EMState.Maintain] < -1f)
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Maintain] *= 0.95f;
     }
     else
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Maintain] = 0f;
     }
     // Defend state
     if (EnemyMainFSM.Instance().LearningDictionary [EMState.Defend] > 1f || EnemyMainFSM.Instance().LearningDictionary [EMState.Defend] < -1f)
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Defend] *= 0.95f;
     }
     else
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Defend] = 0f;
     }
     // AggressiveAttack state
     if (EnemyMainFSM.Instance().LearningDictionary [EMState.AggressiveAttack] > 1f || EnemyMainFSM.Instance().LearningDictionary [EMState.AggressiveAttack] < -1f)
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.AggressiveAttack] *= 0.95f;
     }
     else
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.AggressiveAttack] = 0f;
     }
     // CautiousAttack state
     if (EnemyMainFSM.Instance().LearningDictionary [EMState.CautiousAttack] > 1f || EnemyMainFSM.Instance().LearningDictionary [EMState.CautiousAttack] < -1f)
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.CautiousAttack] *= 0.95f;
     }
     else
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.CautiousAttack] = 0f;
     }
     // Landmine state
     if (EnemyMainFSM.Instance().LearningDictionary [EMState.Landmine] > 1f || EnemyMainFSM.Instance().LearningDictionary [EMState.Landmine] < -1f)
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Landmine] *= 0.95f;
     }
     else
     {
         EnemyMainFSM.Instance().LearningDictionary[EMState.Landmine] = 0f;
     }
 }
コード例 #11
0
    private Vector2 TargetPull()
    {
        Vector2 sumVector = -m_pcFSM.rigidbody2D.position;

        sumVector.x += EnemyMainFSM.Instance().transform.position.x;
        sumVector.y += EnemyMainFSM.Instance().transform.position.y;

        return(sumVector);
    }
コード例 #12
0
 private bool AreThereTargets()
 {
     if (EnemyMainFSM.Instance().ECList.Count > 0)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
コード例 #13
0
 private bool IsTargetAlive()
 {
     if (EnemyMainFSM.Instance().Health > 0)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
コード例 #14
0
 float ScoreCompressor(EMState state, float score)
 {
     if (EnemyMainFSM.Instance().LearningDictionary [state] > 0f)
     {
         return(score / Mathf.Sqrt(Mathf.Sqrt(Mathf.Abs(EnemyMainFSM.Instance().LearningDictionary [state]))));
     }
     else
     {
         return(score);
     }
 }
コード例 #15
0
    IEnumerator EnemyMainAggressiveAttackWaiting()
    {
        yield return(new WaitForSeconds(2f));

        Tutorial.Instance().tutorialState = TutorialState.EnemyMainAggressiveAttackWaiting;
        StartCoroutine(EMTransition.Instance().TransitionAvailability(6f));
        EnemyMainFSM.Instance().ChangeState(EMState.AggressiveAttack);
        Time.timeScale = 0.75f;
        yield return(new WaitForSeconds(4f));

        Tutorial.Instance().tutorialState = TutorialState.EnemyMainAggressiveAttackCompleted;
    }
コード例 #16
0
    // GetNearestTargetPosition(): Assign a target to aggressive squad child cells.
    public static bool GetNearestTargetPosition()
    {
        // if: There are no attacking squad children
        if (SquadChildFSM.StateCount(SCState.Attack) == 0)
        {
            return(false);
        }

        s_list_enemyChild = EnemyMainFSM.Instance().ECList;

        // if: There is no enemy child cells to attack
        if (s_list_enemyChild.Count == 0)
        {
            for (int i = 0; i < s_array_SquadChildFSM.Length; i++)
            {
                if (s_array_SquadChildFSM[i].EnumState == SCState.Attack)
                {
                    s_array_SquadChildFSM[i].Advance(SCState.Idle);
                }
            }
            return(false);
        }

        // for: Resets all the attackTarget of all squad children
        for (int i = 0; i < s_array_SquadChildFSM.Length; i++)
        {
            s_array_SquadChildFSM[i].attackTarget = null;
        }

        // for: Every enemy child in the list...
        for (int i = 0; i < s_list_enemyChild.Count; i++)
        {
            // for: Finds a squad children in the list...
            for (int j = 0; j < s_array_SquadChildFSM.Length; j++)
            {
                // if: The current squad children is attacking and it has no target
                if (s_array_SquadChildFSM[j].EnumState == SCState.Attack && s_array_SquadChildFSM[j].attackTarget == null)
                {
                    s_array_SquadChildFSM[j].attackTarget = s_list_enemyChild[i];
                }
            }
        }

        // for: This for loops returns all attacking squad children to idle when they have no target
        for (int i = 0; i < s_array_SquadChildFSM.Length; i++)
        {
            if (s_array_SquadChildFSM[i].EnumState == SCState.Attack && s_array_SquadChildFSM[i].attackTarget == null)
            {
                s_array_SquadChildFSM[i].Advance(SCState.Idle);
            }
        }
        return(true);
    }
コード例 #17
0
    IEnumerator EnemyMainLandmineWaiting()
    {
        yield return(new WaitForSeconds(2f));

        Tutorial.Instance().tutorialState = TutorialState.EnemyMainLandmineWaiting;
        StartCoroutine(EMTransition.Instance().TransitionAvailability(6f));
        EnemyMainFSM.Instance().ChangeState(EMState.Landmine);
        Time.timeScale = 0.75f;
        yield return(new WaitForSeconds(4f));

        Tutorial.Instance().tutorialState = TutorialState.EnemyMainLandmineCompleted;
        StartCoroutine(Ending());
    }
コード例 #18
0
 void Update()
 {
     // Remove destroyed items in enemy child list
     if (EnemyMainFSM.Instance() != null)
     {
         EnemyMainFSM.Instance().ECList.RemoveAll(item => item.CurrentStateEnum == ECState.Dead);
     }
     //Recalculate available enemy child cells
     m_EMFSM.AvailableChildNum = m_EMFSM.ECList.Count;
     // Check whether the player loses
     LoseCheck();
     // Check if the enemy main cell is visible
     VisibilityCheck();
 }
コード例 #19
0
 // Update the size of enemy main cell according to current health
 private void SizeUpdate()
 {
     if (EnemyMainFSM.Instance() != null)
     {
         if (currentScale != initialScale * Mathf.Sqrt(Mathf.Sqrt(Mathf.Sqrt(Mathf.Pow((float)EnemyMainFSM.Instance().Health, 1.5f)))) &&
             !bIsExpanding &&
             !bIsShrinking &&
             EnemyMainFSM.Instance().CurrentStateIndex != EMState.Die)
         {
             currentScale         = initialScale * Mathf.Sqrt(Mathf.Sqrt(Mathf.Sqrt(Mathf.Pow((float)EnemyMainFSM.Instance().Health, 1.5f))));
             transform.localScale = (Vector3)currentScale;
         }
     }
 }
コード例 #20
0
    IEnumerator EnemyMainProductionWaiting()
    {
        yield return(new WaitForSeconds(3f));

        Tutorial.Instance().tutorialState = TutorialState.EnemyMainProductionWaiting;
        // Prohibit other transitions in the next 6 seconds
        StartCoroutine(EMTransition.Instance().TransitionAvailability(6f));
        // Transition to Production state for demonstration
        EnemyMainFSM.Instance().ChangeState(EMState.Production);
        Time.timeScale = 0.75f;
        yield return(new WaitForSeconds(4f));

        Tutorial.Instance().tutorialState = TutorialState.EnemyMainProductionCompleted;
    }
コード例 #21
0
 // Update the size of enemy main cell according to current health
 private void SizeUpdate()
 {
     if (EnemyMainFSM.Instance() != null)
     {
         if (currentScale != initialScale * fSizeFactor &&
             !bIsExpanding &&
             !bIsShrinking &&
             nCurrentStateNo != 7)
         {
             currentScale         = initialScale * fSizeFactor;
             transform.localScale = (Vector3)currentScale;
         }
     }
 }
コード例 #22
0
    public override void Enter()
    {
        transition = m_EMFSM.emTransition;
        helper     = m_EMFSM.emHelper;

        transition = m_EMFSM.emTransition;
        // Reset transition availability
        transition.CanTransit = true;
        // Pause the transition for randomized time based on num of available child cells
        float fPauseTime = Random.Range(Mathf.Sqrt(Mathf.Sqrt(EnemyMainFSM.Instance().AvailableChildNum) * 10f) / EMDifficulty.Instance().CurrentDiff,
                                        Mathf.Sqrt(Mathf.Sqrt(EnemyMainFSM.Instance().AvailableChildNum) * 50f) / EMDifficulty.Instance().CurrentDiff);

        helper.StartPauseTransition(fPauseTime);
    }
コード例 #23
0
 private void SetLoseGameVisibility(bool _visible)
 {
     if (_visible)
     {
         enemyHealthText.text         = "Remaining\nEnemy\nHealth:\n\n" + EnemyMainFSM.Instance().Health + " / " + Settings.s_nEnemyMainInitialHealth;
         loseCanvasGrp.interactable   = true;
         loseCanvasGrp.blocksRaycasts = true;
         loseCanvasGrp.alpha          = 1f;
     }
     else
     {
         loseCanvasGrp.interactable   = false;
         loseCanvasGrp.blocksRaycasts = false;
         loseCanvasGrp.alpha          = 0f;
     }
 }
コード例 #24
0
    private void FindFarTarget()
    {
        int   nClosestEnemyCell = 0;
        float fshortestYDist    = 10000f;      // Arbitrarily high number.

        // Get Random Target from List.
        for (int i = 0; i < EnemyMainFSM.Instance().ECList.Count; i++)
        {
            if (EnemyMainFSM.Instance().ECList[i].transform.position.y < fshortestYDist)
            {
                fshortestYDist    = EnemyMainFSM.Instance().ECList[i].transform.position.y;
                nClosestEnemyCell = i;
            }
        }

        m_pcFSM.m_currentEnemyCellTarget = EnemyMainFSM.Instance().ECList[nClosestEnemyCell];
    }
コード例 #25
0
ファイル: Misc_UI.cs プロジェクト: raynertanxw/GDP_Cellulose
    void Update()
    {
        if (stunDisplayDuration > 0f)
        {
            stunDisplayDuration    -= Time.deltaTime;
            EnemyStunnedTextOffsetY = 1.0f + EnemyMainFSM.Instance().Health / 100.0f;

            Vector3 textPos = EnemyMainFSM.Instance().transform.position;
            textPos.y -= EnemyStunnedTextOffsetY;
            EnemyStunnedTextSpriteRen.transform.position = textPos;
        }
        else if (EnemyStunnedTextSpriteRen.enabled == true)
        {
            m_EnemyStunnedTextAnimate.StopExpandContract(false);
            EnemyStunnedTextSpriteRen.enabled = false;
        }
    }
コード例 #26
0
    // Rotate faster in AggresiveAttack and CautiousAttack states
    private void FasterRotation()
    {
        if (EnemyMainFSM.Instance().CurrentStateIndex == EMState.AggressiveAttack ||
            EnemyMainFSM.Instance().CurrentStateIndex == EMState.CautiousAttack)
        {
            // Angular velocity increases as time goes by
            if (fAngularVelocity >= 0f && bCanRotate)
            {
                if (fAngularVelocity >= fMinAngularVelocity)
                {
                    fAngularVelocity += fAngularDeclineFactor * Mathf.Sqrt(Mathf.Abs(fAngularVelocity)) *
                                        Mathf.Sqrt(Mathf.Sqrt(EnemyMainFSM.Instance().CurrentAggressiveness));
                }
            }
            else if (fAngularVelocity < 0f && bCanRotate)
            {
                if (fAngularVelocity <= -fMinAngularVelocity)
                {
                    fAngularVelocity -= fAngularDeclineFactor * Mathf.Sqrt(Mathf.Abs(fAngularVelocity)) *
                                        Mathf.Sqrt(Mathf.Sqrt(EnemyMainFSM.Instance().CurrentAggressiveness));
                }
            }

            // Make sure the angular velocity is not less than the minimum value
            if (Mathf.Abs(fAngularVelocity) < fMinAngularVelocity * 3f && bCanRotate)
            {
                if (!bIsRotatingLeft)
                {
                    fAngularVelocity = -fAngularIniFactor *Random.Range(.75f, 1.25f) * 1.5f;

                    bIsRotatingLeft = true;
                }
                else
                {
                    fAngularVelocity = fAngularIniFactor * Random.Range(.75f, 1.25f) * 1.5f;
                    bIsRotatingLeft  = false;
                }
            }

            thisRB.angularVelocity = fAngularVelocity;
        }
    }
コード例 #27
0
    void Update()
    {
        if (bCanStartCheck)
        {
            Critic();
        }

        if (bCanRegain)
        {
            RegainScoreCall();
        }
        // // Update the score on the inspector
        if (EnemyMainFSM.Instance() != null)
        {
            EnemyMainFSM.Instance().ScoreUpdate();
        }
        // Clamp the hided score value between -100f and 100f
        if (EnemyMainFSM.Instance() != null)
        {
            EnemyMainFSM.Instance().ScoreLimit();
        }
    }
コード例 #28
0
 void Update()
 {
     #region Update of health and num of nutrient, and difficulty factors
     if (EnemyMainFSM.Instance() != null)
     {
         // Health Update
         if (nCurrentHealth != EnemyMainFSM.Instance().Health)
         {
             nCurrentHealth = EnemyMainFSM.Instance().Health;
         }
         // Nutrient Update
         if (nCurrentNutrient != EMController.Instance().NutrientNum)
         {
             nCurrentNutrient = EMController.Instance().NutrientNum;
         }
         HealthDiffUpdate();
         NutrientDiffUpdate();
         LevelDiffUpdate();
     }
     #endregion
     // Update current difficulty
     CurrentDiffUpdate();
 }
コード例 #29
0
    // Private Functions
    void Update()
    {
        if (EnemyMainFSM.Instance() != null)
        {
            // Bouncing off EnemyMain
            Vector3 distanceBetween = transform.position - EnemyMainFSM.Instance().transform.position;
            // if: The enemy main is detected within its vicinity
            if (distanceBetween.magnitude < EnemyMainFSM.Instance().transform.lossyScale.x)
            {
                // bounceNormal: The reflection normal for the bounce
                Vector3 bounceNormal = Vector3.Normalize(transform.position - EnemyMainFSM.Instance().transform.position);
                m_RigidBody.velocity = Vector3.Reflect(m_RigidBody.velocity, bounceNormal);
            }
        }

        // Excution of the current state
        if (PlayerSquadFSM.Instance != null)
        {
            m_currentState.Execute();
        }

        // Post-Excution
    }
コード例 #30
0
    // Update angular velocity of the enemy main cell when rotation is allowed
    private void RotationUpdate()
    {
        // Angular velocity declines as time goes by in Production state
        if (fAngularVelocity >= 0f && bCanRotate && EnemyMainFSM.Instance().CurrentStateIndex == EMState.Production)
        {
            if (fAngularVelocity >= fMinAngularVelocity)
            {
                fAngularVelocity -= fAngularDeclineFactor * Mathf.Abs(fAngularVelocity / 3f);
            }
        }
        else if (fAngularVelocity < 0f && bCanRotate && EnemyMainFSM.Instance().CurrentStateIndex == EMState.Production)
        {
            if (fAngularVelocity <= -fMinAngularVelocity)
            {
                fAngularVelocity += fAngularDeclineFactor * Mathf.Abs(fAngularVelocity / 3f);
            }
        }

        // Make sure the angular velocity is not less than the minimum value
        if (Mathf.Abs(fAngularVelocity) < fMinAngularVelocity && bCanRotate && EnemyMainFSM.Instance().CurrentStateIndex == EMState.Production)
        {
            if (!bIsRotatingLeft)
            {
                fAngularVelocity = -fAngularIniFactor *Random.Range(.75f, 1.25f);

                bIsRotatingLeft = true;
            }
            else
            {
                fAngularVelocity = fAngularIniFactor * Random.Range(.75f, 1.25f);
                bIsRotatingLeft  = false;
            }
        }

        thisRB.angularVelocity = fAngularVelocity;
    }