From fb8732f8200429e2cc4e7bccc376fe9c870d4e62 Mon Sep 17 00:00:00 2001 From: Nicholas Novak <34256932+NickyBoy89@users.noreply.github.com> Date: Mon, 17 Apr 2023 00:01:49 -0700 Subject: [PATCH] Progress on movement controller --- .../Physics/PlayerFriction.physicsMaterial2D | 2 +- Assets/Scenes/GrappleScene.unity | 34 +++++- Assets/Scripts/PlayerBehavior.cs | 110 +++++++++++------- Assets/Scripts/PlayerController.cs | 71 ++++++++--- Assets/Scripts/PlayerData.cs | 98 ++++++++++++++++ Assets/Scripts/PlayerData.cs.meta | 11 ++ Assets/ofb-assets | 2 +- 7 files changed, 269 insertions(+), 59 deletions(-) create mode 100644 Assets/Scripts/PlayerData.cs create mode 100644 Assets/Scripts/PlayerData.cs.meta diff --git a/Assets/Physics/PlayerFriction.physicsMaterial2D b/Assets/Physics/PlayerFriction.physicsMaterial2D index 6de366b..85095d8 100644 --- a/Assets/Physics/PlayerFriction.physicsMaterial2D +++ b/Assets/Physics/PlayerFriction.physicsMaterial2D @@ -7,5 +7,5 @@ PhysicsMaterial2D: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: PlayerFriction - friction: 1 + friction: 0 bounciness: 0 diff --git a/Assets/Scenes/GrappleScene.unity b/Assets/Scenes/GrappleScene.unity index 9b1e8dc..7d51799 100644 --- a/Assets/Scenes/GrappleScene.unity +++ b/Assets/Scenes/GrappleScene.unity @@ -1353,13 +1353,32 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -24.1, y: -10.43, z: -10} + m_LocalPosition: {x: -25.56, y: -10.43, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &580890946 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 5885597207104481991, guid: 576d3fc87874f426294e4bbacb171478, type: 3} + m_PrefabInstance: {fileID: 1407172085} + m_PrefabAsset: {fileID: 0} +--- !u!114 &580890947 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 580890946} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7b873819f9a3f36ef898a0403972da28, type: 3} + m_Name: + m_EditorClassIdentifier: + maxRunSpeed: 20 + runAcceleration: 20 --- !u!1 &619394800 GameObject: m_ObjectHideFlags: 0 @@ -2366,6 +2385,14 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 5885597207104481988, guid: 576d3fc87874f426294e4bbacb171478, type: 3} + propertyPath: m_Mass + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5885597207104481988, guid: 576d3fc87874f426294e4bbacb171478, type: 3} + propertyPath: m_AngularDrag + value: 0 + objectReference: {fileID: 0} - target: {fileID: 5885597207104481988, guid: 576d3fc87874f426294e4bbacb171478, type: 3} propertyPath: m_CollisionDetection value: 1 @@ -2377,7 +2404,10 @@ PrefabInstance: m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] - m_AddedComponents: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 5885597207104481991, guid: 576d3fc87874f426294e4bbacb171478, type: 3} + insertIndex: -1 + addedObject: {fileID: 580890947} m_SourcePrefab: {fileID: 100100000, guid: 576d3fc87874f426294e4bbacb171478, type: 3} --- !u!1 &1411598161 GameObject: diff --git a/Assets/Scripts/PlayerBehavior.cs b/Assets/Scripts/PlayerBehavior.cs index d2fce03..1cf03c7 100644 --- a/Assets/Scripts/PlayerBehavior.cs +++ b/Assets/Scripts/PlayerBehavior.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; -public class PlayerBehavior : MonoBehaviour { - +public class PlayerBehavior : MonoBehaviour +{ + [Header("Physics:")] public float moveSpeed; public float jumpSpeed; @@ -13,7 +14,7 @@ public class PlayerBehavior : MonoBehaviour { private Rigidbody2D _rb; private int forward = 1; public PlayerInput playerInput; - + public LayerMask groundLayer; public Vector2 boxSize; public float maxDistanceFromGround; @@ -31,24 +32,29 @@ public class PlayerBehavior : MonoBehaviour { private StateController stateController; - void Start() { + void Start() + { _rb = GetComponent(); airSpeed = .5f * moveSpeed; stateController = GameObject.Find("StateController").GetComponent(); } - void Update() { + void Update() + { // jump // if (Input.GetKeyDown(KeyCode.Space)) { - if (playerInput.actions["Jump"].WasPressedThisFrame() && IsGrounded()) { + if (playerInput.actions["Jump"].WasPressedThisFrame() && IsGrounded()) + { _rb.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse); } // throw tambourine // if (Input.GetKeyDown(KeyCode.K)) { - if (playerInput.actions["ThrowTambourine"].WasPressedThisFrame()) { - if (hasTambourine && !grapplingRope.isGrappling) { + if (playerInput.actions["ThrowTambourine"].WasPressedThisFrame()) + { + if (hasTambourine && !grapplingRope.isGrappling) + { launcher.ThrowTambourine(forward); hasTambourine = false; } @@ -57,78 +63,100 @@ public class PlayerBehavior : MonoBehaviour { // grapple GameObject tambourine = GameObject.FindGameObjectWithTag("tambourine"); // if (Input.GetKeyDown(KeyCode.L)) { - if (playerInput.actions["Grapple"].WasPressedThisFrame()) { - if (tambourine != null) { // grapple to tambourine - if (!grapplingRope.isGrappling && tambourine.GetComponent().pinned) { + if (playerInput.actions["Grapple"].WasPressedThisFrame()) + { + if (tambourine != null) + { // grapple to tambourine + if (!grapplingRope.isGrappling && tambourine.GetComponent().pinned) + { grapplingGun.GrappleToTambourine(tambourine); grapplingRope.isGrappling = true; } - } else { - if (grappleSurface != null) { + } + else + { + if (grappleSurface != null) + { grapplingGun.GrappleToSurface(grappleSurface.transform.position); grapplingRope.isGrappling = true; } } } // if (Input.GetKeyUp(KeyCode.L)) { - if (playerInput.actions["Grapple"].WasReleasedThisFrame()) { - if (tambourine != null && grapplingRope.isGrappling) { + if (playerInput.actions["Grapple"].WasReleasedThisFrame()) + { + if (tambourine != null && grapplingRope.isGrappling) + { tambourine.GetComponent().DestroySelf(); } grapplingGun.ReleaseGrapple(); } // if (Input.GetKey(KeyCode.L)) { - if (playerInput.actions["Grapple"].IsPressed()) { + if (playerInput.actions["Grapple"].IsPressed()) + { Debug.DrawRay(transform.position, new Vector2(0.500f * forward, 0.866f), Color.green); } } - void OnMove(InputValue value) { + void OnMove(InputValue value) + { _hInput = value.Get().x; - if (_hInput < 0) { + if (_hInput < 0) + { forward = -1; - } else if (_hInput > 0) { + } + else if (_hInput > 0) + { forward = 1; } } - void FixedUpdate() { - if (grapplingRope.isGrappling && _hInput != 0 && !IsGrounded()) { - // print("grappling force"); - _rb.AddForce(new Vector2(_hInput * (airSpeed / 3), 0)); - } else if (_hInput != 0 && !IsGrounded()) { - _rb.AddForce(new Vector2(_hInput * airSpeed, 0)); - } else if (_hInput != 0) { - // print("normal movement"); - _rb.AddForce(new Vector2(_hInput * moveSpeed, 0)); - // _rb.velocity = new Vector2(_hInput * moveSpeed, _rb.velocity.y); - } - } + // void FixedUpdate() { + // if (grapplingRope.isGrappling && _hInput != 0 && !IsGrounded()) { + // // print("grappling force"); + // _rb.AddForce(new Vector2(_hInput * (airSpeed / 3), 0)); + // } else if (_hInput != 0 && !IsGrounded()) { + // _rb.AddForce(new Vector2(_hInput * airSpeed, 0)); + // } else if (_hInput != 0) { + // // print("normal movement"); + // _rb.AddForce(new Vector2(_hInput * moveSpeed, 0)); + // // _rb.velocity = new Vector2(_hInput * moveSpeed, _rb.velocity.y); + // } + // } - void OnTriggerEnter2D(Collider2D col) { - if (col.tag == "grappleSurface") { + void OnTriggerEnter2D(Collider2D col) + { + if (col.tag == "grappleSurface") + { grappleSurface = col.gameObject; - } else if (col.tag == "instaDeath") { + } + else if (col.tag == "instaDeath") + { stateController.ToggleDeathCanvas(); Destroy(this.gameObject); } } - void OnTriggerExit2D(Collider2D col) { - if (col.tag == "grappleSurface") { + void OnTriggerExit2D(Collider2D col) + { + if (col.tag == "grappleSurface") + { grappleSurface = null; } } - bool IsGrounded() { - if (Physics2D.BoxCast(transform.position, boxSize, 0, -transform.up, maxDistanceFromGround, groundLayer)) { + bool IsGrounded() + { + if (Physics2D.BoxCast(transform.position, boxSize, 0, -transform.up, maxDistanceFromGround, groundLayer)) + { return true; } return false; } - void OnDrawGizmos() { + void OnDrawGizmos() + { Gizmos.color = Color.red; - Gizmos.DrawCube(transform.position-transform.up*maxDistanceFromGround,boxSize); + Gizmos.DrawCube(transform.position - transform.up * maxDistanceFromGround, boxSize); } -} \ No newline at end of file +} diff --git a/Assets/Scripts/PlayerController.cs b/Assets/Scripts/PlayerController.cs index 43db83f..ca59cd3 100644 --- a/Assets/Scripts/PlayerController.cs +++ b/Assets/Scripts/PlayerController.cs @@ -1,31 +1,74 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; -public class PlayerController : MonoBehaviour +public class PlayerMovement : MonoBehaviour { + private Rigidbody2D rb; - Vector2 movementValue; - [SerializeField] - float speed; + public float maxRunSpeed; + public float runAcceleration; + private bool onGround = false; + + float hangTimeThreshold = 0.1f; + float hangTimeAccel = 0; + float hangTimeSpeed = 0; + + private Vector2 movement = Vector2.zero; + + void OnValidate() + { + this.runAcceleration = Mathf.Clamp(runAcceleration, 0.1f, this.maxRunSpeed); + } - [SerializeField] - Rigidbody2D rb; - // Start is called before the first frame update void Start() { - + this.rb = this.GetComponent(); } void OnMove(InputValue value) { - this.movementValue = value.Get() * speed; + this.movement = value.Get(); + //Debug.Log(this.movement); } - // Update is called once per frame - void Update() + void FixedUpdate() { - this.rb.AddForce(new Vector3(this.movementValue.x, 0, this.movementValue.y)); + Run(1); + } + + float AccelerationRate() + { + return this.runAcceleration / this.maxRunSpeed; + } + + private void Run(float lerpAmount) + { + float targetSpeed = this.movement.x * this.maxRunSpeed; + + float speedDiff = targetSpeed - this.rb.velocity.x; + + float accel = 0.5f; + + float accelRate = (Mathf.Abs(targetSpeed) > 0.1) ? accel : -accel; + + float velPower = 1.0f; + + float move = Mathf.Pow(Mathf.Abs(speedDiff) * accelRate, velPower) * Mathf.Sign(speedDiff); + + this.rb.AddForce(move * Vector2.right, ForceMode2D.Force); + + float frictionAmount = 0.5f; + + this.onGround = true; + + if (this.onGround && (Mathf.Abs(this.movement.x) < 0.1f)) + { + float amount = Mathf.Min( + Mathf.Abs(this.rb.velocity.x), + Mathf.Abs(frictionAmount) + ); + amount *= Mathf.Sign(this.rb.velocity.x); + this.rb.AddForce(-amount * Vector2.right, ForceMode2D.Impulse); + } } } diff --git a/Assets/Scripts/PlayerData.cs b/Assets/Scripts/PlayerData.cs new file mode 100644 index 0000000..6e777c9 --- /dev/null +++ b/Assets/Scripts/PlayerData.cs @@ -0,0 +1,98 @@ +using UnityEngine; + +[CreateAssetMenu(menuName = "Player Data")] //Create a new playerData object by right clicking in the Project Menu then Create/Player/Player Data and drag onto the player +public class PlayerData : ScriptableObject +{ + [Header("Gravity")] + [HideInInspector] + public float gravityStrength; //Downwards force (gravity) needed for the desired jumpHeight and jumpTimeToApex. + [HideInInspector] + public float gravityScale; //Strength of the player's gravity as a multiplier of gravity (set in ProjectSettings/Physics2D). + //Also the value the player's rigidbody2D.gravityScale is set to. + [Space(5)] + public float fallGravityMult; //Multiplier to the player's gravityScale when falling. + public float maxFallSpeed; //Maximum fall speed (terminal velocity) of the player when falling. + [Space(5)] + public float fastFallGravityMult; //Larger multiplier to the player's gravityScale when they are falling and a downwards input is pressed. + //Seen in games such as Celeste, lets the player fall extra fast if they wish. + public float maxFastFallSpeed; //Maximum fall speed(terminal velocity) of the player when performing a faster fall. + + [Space(20)] + + [Header("Run")] + public float runMaxSpeed; //Target speed we want the player to reach. + public float runAcceleration; //The speed at which our player accelerates to max speed, can be set to runMaxSpeed for instant acceleration down to 0 for none at all + [HideInInspector] + public float runAccelAmount; //The actual force (multiplied with speedDiff) applied to the player. + public float runDecceleration; //The speed at which our player decelerates from their current speed, can be set to runMaxSpeed for instant deceleration down to 0 for none at all + [HideInInspector] + public float runDeccelAmount; //Actual force (multiplied with speedDiff) applied to the player . + [Space(5)] + [Range(0f, 1)] + public float accelInAir; //Multipliers applied to acceleration rate when airborne. + [Range(0f, 1)] + public float deccelInAir; + [Space(5)] + public bool doConserveMomentum = true; + + [Space(20)] + + [Header("Jump")] + public float jumpHeight; //Height of the player's jump + public float jumpTimeToApex; //Time between applying the jump force and reaching the desired jump height. These values also control the player's gravity and jump force. + [HideInInspector] + public float jumpForce; //The actual force applied (upwards) to the player when they jump. + + [Header("Both Jumps")] + public float jumpCutGravityMult; //Multiplier to increase gravity if the player releases thje jump button while still jumping + [Range(0f, 1)] + public float jumpHangGravityMult; //Reduces gravity while close to the apex (desired max height) of the jump + public float jumpHangTimeThreshold; //Speeds (close to 0) where the player will experience extra "jump hang". The player's velocity.y is closest to 0 at the jump's apex (think of the gradient of a parabola or quadratic function) + [Space(0.5f)] + public float jumpHangAccelerationMult; + public float jumpHangMaxSpeedMult; + + [Header("Wall Jump")] + public Vector2 wallJumpForce; //The actual force (this time set by us) applied to the player when wall jumping. + [Space(5)] + [Range(0f, 1f)] + public float wallJumpRunLerp; //Reduces the effect of player's movement while wall jumping. + [Range(0f, 1.5f)] + public float wallJumpTime; //Time after wall jumping the player's movement is slowed for. + public bool doTurnOnWallJump; //Player will rotate to face wall jumping direction + + [Space(20)] + + [Header("Slide")] + public float slideSpeed; + public float slideAccel; + + [Header("Assists")] + [Range(0.01f, 0.5f)] + public float coyoteTime; //Grace period after falling off a platform, where you can still jump + [Range(0.01f, 0.5f)] + public float jumpInputBufferTime; //Grace period after pressing jump where a jump will be automatically performed once the requirements (eg. being grounded) are met. + + + //Unity Callback, called when the inspector updates + private void OnValidate() + { + //Calculate gravity strength using the formula (gravity = 2 * jumpHeight / timeToJumpApex^2) + gravityStrength = -(2 * jumpHeight) / (jumpTimeToApex * jumpTimeToApex); + + //Calculate the rigidbody's gravity scale (ie: gravity strength relative to unity's gravity value, see project settings/Physics2D) + gravityScale = gravityStrength / Physics2D.gravity.y; + + //Calculate are run acceleration & deceleration forces using formula: amount = ((1 / Time.fixedDeltaTime) * acceleration) / runMaxSpeed + runAccelAmount = (50 * runAcceleration) / runMaxSpeed; + runDeccelAmount = (50 * runDecceleration) / runMaxSpeed; + + //Calculate jumpForce using the formula (initialJumpVelocity = gravity * timeToJumpApex) + jumpForce = Mathf.Abs(gravityStrength) * jumpTimeToApex; + + #region Variable Ranges + runAcceleration = Mathf.Clamp(runAcceleration, 0.01f, runMaxSpeed); + runDecceleration = Mathf.Clamp(runDecceleration, 0.01f, runMaxSpeed); + #endregion + } +} diff --git a/Assets/Scripts/PlayerData.cs.meta b/Assets/Scripts/PlayerData.cs.meta new file mode 100644 index 0000000..f0502e0 --- /dev/null +++ b/Assets/Scripts/PlayerData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ddb4766145463c75a48eeb29e77e0d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ofb-assets b/Assets/ofb-assets index 413bfb2..23938e9 160000 --- a/Assets/ofb-assets +++ b/Assets/ofb-assets @@ -1 +1 @@ -Subproject commit 413bfb2c6937c2d11546a7a81aed5ae43d5cc147 +Subproject commit 23938e9b94b9022413054828a87c05d8f5decc2b