Exemple #1
0
    void StateWallJumpInAir(APFsmStateEvent eEvent)
    {
        switch (eEvent)
        {
        case APFsmStateEvent.eEnter:
        {
            m_wallJumpAutoRotate = m_basic.m_autoRotate;
            m_wallJumpFlipDone   = false;

            // prevent auto rotate for a while
            if (m_wallJumpAutoRotate)
            {
                m_basic.m_autoRotate = false;
            }
        }
        break;

        case APFsmStateEvent.eUpdate:
        {
            // go back to standard state as soon as touching ground
            if (m_onGround)
            {
                SetState(State.Standard);
            }
            else
            {
                // flip when needed
                bool bFlipEnabled = (m_wallJump.m_timeBeforeFlip >= 0f);
                if (!m_wallJumpFlipDone && bFlipEnabled && (m_fsm.GetFsmStateTime() >= m_wallJump.m_timeBeforeFlip))
                {
                    m_motor.Flip();
                    m_wallJumpFlipDone = true;
                }

                // enable back auto rotate if needed
                if (m_wallJumpAutoRotate && !m_basic.m_autoRotate && (m_fsm.GetFsmStateTime() >= m_wallJump.m_disableAutoRotateTime) && (m_wallJumpFlipDone || !bFlipEnabled))
                {
                    m_basic.m_autoRotate = true;
                }

                // standard process
                StateStandard(APFsmStateEvent.eUpdate);

                // leave state if work is ended and no new state is requested
                if (!IsNewStateRequested() && (!bFlipEnabled || m_wallJumpFlipDone) && (!m_wallJumpAutoRotate || m_basic.m_autoRotate))
                {
                    SetState(State.Standard);
                }
            }
        }
        break;

        case APFsmStateEvent.eLeave:
        {
            // restore initial auto rotate in all cases
            m_basic.m_autoRotate = m_wallJumpAutoRotate;
        }
        break;
        }
    }
Exemple #2
0
    void StateCrouch(APFsmStateEvent eEvent)
    {
        switch (eEvent)
        {
        case APFsmStateEvent.eEnter:
        {
            SendMessage("APOnCharacterCrouch", SendMessageOptions.DontRequireReceiver);
            PlayAnim(m_animations.m_crouch, GetPreviousState() == State.MeleeAttack ? 1f : 0f);
        }
        break;

        case APFsmStateEvent.eUpdate:
        {
            ApplyGravity();
            HandleCrouch();
            HandleHorizontalMove();
            HandleJump();
            HandleMeleeAttack();

            if (m_basic.m_enableCrouchedAutoRotate)
            {
                HandleAutoRotate();
            }
        }
        break;
        }
    }
Exemple #3
0
        /// Virtual method called when state enter, update or leave occur
        public override void OnStateUpdate(APFsmStateEvent eEvent, uint a_oState)
        {
            switch ((State)a_oState)
            {
            case State.Standard:
                m_controller.StateStandard(eEvent);
                break;

            case State.Crouch:
                m_controller.StateCrouch(eEvent);
                break;

            case State.WallJump:
                m_controller.StateWallJump(eEvent);
                break;

            case State.WallJumpInAir:
                m_controller.StateWallJumpInAir(eEvent);
                break;

            case State.MeleeAttack:
                m_controller.StateMeleeAttack(eEvent);
                break;
            }
        }
Exemple #4
0
 void StateStandard(APFsmStateEvent eEvent)
 {
     if (eEvent == APFsmStateEvent.eUpdate)
     {
         ApplyGravity();
         HandleCrouch();
         HandleHorizontalMove();
         HandleJump();
         HandleWallJump();
         HandleMeleeAttack();
         HandleAutoRotate();
     }
 }
Exemple #5
0
    void StateWallJump(APFsmStateEvent eEvent)
    {
        switch (eEvent)
        {
        case APFsmStateEvent.eEnter:
        {
            SendMessage("APOnCharacterWallJump", SendMessageOptions.DontRequireReceiver);
            PlayAnim(m_animations.m_wallJump, 0f);
            m_wallJumpAutoRotate = m_basic.m_autoRotate;

            // prevent auto rotate for a while
            if (m_wallJumpAutoRotate)
            {
                m_basic.m_autoRotate = false;
            }
        }
        break;

        case APFsmStateEvent.eUpdate:
        {
            // cancel any velocity
            m_motor.m_velocity = Vector2.zero;

            // wait for end of timer before effective jump
            if (m_fsm.GetFsmStateTime() >= m_wallJump.m_timeBeforeJump)
            {
                m_motor.m_velocity.y = m_wallJump.m_jumpPower.y;
                m_motor.m_velocity.x = m_wallJump.m_jumpPower.x * (m_motor.FaceRight ? -1f : 1f);
                SetState(State.WallJumpInAir);
            }
        }
        break;

        case APFsmStateEvent.eLeave:
        {
            // restore initial auto rotate in all cases
            m_basic.m_autoRotate = m_wallJumpAutoRotate;
        }
        break;
        }
    }
Exemple #6
0
 /// Virtual method called when state enter, update or leave occur
 public abstract void OnStateUpdate(APFsmStateEvent a_oEvent, uint a_oState);
Exemple #7
0
    void StateMeleeAttack(APFsmStateEvent eEvent)
    {
        switch (eEvent)
        {
        case APFsmStateEvent.eEnter:
        {
            SendMessage("APOnCharacterMeleeAttack", SendMessageOptions.DontRequireReceiver);
            PlayAnim(m_curAttackAnimHash, 0f);

            // clear buffer of hits & disable hit zones at init
            APMeleeAttack curAttack = m_meleeAttacks.m_attacks[m_curAttackId];
            foreach (APHitZone curHitZone in curAttack.m_hitZones)
            {
                curHitZone.attackHits.Clear();
            }
        }
        break;

        case APFsmStateEvent.eUpdate:
        {
            // update state
            ApplyGravity();
            HandleHorizontalMove();

            // Compute all hits for current attack
            APMeleeAttack curAttack = m_meleeAttacks.m_attacks [m_curAttackId];
            foreach (APHitZone curHitZone in curAttack.m_hitZones)
            {
                if (curHitZone.m_active && curHitZone.gameObject.activeInHierarchy)
                {
                    Vector2 wsPos    = curHitZone.transform.position;
                    int     hitCount = Physics2D.OverlapCircleNonAlloc(wsPos, curHitZone.m_radius, m_attackHitResult, m_motor.m_rayLayer);
                    for (int i = 0; i < hitCount; i++)
                    {
                        Collider2D curHit = m_attackHitResult[i];

                        // notify only hitable objects and not already hit by this hit zone
                        APHitable hitable = curHit.GetComponent <APHitable>();
                        if (hitable != null && !curHitZone.attackHits.Contains(hitable))
                        {
                            curHitZone.attackHits.Add(hitable);

                            // alert hitable
                            hitable.OnMeleeAttackHit(this, curHitZone);
                        }
                    }
                }
            }

            // make sure state does not end infinitely
            if (m_fsm.GetFsmStateTime() > m_maxAttackDuration)
            {
                SetState(GetPreviousState());
            }
        }
        break;

        case APFsmStateEvent.eLeave:
        {
            m_curAttackId = -1;
        }
        break;
        }
    }