2020-04-18 18:26:35 +02:00
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
[RequireComponent(typeof(CharacterController))]
|
|
|
|
|
public class PlayerController : MonoBehaviour {
|
|
|
|
|
public float MovementSpeed;
|
|
|
|
|
public float JumpVelocity;
|
2020-04-18 22:05:03 +02:00
|
|
|
|
public float SlideVelocity;
|
2020-04-18 18:26:35 +02:00
|
|
|
|
[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;
|
2020-04-18 22:05:03 +02:00
|
|
|
|
public Vector3 GroundNormal;
|
2020-04-18 18:26:35 +02:00
|
|
|
|
|
|
|
|
|
private CharacterController Character;
|
|
|
|
|
|
|
|
|
|
private Vector3 GroundVelocity = new Vector3();
|
|
|
|
|
private float FallingVelocity;
|
|
|
|
|
private float LastGroundedTime;
|
2020-04-18 22:05:03 +02:00
|
|
|
|
private float SlideStartTime;
|
2020-04-18 18:26:35 +02:00
|
|
|
|
|
|
|
|
|
private void Awake() {
|
|
|
|
|
Character = GetComponent<CharacterController>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Start() {
|
|
|
|
|
LastGroundedTime = -JumpGracePeriod;
|
|
|
|
|
Grounded = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Update() {
|
2020-04-18 22:05:03 +02:00
|
|
|
|
Vector3 CurrentVelocity = new Vector3();
|
|
|
|
|
GroundNormal = RaycastGroundNormal();
|
|
|
|
|
|
|
|
|
|
// Sliding
|
|
|
|
|
bool Sliding = Grounded && Vector3.Angle(GroundNormal, Vector3.up) > Character.slopeLimit;
|
|
|
|
|
|
2020-04-18 18:26:35 +02:00
|
|
|
|
// Groundedness stuff and gravity
|
2020-04-18 22:05:03 +02:00
|
|
|
|
if (Character.isGrounded && !Sliding) {
|
2020-04-18 18:26:35 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
2020-04-18 22:05:03 +02:00
|
|
|
|
CurrentVelocity += FallingVelocity * Vector3.up;
|
2020-04-18 18:26:35 +02:00
|
|
|
|
|
|
|
|
|
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");
|
2020-04-19 00:35:03 +02:00
|
|
|
|
// If Move magnitude is < 0, it's probably an analog stick, so scale target speed accordingly.
|
|
|
|
|
TargetSpeed *= Mathf.Min(1, Move.magnitude);
|
|
|
|
|
|
2020-04-18 18:26:35 +02:00
|
|
|
|
if (Move.magnitude > 0) {
|
2020-04-19 00:35:03 +02:00
|
|
|
|
Move.Normalize();
|
2020-04-18 22:05:03 +02:00
|
|
|
|
if (Grounded) {
|
2020-04-19 00:35:03 +02:00
|
|
|
|
// Slow down when moving on slopes
|
2020-04-18 22:05:03 +02:00
|
|
|
|
TargetSpeed *= Vector3.Dot(Vector3.up, GroundNormal);
|
|
|
|
|
}
|
2020-04-18 18:26:35 +02:00
|
|
|
|
float CurrentSpeed = Vector3.Dot(Move, GroundVelocity);
|
|
|
|
|
float SpeedDiff = TargetSpeed - CurrentSpeed;
|
|
|
|
|
float Acceleration = Mathf.Min(SpeedDiff, TargetSpeed * SlippyFactor * Time.deltaTime);
|
|
|
|
|
GroundVelocity += Move * Acceleration;
|
|
|
|
|
}
|
2020-04-18 22:05:03 +02:00
|
|
|
|
CurrentVelocity += GroundVelocity;
|
|
|
|
|
|
|
|
|
|
// Sliiide
|
|
|
|
|
if (Sliding) {
|
|
|
|
|
CurrentVelocity = Vector3.ProjectOnPlane(CurrentVelocity, GroundNormal);
|
|
|
|
|
CurrentVelocity += Vector3.ProjectOnPlane(-Vector3.up, GroundNormal) * SlideVelocity;
|
|
|
|
|
}
|
2020-04-18 18:26:35 +02:00
|
|
|
|
|
2020-04-18 22:05:03 +02:00
|
|
|
|
Character.Move(CurrentVelocity * Time.deltaTime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Vector3 RaycastGroundNormal() {
|
|
|
|
|
RaycastHit Hit;
|
|
|
|
|
if (Physics.CapsuleCast(
|
|
|
|
|
transform.position + Vector3.up * Character.radius,
|
|
|
|
|
transform.position + Vector3.up * (Character.height - Character.radius),
|
|
|
|
|
Character.radius, -Vector3.up, out Hit, Character.skinWidth * 2)) {
|
|
|
|
|
return Hit.normal;
|
|
|
|
|
} else {
|
|
|
|
|
return Vector3.up;
|
|
|
|
|
}
|
2020-04-18 18:26:35 +02:00
|
|
|
|
}
|
|
|
|
|
}
|