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); }
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; }