private IEnumerator _Attack(AttackAction attackAction) { float chargeDistance = (_chargeAmount - chargeMinLength + 0.1f) * 2.5f; if (_isparticleTrailNotNull) { var emissionModule = _repelCirclePart.particleTrail.emission; emissionModule.rateOverDistance = TrailRateOverDistance; } weapon.Blocking = true; _rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous; while (chargeDistance > 0 && _repelCirclePart.energy > 0 && !_repelCirclePart.touchingHittable) { _rb.gravityScale = 0; _rb.velocity = attackSpeed * _dir; chargeDistance -= Time.fixedDeltaTime * attackLengthReducer; _repelCirclePart.energy -= Time.fixedDeltaTime * attackLengthReducer; yield return(Yields.WaitForFixedUpdate); } attackAction.state = AttackState.Recovering; attackAction.BeginRecovering(); }
/// <summary> Receives events from weapon animations. </summary> /// <param name="e"> The object sent from the animation </param> /// <param name="duration"> An optional duration that some events need </param> public void ReceiveAnimationEvent(AnimationEventObject e, float duration) { if (primaryAttack.state == AttackState.Ended) { return; } if (e == _animEventObjs.attackFadeIn && primaryAttack.state == AttackState.WindingUp) { FadeAttackIn(duration); } else if (e == _animEventObjs.attackAttackingStart && primaryAttack.state == AttackState.WindingUp) { primaryAttack.BeginAttacking(); } else if (e == _animEventObjs.attackAttackingEnd && primaryAttack.state == AttackState.Attacking) { primaryAttack.BeginRecovering(); } else if (e == _animEventObjs.attackFadeOut && primaryAttack.state == AttackState.Recovering) { primaryAttack.EndAttack(duration); } }
internal IEnumerator _CheckMeleeHit(AttackAction attackAction) { DirectionalAttackDefinition attackDefinition = attackAction.attackDefinition; _prevBase = weaponBase.position; _prevTip = weaponTip.position; while (attackAction.state == AttackState.Attacking) { bool GetBaddyHit(out RaycastHit2D swingCheck) { bool HitBaddy(RaycastHit2D rHit) { #if UNITY_EDITOR if (visualizeDebug && rHit && !(rHit.collider.GetComponentInParent <IDamageable>() is null) && Linecast(_prevBase, rHit.point, whatIsNotHittable & ~(1 << rHit.collider.gameObject.layer))) { Debug.DrawLine(_prevBase, rHit.point, Color.red); } #endif return(rHit && !(rHit.collider.GetComponentInParent <IDamageable>() is null) && // Make sure nothing of a different layer is between where the sword was and where it hit !Linecast(_prevBase, rHit.point, whatIsNotHittable & ~(1 << rHit.collider.gameObject.layer))); } // print("CHECK1"); //CHECK1: along blade Vector2 basePos = weaponBase.position; Vector2 tipPos = weaponTip.position; swingCheck = Linecast(basePos, tipPos, whatIsHittable); #if UNITY_EDITOR if (visualizeDebug) { Debug.DrawLine(basePos, tipPos); } #endif if (HitBaddy(swingCheck)) { return(true); } // print("CHECK2"); //CHECK2: along tip movement swingCheck = Linecast(_prevTip, tipPos, whatIsHittable); #if UNITY_EDITOR if (visualizeDebug) { Debug.DrawLine(_prevTip, tipPos); } #endif if (HitBaddy(swingCheck)) { return(true); } // print("CHECK3"); //CHECK3: along base movement swingCheck = Linecast(_prevBase, basePos, whatIsHittable); #if UNITY_EDITOR if (visualizeDebug) { Debug.DrawLine(_prevBase, basePos); } #endif if (HitBaddy(swingCheck)) { return(true); } // print("CHECK4"); //CHECK4: along lower third movement swingCheck = Linecast(Vector2.Lerp(_prevBase, _prevTip, 0.33f), Vector2.Lerp(basePos, tipPos, 0.33f), whatIsHittable); #if UNITY_EDITOR if (visualizeDebug) { Debug.DrawLine(Vector2.Lerp(_prevBase, _prevTip, 0.33f), Vector2.Lerp(basePos, tipPos, 0.33f)); } #endif if (HitBaddy(swingCheck)) { return(true); } // print("CHECK5"); //CHECK5: along upper third movement swingCheck = Linecast(Vector2.Lerp(_prevBase, _prevTip, 0.66f), Vector2.Lerp(basePos, tipPos, 0.66f), whatIsHittable); #if UNITY_EDITOR if (visualizeDebug) { Debug.DrawLine(Vector2.Lerp(_prevBase, _prevTip, 0.66f), Vector2.Lerp(basePos, tipPos, 0.66f)); } #endif if (HitBaddy(swingCheck)) { return(true); } // print("CHECK6"); //CHECK6: along first third blade float swordLength = Vector2.Distance(basePos, tipPos); Vector2 baseMid = Vector2.Lerp(_prevBase, basePos, 0.33f); Vector2 tipMid = Vector2.Lerp(_prevTip, tipPos, 0.33f); swingCheck = Raycast(baseMid, tipMid - baseMid, swordLength, whatIsHittable); #if UNITY_EDITOR if (visualizeDebug) { Debug.DrawRay(baseMid, (tipMid - baseMid).normalized * swordLength); } #endif if (HitBaddy(swingCheck)) { return(true); } // print("CHECK7"); //CHECK7: along second third blade baseMid = Vector2.Lerp(_prevBase, basePos, 0.66f); tipMid = Vector2.Lerp(_prevTip, tipPos, 0.66f); swingCheck = Raycast(baseMid, tipMid - baseMid, swordLength, whatIsHittable); #if UNITY_EDITOR if (visualizeDebug) { Debug.DrawRay(baseMid, (tipMid - baseMid).normalized * swordLength); } #endif return(HitBaddy(swingCheck)); } // Check for any hits, then update the prev things bool baddyHit = GetBaddyHit(out RaycastHit2D swingHit); _prevBase = weaponBase.position; _prevTip = weaponTip.position; // Wait till next frame if we didn't hit anything hittable if (!baddyHit) { yield return(Yields.WaitForFixedUpdate); continue; } IDamageable damageable = swingHit.collider.GetComponentInParent <IDamageable>(); Vector2 point = swingHit.point; Vector2 force = mvmt.rb.velocity; //Relative Velocity if (swingHit.collider.attachedRigidbody) { force -= swingHit.collider.attachedRigidbody.velocity; } force = mass * force; //Kinetic Energy = mv^2, but that was too much so just doing mv lol force += attackAction.attackDir * attackDefinition.knockback; // Add knockback in the direction of the swing switch (damageable.CheckProtected(point, swingHit.collider)) { case ProtectedType.Dodging: yield break; case ProtectedType.Blocking: { //TODO recoil and sparks or something shit idk var hTf = holder.transform; Vector2 recoil = (hTf.position - swingHit.transform.position + hTf.up / 6) * attackDefinition.knockback; holder.characterPhysics?.AddForceAt(point, recoil, GetComponentInParent <Collider2D>()); FadeAttackOut(0.30121f); attackAction.BeginRecovering(); yield break; } } // Damage scaled based on relative velocity int damageGiven = (int)Math.Max(attackAction.attackDefinition.damage, attackAction.attackDefinition.knockback * mvmt.rb.velocity.magnitude); damageable.DamageMe(point, force, damageGiven, swingHit.collider); yield break; } }