public IState Execute(PlayerController p) { p.Move(); p.ApplyGravity(); if (p.Falling) { p.SetPhysicsProfile(p.PhysJumpGetup); return(new FallState()); } // Only re-slide if moving down, otherwise we // risk regrounding immediately after jumping. if (p.Surface.Unstable && p.Velocity.y < 0) { return(new FallSlideState()); } return(null); }
public IState Execute(PlayerController p) { p.DetermineFacing(); if (accelerationCurve != null) { var accel = p.Physics.Acceleration * accelerationCurve.Evaluate(Time.time - startTime); p.Move(p.Physics.Speed, accel); } else { p.Move(); } // While inside the jump extend window, we don't apply gravity. var extendTime = p.JumpExtendTime; var outsideExtendWindow = Utility.Elapsed(startTime, extendTime); if (outsideExtendWindow) { p.ApplyGravity(); } foreach (var input in p.Input) { if (input.Action == InputActions.AttackDown) { return(new AttackState()); } // If we release the button mid-jump, cap our upward momentum and start to fall. if (cappable && input.Action == InputActions.JumpUp && !outsideExtendWindow) { p.CapJumpIfRising(); return(CreateFallState()); } // Walljumping. if (input.Action == InputActions.JumpDown) { if (p.SweepForWall(Vector2.right)) { return(PlayerController.WallJump(p, Vector2.left)); } if (p.SweepForWall(Vector2.left)) { return(PlayerController.WallJump(p, Vector2.right)); } } p.Input.Release(input); } if (p.Falling) { return(CreateFallState()); } if (p.Surface.Unstable) { return(new FallSlideState()); } return(null); }
public IState Execute(PlayerController p) { p.Move(); p.ApplyGravity(); p.DetermineFacing(); p.SpriteManager.AlignWith(p.Surface.SurfaceNormal); if (p.Surface.Airborne) { return(new FallState()); } if (p.Surface.Unstable) { // TODO: Make this an event or observable perhaps? // So it isnt running every frame. var animation = p.SpriteManager.GetAnimationState(); if (animation.IsName("Run")) { p.SpriteManager.SetAnimation("RunDifficult"); p.SpriteManager.Speed = 1f; } var v = p.GetSurfaceProjectedVelocity(); var i = p.Input.MovementHorizontal; // We slip and fall if... // We are on a slope above the slope angle threshold. // We aren't inputting any movement. // We are moving backward (relative to our input). var aboveSlopeThreshold = p.Surface.SurfaceAngle > p.Surface.SlopeAngleThreshold; var noInput = i.magnitude <= 0.01f; var movingBackwards = Vector2.Dot(v.normalized, i.normalized) < 0f; if (aboveSlopeThreshold) { if (noInput || movingBackwards) { return(new FallSlideState()); } } } else { var v = p.GetSurfaceProjectedVelocity(); var i = p.GetSurfaceAlignedXInput(); var movingIntentionally = i.sqrMagnitude > 0.01f && v.sqrMagnitude > 0.01f; var animation = p.SpriteManager.GetAnimationState(); /// Select an animation based on what we are doing: // TODO: Make this an event or observable perhaps? // So it isnt running every frame. if (animation.IsName("RunDifficult")) { p.SpriteManager.SetAnimation("Run"); } p.SpriteManager.Animator.SetBool("MovingIntentionally", movingIntentionally); p.SpriteManager.Animator.SetBool("Pushing", p.TowardWall(i)); // Scale animation with relative speed. if (animation.IsName("Run")) { var aligned = Vector2.Dot(v.normalized, i) > 0; var speed = aligned ? v.magnitude : 0f; p.SpriteManager.Speed = Mathf.Clamp01(speed); } else { p.SpriteManager.Speed = 1f; } } foreach (var input in p.Input) { if (input.Action == InputActions.JumpDown) { return(new JumpState()); } if (input.Action == InputActions.AttackDown) { return(new AttackState()); } p.Input.Release(input); } return(null); }
public IState Execute(PlayerController p) { p.ApplyGravity(); p.DetermineFacing(); if (accelerationCurve != null) { var accel = p.Physics.Acceleration * accelerationCurve.Evaluate(Time.time - atTime); p.Move(p.Physics.Speed, accel); } else { p.Move(); } // Wall Jumping / Attacking foreach (var input in p.Input) { if (input.Action == InputActions.AttackDown) { return(new AttackState()); } if (input.Action == InputActions.JumpDown) { if (p.SweepForWall(Vector2.right)) { return(PlayerController.WallJump(p, Vector2.left)); } if (p.SweepForWall(Vector2.left)) { return(PlayerController.WallJump(p, Vector2.right)); } // Coyote Time if (p.StateMachine.PreviousState is RunState && !Utility.Elapsed(startTime, p.CoyoteTime)) { return(new JumpState()); } } p.Input.Release(input); } if (p.Surface.Grounded) { var moving = p.GetSurfaceProjectedVelocity().sqrMagnitude > 0.01f; p.SpriteManager.SetAnimation(moving ? "LandMoving" : "LandStationary"); return(new RunState()); } if (p.Surface.ContactingWall) { // Wallslide. var i = p.GetSurfaceAlignedXInput(); if (!p.AwayFromWall(i) && p.SweepForWall(-p.Surface.WallNormal)) { return(new WallSlideState()); } } if (p.Surface.Unstable) { return(new FallSlideState()); } return(null); }