From 676700ecfa71870eb99c76ad04c62fe937350807 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Tue, 2 Feb 2021 17:30:13 +0800 Subject: [PATCH] Jumping --- Assets/Scenes/SampleScene.unity | 2 + Assets/Scripts/MovingSphere.cs | 77 ++++++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 867852a..c219f9b 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -1001,6 +1001,8 @@ MonoBehaviour: m_EditorClassIdentifier: maxSpeed: 10 maxAcceleration: 10 + jumpHeight: 2 + maxAirJumps: 1 --- !u!54 &1695436951 Rigidbody: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/MovingSphere.cs b/Assets/Scripts/MovingSphere.cs index 879ea9f..9a1612f 100644 --- a/Assets/Scripts/MovingSphere.cs +++ b/Assets/Scripts/MovingSphere.cs @@ -6,11 +6,22 @@ public class MovingSphere : MonoBehaviour private float maxSpeed = 10f; [SerializeField, Range(0f, 100f)] - private float maxAcceleration = 10f; - + private float maxAcceleration = 10f, maxAirAcceleration = 1f; + + [SerializeField, Range(0f, 10f)] + float jumpHeight = 2f; + + [SerializeField, Range(0, 5)] + int maxAirJumps = 0; + private Rigidbody body; - private Vector3 desiredVelocity; + private Vector3 desiredVelocity = new Vector3(0f, 0f, 0f); + private bool desiredJump = false; + + private bool onGround; + private int jumpPhase; + private Vector3 velocity; private void Awake() { @@ -24,14 +35,70 @@ public class MovingSphere : MonoBehaviour playerInput.y = Input.GetAxis("Vertical"); playerInput = Vector2.ClampMagnitude(playerInput, 1f); desiredVelocity = new Vector3(playerInput.x, 0f, playerInput.y) * maxSpeed; + + desiredJump |= Input.GetButtonDown("Jump"); } private void FixedUpdate() { - var velocity = body.velocity; - float maxSpeedChange = maxAcceleration * Time.deltaTime; + UpdateState(); + + float acceleration = onGround ? maxAcceleration : maxAirAcceleration; + float maxSpeedChange = acceleration * Time.deltaTime; velocity.x = Mathf.MoveTowards(velocity.x, desiredVelocity.x, maxSpeedChange); velocity.z = Mathf.MoveTowards(velocity.z, desiredVelocity.z, maxSpeedChange); + + if (desiredJump) + { + desiredJump = false; + Jump(); + } + body.velocity = velocity; + + onGround = false; } + + private void UpdateState() + { + velocity = body.velocity; + if (onGround) + { + jumpPhase = 0; + } + } + + private void OnCollisionEnter(Collision collision) + { + EvaluateCollision(collision); + } + + private void OnCollisionStay(Collision collision) + { + EvaluateCollision(collision); + } + + private void EvaluateCollision(Collision collision) + { + for (int i = 0; i < collision.contactCount; i++) + { + var normal = collision.GetContact(i).normal; + onGround |= normal.y >= 0.9f; + } + } + + private void Jump() + { + if (onGround || jumpPhase < maxAirJumps) + { + jumpPhase++; + float jumpSpeed = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight); + if (velocity.y > 0f) + { + jumpSpeed = Mathf.Max(jumpSpeed - velocity.y, 0f); + } + velocity.y += jumpSpeed; + } + } + }