private void JumpOnTarget(Unit ActingUnit, Unit[] targetUnits, int targetIndex, Rigidbody actingRigidBody, int jumpsPerformed, int jumpLimit, int multibounceQuotient) { ActingUnit.Animator.SetTrigger("Airborn"); Unit targetUnit = targetUnits[targetIndex]; Vector3 targetPosition = targetUnit.HeadPosition.transform.position; Vector3 actingUnitPosition = ActingUnit.transform.position; Vector3 initialVelocity = CalculateInitialJumpVelocity(actingUnitPosition, targetPosition, JumpPeakOffset); //Jump and land on enemies head actingRigidBody.constraints = actingRigidBody.constraints & (~RigidbodyConstraints.FreezePosition); actingRigidBody.velocity = initialVelocity; InputBufferRef.FlushBuffer(); ActingUnit.WaitForTrigger(() => { actingRigidBody.constraints = actingRigidBody.constraints | RigidbodyConstraints.FreezePosition; float impactTime = Time.time; //play the impact animation and freeze the position ActingUnit.SetTriggerAndTriggerCallbackOnReenter("Impact", () => { ActionData.ApplyDamage(ActingUnit, targetUnits[targetIndex], this.BaseAttackDamage); bool actionCommandHit = false; foreach (InputBufferData inputData in InputBufferRef) { float timeDif = Math.Abs(impactTime - inputData.Time); if (timeDif > this.InvalidationWindow) { break; //no more commands to check } if (inputData.InputName.Equals(AButtonInputName)) { if (timeDif > this.ActionPressWindow || actionCommandHit) { actionCommandHit = false; //invalid button press recorded break; } actionCommandHit = true; } } jumpsPerformed++; bool jumpLimitReached = jumpsPerformed >= jumpLimit; //calculate new multibounceQuotient if (jumpsPerformed > 2 && !jumpLimitReached) { multibounceQuotient = (multibounceQuotient * (targetUnit as Enemy).PowerBounceMultiplier) / 100; int thresholdValue = UnityEngine.Random.Range(0, 101); jumpLimitReached = multibounceQuotient < thresholdValue; } //will do nothing if not performing a row bounce if (!actionCommandHit || jumpLimitReached) { //end the jump and return to the start Transform landingSpot; if (!actionCommandHit) { landingSpot = Unit.GetChildTransformByName(targetUnits[targetIndex].transform.parent, "Forward"); } else { landingSpot = Unit.GetChildTransformByName(ActingUnit.transform.parent, "Forward"); } float adjustedPeakOffset = ActingUnit.HeadPosition.position.y + (actionCommandHit ? JumpPeakOffset : JumpPeakOffset / 4) - landingSpot.position.y; ActingUnit.StartJumpTo(landingSpot, adjustedPeakOffset, () => { ActingUnit.StartMoveTo("Standard", () => { ActingUnit.EndTurn(); }, .5f); }); } else { //continue the jump chain (if possible) -- also need to remember that there are different types of jumps targetIndex = targetIndex + 1 % targetUnits.Length; JumpOnTarget(ActingUnit, targetUnits, targetIndex, actingRigidBody, jumpsPerformed, jumpLimit, multibounceQuotient); } }); }); }