Add sliding down slopes

This commit is contained in:
Jens Pitkänen 2020-04-18 23:05:03 +03:00
parent 7518e6cc58
commit 248fb742b0
2 changed files with 42 additions and 8 deletions

View File

@ -56,7 +56,7 @@ Camera:
y: 0 y: 0
width: 1 width: 1
height: 1 height: 1
near clip plane: 0.1 near clip plane: 0.05
far clip plane: 200 far clip plane: 200
field of view: 75 field of view: 75
orthographic: 0 orthographic: 0
@ -204,12 +204,14 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 6b513dcf57a19464b92ff712f770f105, type: 3} m_Script: {fileID: 11500000, guid: 6b513dcf57a19464b92ff712f770f105, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
MovementSpeed: 4 MovementSpeed: 3
JumpVelocity: 4 JumpVelocity: 4
SlideVelocity: 3
JumpGracePeriod: 0.2 JumpGracePeriod: 0.2
Antislipperiness: 10 Antislipperiness: 20
AntislipperinessInAir: 3 AntislipperinessInAir: 3
Grounded: 0 Grounded: 0
GroundNormal: {x: 0, y: 0, z: 0}
--- !u!143 &6125707630481988371 --- !u!143 &6125707630481988371
CharacterController: CharacterController:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -222,9 +224,9 @@ CharacterController:
m_Enabled: 1 m_Enabled: 1
serializedVersion: 2 serializedVersion: 2
m_Height: 1.8 m_Height: 1.8
m_Radius: 0.25 m_Radius: 0.1
m_SlopeLimit: 45 m_SlopeLimit: 30
m_StepOffset: 0.3 m_StepOffset: 0.05
m_SkinWidth: 0.08 m_SkinWidth: 0.08
m_MinMoveDistance: 0.001 m_MinMoveDistance: 0.001
m_Center: {x: 0, y: 0.9, z: 0} m_Center: {x: 0, y: 0.9, z: 0}

View File

@ -6,6 +6,7 @@ using UnityEngine;
public class PlayerController : MonoBehaviour { public class PlayerController : MonoBehaviour {
public float MovementSpeed; public float MovementSpeed;
public float JumpVelocity; public float JumpVelocity;
public float SlideVelocity;
[Tooltip("How long after falling off a ledge can the player still jump?")] [Tooltip("How long after falling off a ledge can the player still jump?")]
public float JumpGracePeriod; public float JumpGracePeriod;
[Tooltip("Lower values make the movement feel floatier.")] [Tooltip("Lower values make the movement feel floatier.")]
@ -15,12 +16,14 @@ public class PlayerController : MonoBehaviour {
[Header("Runtime values")] [Header("Runtime values")]
public bool Grounded; public bool Grounded;
public Vector3 GroundNormal;
private CharacterController Character; private CharacterController Character;
private Vector3 GroundVelocity = new Vector3(); private Vector3 GroundVelocity = new Vector3();
private float FallingVelocity; private float FallingVelocity;
private float LastGroundedTime; private float LastGroundedTime;
private float SlideStartTime;
private void Awake() { private void Awake() {
Character = GetComponent<CharacterController>(); Character = GetComponent<CharacterController>();
@ -32,8 +35,14 @@ public class PlayerController : MonoBehaviour {
} }
private void Update() { private void Update() {
Vector3 CurrentVelocity = new Vector3();
GroundNormal = RaycastGroundNormal();
// Sliding
bool Sliding = Grounded && Vector3.Angle(GroundNormal, Vector3.up) > Character.slopeLimit;
// Groundedness stuff and gravity // Groundedness stuff and gravity
if (Character.isGrounded) { if (Character.isGrounded && !Sliding) {
FallingVelocity = Mathf.Max(0, FallingVelocity); FallingVelocity = Mathf.Max(0, FallingVelocity);
LastGroundedTime = Time.time; LastGroundedTime = Time.time;
} else { } else {
@ -46,6 +55,7 @@ public class PlayerController : MonoBehaviour {
FallingVelocity = JumpVelocity; FallingVelocity = JumpVelocity;
Grounded = false; Grounded = false;
} }
CurrentVelocity += FallingVelocity * Vector3.up;
float SlippyFactor = Grounded ? Antislipperiness : AntislipperinessInAir; float SlippyFactor = Grounded ? Antislipperiness : AntislipperinessInAir;
@ -58,12 +68,34 @@ public class PlayerController : MonoBehaviour {
float TargetSpeed = MovementSpeed; // Tweak this to enable running or stuff float TargetSpeed = MovementSpeed; // Tweak this to enable running or stuff
Vector3 Move = transform.forward * Input.GetAxis("Vertical") + transform.right * Input.GetAxis("Horizontal"); Vector3 Move = transform.forward * Input.GetAxis("Vertical") + transform.right * Input.GetAxis("Horizontal");
if (Move.magnitude > 0) { if (Move.magnitude > 0) {
if (Grounded) {
TargetSpeed *= Vector3.Dot(Vector3.up, GroundNormal);
}
float CurrentSpeed = Vector3.Dot(Move, GroundVelocity); float CurrentSpeed = Vector3.Dot(Move, GroundVelocity);
float SpeedDiff = TargetSpeed - CurrentSpeed; float SpeedDiff = TargetSpeed - CurrentSpeed;
float Acceleration = Mathf.Min(SpeedDiff, TargetSpeed * SlippyFactor * Time.deltaTime); float Acceleration = Mathf.Min(SpeedDiff, TargetSpeed * SlippyFactor * Time.deltaTime);
GroundVelocity += Move * Acceleration; GroundVelocity += Move * Acceleration;
} }
CurrentVelocity += GroundVelocity;
Character.Move((GroundVelocity + FallingVelocity * Vector3.up) * Time.deltaTime); // Sliiide
if (Sliding) {
CurrentVelocity = Vector3.ProjectOnPlane(CurrentVelocity, GroundNormal);
CurrentVelocity += Vector3.ProjectOnPlane(-Vector3.up, GroundNormal) * SlideVelocity;
}
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;
}
} }
} }