From 248fb742b03aef4195c874b96c3e23c855e21e0a Mon Sep 17 00:00:00 2001 From: Jens Pitkanen Date: Sat, 18 Apr 2020 23:05:03 +0300 Subject: [PATCH] Add sliding down slopes --- Assets/Prefabs/Player/Player.prefab | 14 ++++++----- Assets/Scripts/PlayerController.cs | 36 +++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/Assets/Prefabs/Player/Player.prefab b/Assets/Prefabs/Player/Player.prefab index 957657a..2b1d632 100644 --- a/Assets/Prefabs/Player/Player.prefab +++ b/Assets/Prefabs/Player/Player.prefab @@ -56,7 +56,7 @@ Camera: y: 0 width: 1 height: 1 - near clip plane: 0.1 + near clip plane: 0.05 far clip plane: 200 field of view: 75 orthographic: 0 @@ -204,12 +204,14 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 6b513dcf57a19464b92ff712f770f105, type: 3} m_Name: m_EditorClassIdentifier: - MovementSpeed: 4 + MovementSpeed: 3 JumpVelocity: 4 + SlideVelocity: 3 JumpGracePeriod: 0.2 - Antislipperiness: 10 + Antislipperiness: 20 AntislipperinessInAir: 3 Grounded: 0 + GroundNormal: {x: 0, y: 0, z: 0} --- !u!143 &6125707630481988371 CharacterController: m_ObjectHideFlags: 0 @@ -222,9 +224,9 @@ CharacterController: m_Enabled: 1 serializedVersion: 2 m_Height: 1.8 - m_Radius: 0.25 - m_SlopeLimit: 45 - m_StepOffset: 0.3 + m_Radius: 0.1 + m_SlopeLimit: 30 + m_StepOffset: 0.05 m_SkinWidth: 0.08 m_MinMoveDistance: 0.001 m_Center: {x: 0, y: 0.9, z: 0} diff --git a/Assets/Scripts/PlayerController.cs b/Assets/Scripts/PlayerController.cs index 449242d..79b3203 100644 --- a/Assets/Scripts/PlayerController.cs +++ b/Assets/Scripts/PlayerController.cs @@ -6,6 +6,7 @@ using UnityEngine; public class PlayerController : MonoBehaviour { public float MovementSpeed; public float JumpVelocity; + public float SlideVelocity; [Tooltip("How long after falling off a ledge can the player still jump?")] public float JumpGracePeriod; [Tooltip("Lower values make the movement feel floatier.")] @@ -15,12 +16,14 @@ public class PlayerController : MonoBehaviour { [Header("Runtime values")] public bool Grounded; + public Vector3 GroundNormal; private CharacterController Character; private Vector3 GroundVelocity = new Vector3(); private float FallingVelocity; private float LastGroundedTime; + private float SlideStartTime; private void Awake() { Character = GetComponent(); @@ -32,8 +35,14 @@ public class PlayerController : MonoBehaviour { } private void Update() { + Vector3 CurrentVelocity = new Vector3(); + GroundNormal = RaycastGroundNormal(); + + // Sliding + bool Sliding = Grounded && Vector3.Angle(GroundNormal, Vector3.up) > Character.slopeLimit; + // Groundedness stuff and gravity - if (Character.isGrounded) { + if (Character.isGrounded && !Sliding) { FallingVelocity = Mathf.Max(0, FallingVelocity); LastGroundedTime = Time.time; } else { @@ -46,6 +55,7 @@ public class PlayerController : MonoBehaviour { FallingVelocity = JumpVelocity; Grounded = false; } + CurrentVelocity += FallingVelocity * Vector3.up; float SlippyFactor = Grounded ? Antislipperiness : AntislipperinessInAir; @@ -58,12 +68,34 @@ public class PlayerController : MonoBehaviour { 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) { + if (Grounded) { + TargetSpeed *= Vector3.Dot(Vector3.up, GroundNormal); + } float CurrentSpeed = Vector3.Dot(Move, GroundVelocity); float SpeedDiff = TargetSpeed - CurrentSpeed; float Acceleration = Mathf.Min(SpeedDiff, TargetSpeed * SlippyFactor * Time.deltaTime); 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; + } } }