Esempio n. 1
0
    private bool TryReachLedge(PlayerController player, float zVel, ref float yVel, bool allowClearingBoost = true)
    {
        // Doing standing jump, allow player to grab if close
        if (zVel < 0.5f)
        {
            zVel = 0.5f;
        }

        // Need to check where player will be relative to ledge
        float   timeAtPeak   = yVel / player.Gravity; // v = u + at
        Vector3 relative     = ledgeInfo.Point - player.transform.position;
        float   displacement = UMath.GetHorizontalMag(relative);
        // Maximum to account for when player hits wall but keeps moving up
        float timeAtLedge = Mathf.Max(UMath.TimeAtHorizontalPoint(zVel, displacement), timeAtPeak);
        float vertPos     = UMath.PredictDisplacement(yVel, timeAtLedge, -player.Gravity);

        if (vertPos >= relative.y - 2.6f && vertPos <= relative.y - 0.8f) // Distance is great, do auto-grab
        {
            player.StateMachine.GoToState <AutoGrabbing>(ledgeInfo);
            return(true);
        }
        else if (allowClearingBoost && vertPos < relative.y && vertPos > relative.y - 0.8f) // she hits it around the hip just adjust up velocity to clear it
        {
            float   time;
            Vector3 adjustedVel = UMath.VelocityToReachPoint(player.transform.position,
                                                             ledgeInfo.Point, zVel, player.Gravity, out time);
            yVel = adjustedVel.y;
        }

        return(false);
    }
Esempio n. 2
0
    public override void OnEnter(PlayerController player)
    {
        if (ledgeInfo == null)
        {
            Debug.LogError("Autograbbing has no ledge info... you need to pass ledge info as context... going to in air");
            player.StateMachine.GoToState <InAir>();
            return;
        }

        player.UseGravity      = true;
        player.UseRootMotion   = false;
        player.GroundedOnSteps = false;

        player.MinimizeCollider();

        player.Anim.SetBool("isAutoGrabbing", true);

        player.ForceHeadLook = true;
        player.HeadLookAt    = ledgeInfo.Point;

        grabPoint   = ledgeInfo.Point - player.transform.forward * player.HangForwardOffset;
        grabPoint.y = ledgeInfo.Point.y - player.HangUpOffset;

        Vector3 calcGrabPoint;

        if (ledgeInfo.Type == LedgeType.Monkey || ledgeInfo.Type == LedgeType.HorPole)
        {
            calcGrabPoint = grabPoint - Vector3.up * 0.14f;
            targetRot     = player.transform.rotation;
        }
        else
        {
            calcGrabPoint = ledgeInfo.Point + player.GrabUpOffset * Vector3.down - ledgeInfo.Direction * player.GrabForwardOffset;
            Vector3 ledgeDir = ledgeInfo.Direction;
            ledgeDir.y = 0f;
            targetRot  = Quaternion.LookRotation(ledgeDir);
        }

        Vector3 velocityAdjusted = UMath.VelocityToReachPoint(player.transform.position,
                                                              calcGrabPoint,
                                                              player.RunJumpVel,
                                                              player.Gravity,
                                                              out grabTime);

        // So Lara doesn't do huge upwards jumps or snap when close
        if (grabTime < 0.3f || grabTime > 1.2f)
        {
            grabTime = Mathf.Clamp(grabTime, 0.4f, 1.2f);

            velocityAdjusted = UMath.VelocityToReachPoint(player.transform.position,
                                                          calcGrabPoint,
                                                          player.Gravity,
                                                          grabTime);
        }

        // Apply the correct velocity calculated
        player.ImpulseVelocity(velocityAdjusted);

        Debug.Log("Setting vel: " + velocityAdjusted);

        if (ledgeInfo.Collider != null)
        {
            initialColliderPos = ledgeInfo.Collider.transform.position;

            MovingPlatform moving = ledgeInfo.Collider.GetComponent <MovingPlatform>();

            if (moving != null)
            {
                // So Player aligns with ledge
                moving.AttachTransform(player.transform);
            }
        }

        timeTracker = Time.time;
    }