Beispiel #1
0
    public (bool jumpConsumed, int cyoteTime) SimulateFrame(InputSnapshot input, int cyoteTime)
    {
        bool jumpConsumed = false;

        // useful variables
        var peakJump     = (VMomentum <1f && VMomentum> -1f) && !Grounded;
        var x            = input.direction.x;
        var currentSpeed = Mathf.Abs(HMomentum);

        // facing
        if (x < .25f && x > -.25f)
        {
            x = 0f;
        }
        if (x > .75f)
        {
            x = 1f;
        }
        if (x < -.75f)
        {
            x = -1f;
        }
        if (x != 0f && (Grounded || Properties.airTurn))
        {
            FaceRight = x > 0f;
        }

        // horiontal movement
        var  desiredSpeed = x * Properties.MaxSpeed;
        bool breaking     = (Mathf.Abs(desiredSpeed) < Mathf.Abs(HMomentum) || Mathf.Sign(desiredSpeed) != Mathf.Sign(HMomentum));
        var  accel        = Properties.AccelerationCurve.Evaluate(breaking ? -currentSpeed : currentSpeed);

        if (peakJump)
        {
            accel *= Properties.PeakAirControl;
        }
        else if (!Grounded)
        {
            accel *= Properties.AirControl;
        }
        HMomentum = Mathf.Clamp(desiredSpeed, HMomentum - accel, HMomentum + accel);
        if (Grounded && breaking)
        {
            HMomentum *= Properties.Traction;
        }

        // jump resolver
        if (Grounded)
        {
            cyoteTime = Properties.CyoteTime + 1;
        }
        else
        {
            cyoteTime--;
        }

        if (Properties.WalljumpForce > 0f && !Grounded && TouchingWall && TouchingWallDirection == System.Math.Sign(input.direction.x))
        {
            if (WallSliding)
            {
                FaceRight = TouchingWallDirection < 0;
            }
            wallSlideTime = Properties.CyoteTime + 1;
        }
        else
        {
            wallSlideTime--;
        }

        if (cyoteTime > 0 && input.jumpBufferTimer >= 0f)
        {
            VMomentum = Properties.JumpForce;
            OnJump?.Invoke();
            cyoteTime    = 0;
            jumpConsumed = true;
        }
        else if (Properties.WalljumpForce > 0f && !Grounded && input.jumpBufferTimer >= 0f && wallSlideTime > 0)
        {
            if (TouchingWall)
            {
                FaceRight = TouchingWallDirection < 0;
            }
            VMomentum = Properties.WalljumpForce;
            HMomentum = Properties.WalljumpForce * -Forward;

            OnJump?.Invoke();
            wallSlideTime = 0;
            jumpConsumed  = true;
        }
        else if (!Grounded && VMomentum < 0f && Properties.HeadBonkForce > 0f)
        {
            // jump on player here
            var hits = Physics2D.BoxCastAll(
                origin: new Vector2(transform.position.x, transform.position.y - radius + .08f),
                size: new Vector2(radius * .9f, .02f),
                angle: 0f,
                direction: Vector2.down,
                distance: -VMomentum * Time.fixedDeltaTime,
                layerMask: Player
                );
            if (hits.Length > 1)
            {
                foreach (var hit in hits)
                {
                    if (hit.transform != transform && hit.transform.position.y < transform.position.y)
                    {
                        VMomentum = Properties.HeadBonkForce;
                        var other = hit.transform.GetComponent <PlatformingCharacter>();
                        other.VMomentum = Mathf.Min(VMomentum - Properties.HeadBonkForce, -Properties.HeadBonkForce);
                        OnStomp?.Invoke(other);
                        break;
                    }
                }
            }
        }

        if (Grounded == false && input.jumpHeld == false && VMomentum > 0f)
        {
            VMomentum *= Properties.JumpCap;
        }

        // Gravity Manipulation
        if (peakJump && input.jumpHeld)
        {
            Gravity = Properties.Gravity * Properties.PeakJumpGravity;
        }
        else if (!Grounded && Properties.slowfallTrottle > 0f && input.jumpHeld && VMomentum < -Properties.slowfallSpeed)
        {
            VMomentum += (1f - Properties.slowfallTrottle) * (-VMomentum - Properties.slowfallSpeed);
        }
        else if (TouchingWall && WallSliding)
        {
            VMomentum += .2f * (-VMomentum - Properties.MaxWallslideSpeed);
            Gravity    = 0f;
        }
        else if (VMomentum < -Properties.MaxFallSpeed)
        {
            Gravity = 0f;
        }
        else
        {
            Gravity = Properties.Gravity;
        }



        base.FixedUpdate();

        return(jumpConsumed, cyoteTime);
    }
