void HandleMeleeAttack() { // check if attack allowed State eCurState = GetState(); if (m_meleeAttacks.m_enabled && ((eCurState == State.Crouch) || (eCurState == State.Standard)) && !IsNewStateRequested()) { // parse list of attack, check if one is launched for (int i = 0; i < m_meleeAttacks.m_attacks.Length; i++) { APMeleeAttack curAttack = m_meleeAttacks.m_attacks [i]; if (curAttack.inputStatus) { // make sure this attack is enabled for this state string sAttackAnim = (eCurState == State.Crouch) ? curAttack.m_animCrouched : (m_onGround ? curAttack.m_animStand : curAttack.m_animInAir); if (string.IsNullOrEmpty(sAttackAnim)) { continue; } // launch attack m_curAttackId = i; m_curAttackAnimHash = Animator.StringToHash(sAttackAnim); m_attackCrouched = (eCurState == State.Crouch); SetState(State.MeleeAttack); return; } } } }
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; } }