using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(CharacterController))] public class PlayerController : MonoBehaviour { public float MovementSpeed; public float JumpVelocity; [Tooltip("How long after falling off a ledge can the player still jump?")] public float JumpGracePeriod; [Tooltip("Lower values make the movement feel floatier.")] public float Antislipperiness = 1; [Tooltip("Lower values make the movement feel floatier in air.")] public float AntislipperinessInAir = 1; [Header("Runtime values")] public bool Grounded; private CharacterController Character; private Vector3 GroundVelocity = new Vector3(); private float FallingVelocity; private float LastGroundedTime; private void Awake() { Character = GetComponent(); } private void Start() { LastGroundedTime = -JumpGracePeriod; Grounded = false; } private void Update() { // Groundedness stuff and gravity if (Character.isGrounded) { FallingVelocity = Mathf.Max(0, FallingVelocity); LastGroundedTime = Time.time; } else { FallingVelocity += Physics.gravity.y * Time.deltaTime; } Grounded = Time.time - LastGroundedTime <= JumpGracePeriod && FallingVelocity <= 0; // Jumping if (Input.GetButton("Jump") && Grounded) { FallingVelocity = JumpVelocity; Grounded = false; } float SlippyFactor = Grounded ? Antislipperiness : AntislipperinessInAir; // Subtract friction float FrictionFactor = Mathf.Max(GroundVelocity.magnitude, 1); float Friction = Mathf.Min(GroundVelocity.magnitude, FrictionFactor * SlippyFactor * Time.deltaTime); GroundVelocity -= Friction * GroundVelocity.normalized; // Add player input momentum float TargetSpeed = MovementSpeed; // Tweak this to enable running or stuff Vector3 Move = transform.forward * Input.GetAxis("Vertical") + transform.right * Input.GetAxis("Horizontal"); if (Move.magnitude > 0) { float CurrentSpeed = Vector3.Dot(Move, GroundVelocity); float SpeedDiff = TargetSpeed - CurrentSpeed; float Acceleration = Mathf.Min(SpeedDiff, TargetSpeed * SlippyFactor * Time.deltaTime); GroundVelocity += Move * Acceleration; } Character.Move((GroundVelocity + FallingVelocity * Vector3.up) * Time.deltaTime); } }