Beispiel #2
0
    public (bool jumpConsumed, int cyoteTime) SimulateFrame(InputSnapshot input, int cyoteTime)
    {
        bool jumpConsumed = false;

        ForceJumpFrames--;
        ForceMoveFrames--;
        rootDuration--;

        // useful variables
        var  peakJump     = (VMomentum <1f && VMomentum> -1f) && !Grounded;
        var  x            = input.direction.x;
        var  currentSpeed = Mathf.Abs(HMomentum);
        bool jumpHeld     = ForceJumpFrames > 0 || input.jumpHeld || ForceJumpUntillPeak;

        if (ForceMoveFrames > 0)
        {
            x = ForceMove.x;
        }

        // facing
        if (x < .25f && x > -.25f)
        {
            x = 0f;
        }
        if (x > .75f)
        {
            x = 1f;
        }
        if (x < -.75f)
        {
            x = -1f;
        }

        // horiontal movement
        var desiredSpeed = x * Properties.MaxSpeed;

        if (!Grounded && Mathf.Abs(HMomentum) > Properties.MaxSpeed && Mathf.Abs(x) > .75f && x == Mathf.Sign(HMomentum)) // do magic to perserve massive vertical momentum or something
        {
            desiredSpeed = HMomentum * .98f;
        }

        var accelMultipler = 1f; //desiredSpeed == 0f && !Grounded ? .1f : 1f; // keep momentum in air if stick is neutral.

        accelMultipler *= Friction;
        if (lowStamina)
        {
            accelMultipler *= .12f;
            desiredSpeed   *= .4f;
        }
        if (Grounded)
        {
            lastWallJump = 0f;
        }
        if (TimeSinceLastWalljump < 1f)
        {
            accelMultipler *= TimeSinceLastWalljump;
        }
        if (Grounded && Rooted)
        {
            desiredSpeed = 0f;
        }
        bool breaking = (Mathf.Abs(desiredSpeed) < Mathf.Abs(HMomentum) || Mathf.Sign(desiredSpeed) != Mathf.Sign(HMomentum));
        var  accel    = Properties.AccelerationCurve.Evaluate(breaking ? -currentSpeed : currentSpeed) * accelMultipler;

        if (peakJump)
        {
            accel *= Properties.PeakAirControl;
        }
        else if (!Grounded)
        {
            accel *= Properties.AirControl;
        }
        float suggestion = Mathf.Clamp(desiredSpeed, HMomentum - accel, HMomentum + accel);

        if (HMomentum != 0f && System.Math.Sign(suggestion) != System.Math.Sign(HMomentum)) // snap to 0 before conitnuing in the other direction.
        {
            HMomentum = 0f;
        }
        else
        {
            HMomentum = suggestion;
            if (x != 0f && (Grounded || Properties.airTurn) && !Rooted && (Mathf.Abs(HMomentum) > .7f || Mathf.Abs(x) > .75f))
            {
                FaceRight = x > 0f;
            }
        }
        if (Grounded && breaking)
        {
            HMomentum *= Properties.Traction;
        }

        // jump resolver
        if (Grounded)
        {
            cyoteTime = Properties.CyoteTime + 1;
        }
        else
        {
            cyoteTime--;
        }

        if (TouchingWall)
        {
            lastTouchingWallDirection = TouchingWallDirection;
        }

        // climbing
        if (!lowStamina && InputToken.ClimbHeld && Properties.ClimbSpeed > 0f && !Grounded && TouchingWall && !Rooted)
        {
            if (input.direction.y < 0f && Properties.ClimbSpeed < Properties.MaxWallslideSpeed)
            {
                VMomentum = VMomentum * .5f + Properties.MaxWallslideSpeed * .5f * input.direction.y;
            }
            else
            {
                VMomentum = VMomentum * .5f + Properties.ClimbSpeed * .5f * input.direction.y;
            }
            HMomentum     = TouchingWallDirection * 3f;
            FaceRight     = TouchingWallDirection < 0;
            wallSlideTime = 6;
            Climbing      = true;
            ForceMove     = new Vector2(TouchingWallDirection, 0f);
        }
        // wallsliding
        else if (Properties.WalljumpForce > 0f && !Grounded && TouchingWall && TouchingWallDirection == System.Math.Sign(input.direction.x) && !Rooted)
        {
            if (WallSliding)
            {
                FaceRight = TouchingWallDirection < 0;
            }
            wallSlideTime = 8;
            Climbing      = false;
        }
        else
        {
            if (Climbing == true)
            {
                if (input.direction.y > .5f && InputToken.ClimbHeld)
                {
                    VMomentum       = 10f;
                    ForceJumpFrames = 15;
                    ForceMoveFrames = 10;
                    FaceRight       = ForceMove.x > 0f;
                }
            }
            wallSlideTime--;
            Climbing = false;
        }

        if (cyoteTime > 0 && input.jumpBufferTimer >= 0f && !Rooted)
        {
            VMomentum = lowStamina ? Properties.JumpForce * .5f : Properties.JumpForce;
            OnJump?.Invoke();
            cyoteTime    = 0;
            jumpConsumed = true;
        }
        else if (input.jumpBufferTimer >= 0f && CanWallJump) // Walljump
        {
            if (TouchingWall)
            {
                FaceRight = TouchingWallDirection < 0;
            }
            else
            {
                FaceRight = lastTouchingWallDirection < 0;
            }
            VMomentum = Properties.WalljumpForce;
            HMomentum = Properties.WallpushForce * Forward;

            OnWallJump?.Invoke();
            wallSlideTime   = 0;
            jumpConsumed    = true;
            ForceMove       = new Vector2(-TouchingWallDirection, 0f);
            ForceMoveFrames = 5;
            lastWallJump    = Time.timeSinceLevelLoad;
        }
        else if (!Grounded && VMomentum < 0f && Properties.HeadBonkForce > 0f) // STOMPing
        {
            // jump on player here
            var hits = Physics2D.BoxCastAll(
                origin: new Vector2(transform.position.x, transform.position.y - radius + .08f),
                size: new Vector2(radius * .9f, .02f),
                angle: 0f,
                direction: Vector2.down,
                distance: -VMomentum * Time.fixedDeltaTime,
                layerMask: Player
                );
            if (hits.Length > 1)
            {
                foreach (var hit in hits)
                {
                    if (hit.transform != transform && hit.transform.position.y < transform.position.y)
                    {
                        VMomentum = Properties.HeadBonkForce;
                        var other = hit.transform.GetComponent <PlatformingCharacter>();
                        if (other)
                        {
                            other.VMomentum = Mathf.Min(VMomentum - Properties.HeadBonkForce, -Properties.HeadBonkForce);
                        }
                        foreach (var stompable in hit.collider.GetComponents <IStompable>())
                        {
                            stompable.Stomp(this);
                        }
                        OnStomp?.Invoke(other);
                        ForceJumpFrames = 4;
                        jumpHeld        = true;
                        StartCoroutine(Freeze(.05f));
                        other?.OnStomped?.Invoke(this);
                        break;
                    }
                }
            }
        }

        if (Grounded == false && jumpHeld == false && VMomentum > 0f)
        {
            VMomentum *= Properties.JumpCap;
        }

        // pass through platforms
        AllowSemiSolids = !InputToken.PassThrough;

        // Gravity Manipulation
        if (Climbing)
        {
            Gravity = 0f;
        }
        else if (peakJump && jumpHeld)
        {
            Gravity = Properties.Gravity * Properties.PeakJumpGravity;
        }
        else if (!Grounded && Properties.slowfallTrottle > 0f && jumpHeld && VMomentum < -Properties.slowfallSpeed)
        {
            VMomentum += (1f - Properties.slowfallTrottle) * (-VMomentum - Properties.slowfallSpeed);
        }
        else if (TouchingWall && WallSliding)
        {
            VMomentum += .2f * (-VMomentum - Properties.MaxWallslideSpeed);
            Gravity    = 0f;
        }
        else if (VMomentum < -Properties.MaxFallSpeed)
        {
            Gravity = 0f;
        }
        else
        {
            Gravity = Properties.Gravity;
        }

        if (VMomentum < 0f || Grounded)
        {
            ForceJumpUntillPeak = false;
        }

        base.FixedUpdate();

        return(jumpConsumed, cyoteTime);
    }