diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player.prefab index 2717c42..fd926f5 100644 --- a/Assets/Prefabs/Player.prefab +++ b/Assets/Prefabs/Player.prefab @@ -40,7 +40,7 @@ Transform: - {fileID: 5885597207531562994} - {fileID: 5885597208269163161} m_Father: {fileID: 0} - m_RootOrder: 0 + m_RootOrder: 9 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &5885597207104481987 SpriteRenderer: @@ -251,17 +251,14 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 7b873819f9a3f36ef898a0403972da28, type: 3} m_Name: m_EditorClassIdentifier: - maxRunSpeed: 10 - runAcceleration: 10 - snappiness: 2.5 - jumpSpeed: 5 - airSpeedMultiplier: 0.5 - groundLayer: + Data: {fileID: 11400000, guid: fec218a9d55267dedac6ebe31eab6dcd, type: 2} + in_range: 0 + enemy: {fileID: 0} + _groundCheckSize: {x: 0.49, y: 0.57} + _wallCheckSize: {x: 0.5, y: 1} + _groundLayer: serializedVersion: 2 m_Bits: 64 - boxSize: {x: 0.03, y: 0.21} - maxDistanceFromGround: 0.22 - stateController: {fileID: 0} --- !u!95 &2772748892378701928 Animator: serializedVersion: 5 @@ -595,7 +592,7 @@ LineRenderer: m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingLayer: 0 - m_SortingOrder: 0 + m_SortingOrder: 2 m_Positions: - {x: 0, y: 0, z: 0} - {x: 0, y: 0, z: 1} diff --git a/Assets/Scenes/GrappleScene.unity b/Assets/Scenes/GrappleScene.unity index 9fb8ea8..6dc1e51 100644 --- a/Assets/Scenes/GrappleScene.unity +++ b/Assets/Scenes/GrappleScene.unity @@ -357,11 +357,11 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 493245979038171992, guid: d175e4c5882b2464ab0425220d00a671, type: 3} propertyPath: m_LocalPosition.x - value: -30.56 + value: -14.54 objectReference: {fileID: 0} - target: {fileID: 493245979038171992, guid: d175e4c5882b2464ab0425220d00a671, type: 3} propertyPath: m_LocalPosition.y - value: -10.5 + value: -10.53 objectReference: {fileID: 0} - target: {fileID: 493245979038171992, guid: d175e4c5882b2464ab0425220d00a671, type: 3} propertyPath: m_LocalPosition.z @@ -1365,7 +1365,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!224 &724240633 RectTransform: m_ObjectHideFlags: 0 @@ -2670,7 +2670,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!224 &1385054184 RectTransform: m_ObjectHideFlags: 0 @@ -2816,10 +2816,6 @@ PrefabInstance: propertyPath: m_Name value: Player objectReference: {fileID: 0} - - target: {fileID: 5885597207789090694, guid: 576d3fc87874f426294e4bbacb171478, type: 3} - propertyPath: m_SortingOrder - value: 2 - objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] diff --git a/Assets/Scripts/PlayerController.cs b/Assets/Scripts/PlayerController.cs index c9e6b8f..5b57219 100644 --- a/Assets/Scripts/PlayerController.cs +++ b/Assets/Scripts/PlayerController.cs @@ -1,151 +1,445 @@ +using System.Collections; using UnityEngine; using UnityEngine.InputSystem; public class PlayerMovement : MonoBehaviour { - private Rigidbody2D rb; + //Scriptable object which holds all the player's movement parameters. If you don't want to use it + //just paste in all the parameters, though you will need to manuly change all references in this script - public float maxRunSpeed; - public float runAcceleration; - public float snappiness = 1; - public float jumpSpeed; - [Range(0, 1)] public float airSpeedMultiplier; - private bool onGround = false; - private float forward = 1; + //HOW TO: to add the scriptable object, right-click in the project window -> create -> Player Data + //Next, drag it into the slot in playerMovement on your player - float hangTimeThreshold = 0.1f; - float hangTimeAccel = 0; - float hangTimeSpeed = 0; + public PlayerData Data; - private Vector2 movement = Vector2.zero; + #region Variables + //Components + public Rigidbody2D RB { get; private set; } - public LayerMask groundLayer; - public Vector2 boxSize; - public float maxDistanceFromGround; + //Variables control the various actions the player can perform at any time. + //These are fields which can are public allowing for other sctipts to read them + //but can only be privately written to. + public bool IsFacingRight { get; private set; } + public bool IsJumping { get; private set; } + public bool IsWallJumping { get; private set; } + public bool IsSliding { get; private set; } + //Timers (also all fields, could be private and a method returning a bool could be used) + public float LastOnGroundTime { get; private set; } + public float LastOnWallTime { get; private set; } + public float LastOnWallRightTime { get; private set; } + public float LastOnWallLeftTime { get; private set; } + private bool trumpet = false; public bool in_range = false; public GameObject enemy; - [Header("State Control:")] - [SerializeField] private StateController stateController; + //Jump + private bool _isJumpCut; + private bool _isJumpFalling; - PlayerBehavior playerBehavior; + //Wall Jump + private float _wallJumpStartTime; + private int _lastWallJumpDir; - void OnValidate() + private Vector2 _moveInput; + public float LastPressedJumpTime { get; private set; } + + Tutorial_GrapplingRope grapplingRope; + + //Set all of these up in the inspector + [Header("Checks")] + //Size of groundCheck depends on the size of your character generally you want them slightly small than width (for ground) and height (for the wall check) + [SerializeField] private Vector2 _groundCheckSize = new Vector2(0.49f, 0.03f); + [Space(5)] + [SerializeField] private Vector2 _wallCheckSize = new Vector2(0.5f, 1f); + + [Header("Layers & Tags")] + [SerializeField] private LayerMask _groundLayer; + #endregion + + private void Awake() { - this.runAcceleration = Mathf.Clamp(runAcceleration, 0.1f, this.maxRunSpeed); + RB = GetComponent(); + grapplingRope = this.gameObject.GetComponent().grapplingRope; } - void Start() + private void Start() { - playerBehavior = this.gameObject.GetComponent(); - this.rb = this.GetComponent(); - stateController = GameObject.Find("StateController").GetComponent(); + SetGravityScale(Data.gravityScale); + IsFacingRight = true; } void OnMove(InputValue value) { - this.movement = value.Get(); - //Debug.Log(this.movement); + this._moveInput = value.Get(); } void OnJump() { - if (IsGrounded()) - { - //need to add a condition so that trumpet is only true in certain scenes - trumpet = true; - rb.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse); - } - else if (!IsGrounded() && in_range && trumpet) - { - Destroy(enemy.gameObject); - rb.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse); - enemy = null; - in_range = false; - } - else if (!IsGrounded() && trumpet && !in_range) - { - rb.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse); - trumpet = false; - } + OnJumpInput(); } - void FixedUpdate() + private void Update() { - Run(1); + #region TIMERS + LastOnGroundTime -= Time.deltaTime; + LastOnWallTime -= Time.deltaTime; + LastOnWallRightTime -= Time.deltaTime; + LastOnWallLeftTime -= Time.deltaTime; + + LastPressedJumpTime -= Time.deltaTime; + #endregion + + #region INPUT HANDLER + + if (_moveInput.x != 0) + CheckDirectionToFace(_moveInput.x > 0); + #endregion + + if (!IsJumping) { + print("not jumping"); + } else { + print("jumping, " + RB.velocity.y); + } + + #region COLLISION CHECKS + if (!IsJumping) + { + //Ground Check + if (IsGrounded()) //checks if set box overlaps with ground + { + LastOnGroundTime = Data.coyoteTime; //if so sets the lastGrounded to coyoteTime + trumpet = true; + } + + //Right Wall Check + if (((Physics2D.OverlapBox(this.transform.position, _wallCheckSize, 0, _groundLayer) && IsFacingRight) + || (Physics2D.OverlapBox(this.transform.position, _wallCheckSize, 0, _groundLayer) && !IsFacingRight)) && !IsWallJumping) + LastOnWallRightTime = Data.coyoteTime; + + //Right Wall Check + if (((Physics2D.OverlapBox(this.transform.position, _wallCheckSize, 0, _groundLayer) && !IsFacingRight) + || (Physics2D.OverlapBox(this.transform.position, _wallCheckSize, 0, _groundLayer) && IsFacingRight)) && !IsWallJumping) + LastOnWallLeftTime = Data.coyoteTime; + + //Two checks needed for both left and right walls since whenever the play turns the wall checkPoints swap sides + LastOnWallTime = Mathf.Max(LastOnWallLeftTime, LastOnWallRightTime); + } + #endregion + + #region JUMP CHECKS + if (IsJumping && RB.velocity.y <= 0) + { + IsJumping = false; + print("isJumping " + IsJumping); + + if (!IsWallJumping) + _isJumpFalling = true; + } + + if (IsWallJumping && Time.time - _wallJumpStartTime > Data.wallJumpTime) + { + IsWallJumping = false; + } + + if (LastOnGroundTime > 0 && !IsJumping && !IsWallJumping) + { + _isJumpCut = false; + + if (!IsJumping) + _isJumpFalling = false; + } + + //Jump + if (CanJump() && LastPressedJumpTime > 0) + { + IsJumping = true; + IsWallJumping = false; + _isJumpCut = false; + _isJumpFalling = false; + Jump(); + if (!IsGrounded() && in_range && trumpet) { + Destroy(enemy.gameObject); + enemy = null; + in_range = false; + } else if (!IsGrounded() && !in_range && trumpet) { + trumpet = false; + } + } + //WALL JUMP + // else if (CanWallJump() && LastPressedJumpTime > 0) + // { + // IsWallJumping = true; + // IsJumping = false; + // _isJumpCut = false; + // _isJumpFalling = false; + // _wallJumpStartTime = Time.time; + // _lastWallJumpDir = (LastOnWallRightTime > 0) ? -1 : 1; + // + // WallJump(_lastWallJumpDir); + // } + #endregion + + #region SLIDE CHECKS + if (CanSlide() && ((LastOnWallLeftTime > 0 && _moveInput.x < 0) || (LastOnWallRightTime > 0 && _moveInput.x > 0))) + IsSliding = true; + else + IsSliding = false; + #endregion + + #region GRAVITY + //Higher gravity if we've released the jump input or are falling + if (IsSliding) + { + SetGravityScale(0); + } + else if (RB.velocity.y < 0 && _moveInput.y < 0) + { + //Much higher gravity if holding down + SetGravityScale(Data.gravityScale * Data.fastFallGravityMult); + //Caps maximum fall speed, so when falling over large distances we don't accelerate to insanely high speeds + RB.velocity = new Vector2(RB.velocity.x, Mathf.Max(RB.velocity.y, -Data.maxFastFallSpeed)); + } + else if (_isJumpCut) + { + //Higher gravity if jump button released + SetGravityScale(Data.gravityScale * Data.jumpCutGravityMult); + RB.velocity = new Vector2(RB.velocity.x, Mathf.Max(RB.velocity.y, -Data.maxFallSpeed)); + } + else if ((IsJumping || IsWallJumping || _isJumpFalling) && Mathf.Abs(RB.velocity.y) < Data.jumpHangTimeThreshold) + { + SetGravityScale(Data.gravityScale * Data.jumpHangGravityMult); + } + else if (RB.velocity.y < 0) + { + //Higher gravity if falling + SetGravityScale(Data.gravityScale * Data.fallGravityMult); + //Caps maximum fall speed, so when falling over large distances we don't accelerate to insanely high speeds + RB.velocity = new Vector2(RB.velocity.x, Mathf.Max(RB.velocity.y, -Data.maxFallSpeed)); + } + else + { + //Default gravity if standing on a platform or moving upwards + SetGravityScale(Data.gravityScale); + } + #endregion } - float AccelerationRate() + private void FixedUpdate() { - return this.runAcceleration / this.maxRunSpeed; + //Handle Run + if (IsWallJumping) + Run(Data.wallJumpRunLerp); + else + Run(1); + + //Handle Slide + if (IsSliding) + Slide(); } + #region INPUT CALLBACKS + //Methods which whandle input detected in Update() + public void OnJumpInput() + { + LastPressedJumpTime = Data.jumpInputBufferTime; + } + + public void OnJumpUpInput() + { + if (CanJumpCut() || CanWallJumpCut()) + _isJumpCut = true; + } + #endregion + + #region GENERAL METHODS + public void SetGravityScale(float scale) + { + RB.gravityScale = scale; + } + #endregion + + //MOVEMENT METHODS + #region RUN METHODS private void Run(float lerpAmount) { - float targetSpeed = this.movement.x * this.maxRunSpeed; + //Calculate the direction we want to move in and our desired velocity + float targetSpeed = _moveInput.x * Data.runMaxSpeed; + //We can reduce are control using Lerp() this smooths changes to are direction and speed + targetSpeed = Mathf.Lerp(RB.velocity.x, targetSpeed, lerpAmount); - float speedDiff = targetSpeed - this.rb.velocity.x; - forward = Mathf.Sign(speedDiff); + #region Calculate AccelRate + float accelRate; - float accel = AccelerationRate() * snappiness; + //Gets an acceleration value based on if we are accelerating (includes turning) + //or trying to decelerate (stop). As well as applying a multiplier if we're air borne. + if (LastOnGroundTime > 0) + accelRate = (Mathf.Abs(targetSpeed) > 0.01f) ? Data.runAccelAmount : Data.runDeccelAmount; + else + accelRate = (Mathf.Abs(targetSpeed) > 0.01f) ? Data.runAccelAmount * Data.accelInAir : Data.runDeccelAmount * Data.deccelInAir; + #endregion - float accelRate = (Mathf.Abs(targetSpeed) > 0.1) ? accel : -accel; - - float velPower = 1.0f; - - float move = Mathf.Pow(Mathf.Abs(speedDiff) * accelRate, velPower) * forward; - - this.onGround = IsGrounded(); - - float frictionAmount = 0.5f; - - // accelerate - if (onGround && (Mathf.Abs(this.movement.x) > 0.1f)) - { // regular acceleration - this.rb.AddForce(move * Vector2.right, ForceMode2D.Force); - } - else if (!onGround && (Mathf.Abs(this.movement.x) > 0.1f) && !playerBehavior.grapplingRope.isGrappling) - { // while in air - this.rb.AddForce(move * Vector2.right * airSpeedMultiplier, ForceMode2D.Force); - } - else if (!playerBehavior.grapplingRope.isGrappling) - { // while grappling - this.rb.AddForce(move * Vector2.right * airSpeedMultiplier * airSpeedMultiplier, ForceMode2D.Force); - } - - // decelerate until stopped - if (onGround && Mathf.Abs(this.movement.x) < 0.1f) + #region Add Bonus Jump Apex Acceleration + //Increase are acceleration and maxSpeed when at the apex of their jump, makes the jump feel a bit more bouncy, responsive and natural + if ((IsJumping || IsWallJumping || _isJumpFalling) && Mathf.Abs(RB.velocity.y) < Data.jumpHangTimeThreshold) { - if (Mathf.Abs(rb.velocity.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 * snappiness, ForceMode2D.Impulse); - } - else - { - this.rb.velocity = new Vector2(0, rb.velocity.y); - } + accelRate *= Data.jumpHangAccelerationMult; + targetSpeed *= Data.jumpHangMaxSpeedMult; } + #endregion + + #region Conserve Momentum + //We won't slow the player down if they are moving in their desired direction but at a greater speed than their maxSpeed + if ((Data.doConserveMomentum && Mathf.Abs(RB.velocity.x) > Mathf.Abs(targetSpeed) && Mathf.Sign(RB.velocity.x) == Mathf.Sign(targetSpeed) && Mathf.Abs(targetSpeed) > 0.01f && LastOnGroundTime < 0) || grapplingRope.isGrappling) + { + //Prevent any deceleration from happening, or in other words conserve are current momentum + //You could experiment with allowing for the player to slightly increae their speed whilst in this "state" + accelRate = 0; + } + #endregion + + //Calculate difference between current velocity and desired velocity + float speedDif = targetSpeed - RB.velocity.x; + //Calculate force along x-axis to apply to thr player + + float movement = speedDif * accelRate; + + //Convert this to a vector and apply to rigidbody + RB.AddForce(movement * Vector2.right, ForceMode2D.Force); + + /* + * For those interested here is what AddForce() will do + * RB.velocity = new Vector2(RB.velocity.x + (Time.fixedDeltaTime * speedDif * accelRate) / RB.mass, RB.velocity.y); + * Time.fixedDeltaTime is by default in Unity 0.02 seconds equal to 50 FixedUpdate() calls per second + */ } - bool IsGrounded() + private void Turn() { - if (Physics2D.BoxCast(transform.position, boxSize, 0, -transform.up, maxDistanceFromGround, groundLayer)) - { + //stores scale and flips the player along the x axis, + Vector3 scale = transform.localScale; + scale.x *= -1; + transform.localScale = scale; + + IsFacingRight = !IsFacingRight; + } + #endregion + + #region JUMP METHODS + private void Jump() + { + //Ensures we can't call Jump multiple times from one press + LastPressedJumpTime = 0; + LastOnGroundTime = 0; + + #region Perform Jump + //We increase the force applied if we are falling + //This means we'll always feel like we jump the same amount + //(setting the player's Y velocity to 0 beforehand will likely work the same, but I find this more elegant :D) + float force = Data.jumpForce; + if (RB.velocity.y < 0) + force -= RB.velocity.y; + + RB.AddForce(Vector2.up * force, ForceMode2D.Impulse); + #endregion + } + + private void WallJump(int dir) + { + //Ensures we can't call Wall Jump multiple times from one press + LastPressedJumpTime = 0; + LastOnGroundTime = 0; + LastOnWallRightTime = 0; + LastOnWallLeftTime = 0; + + #region Perform Wall Jump + Vector2 force = new Vector2(Data.wallJumpForce.x, Data.wallJumpForce.y); + force.x *= dir; //apply force in opposite direction of wall + + if (Mathf.Sign(RB.velocity.x) != Mathf.Sign(force.x)) + force.x -= RB.velocity.x; + + if (RB.velocity.y < 0) //checks whether player is falling, if so we subtract the velocity.y (counteracting force of gravity). This ensures the player always reaches our desired jump force or greater + force.y -= RB.velocity.y; + + //Unlike in the run we want to use the Impulse mode. + //The default mode will apply are force instantly ignoring masss + //RB.AddForce(force, ForceMode2D.Impulse); + #endregion + } + #endregion + + #region OTHER MOVEMENT METHODS + private void Slide() + { + //Works the same as the Run but only in the y-axis + //THis seems to work fine, buit maybe you'll find a better way to implement a slide into this system + float speedDif = Data.slideSpeed - RB.velocity.y; + float movement = speedDif * Data.slideAccel; + //So, we clamp the movement here to prevent any over corrections (these aren't noticeable in the Run) + //The force applied can't be greater than the (negative) speedDifference * by how many times a second FixedUpdate() is called. For more info research how force are applied to rigidbodies. + movement = Mathf.Clamp(movement, -Mathf.Abs(speedDif) * (1 / Time.fixedDeltaTime), Mathf.Abs(speedDif) * (1 / Time.fixedDeltaTime)); + + RB.AddForce(movement * Vector2.up); + } + #endregion + + + #region CHECK METHODS + public void CheckDirectionToFace(bool isMovingRight) + { + // if (isMovingRight != IsFacingRight) + // Turn(); + } + + private bool CanJump() + { + if (!IsGrounded() && trumpet) { return true; } - return false; + return LastOnGroundTime > 0 && !IsJumping; } - void OnDrawGizmos() + private bool CanWallJump() { - Gizmos.color = Color.red; - Gizmos.DrawCube(transform.position - transform.up * maxDistanceFromGround, boxSize); + return LastPressedJumpTime > 0 && LastOnWallTime > 0 && LastOnGroundTime <= 0 && (!IsWallJumping || + (LastOnWallRightTime > 0 && _lastWallJumpDir == 1) || (LastOnWallLeftTime > 0 && _lastWallJumpDir == -1)); } + + private bool CanJumpCut() + { + return IsJumping && RB.velocity.y > 0; + } + + private bool CanWallJumpCut() + { + return IsWallJumping && RB.velocity.y > 0; + } + + public bool CanSlide() + { + if (LastOnWallTime > 0 && !IsJumping && !IsWallJumping && LastOnGroundTime <= 0) + return true; + else + return false; + } + + public bool IsGrounded() { + // print(Physics2D.OverlapBox(this.transform.position, _groundCheckSize, 0, _groundLayer) && !IsJumping); + return (Physics2D.OverlapBox(this.transform.position, _groundCheckSize, 0, _groundLayer) && !IsJumping); + } + #endregion + + + #region EDITOR METHODS + private void OnDrawGizmosSelected() + { + Gizmos.color = Color.green; + Gizmos.DrawWireCube(this.transform.position, _groundCheckSize); + Gizmos.color = Color.blue; + Gizmos.DrawWireCube(this.transform.position, _wallCheckSize); + Gizmos.DrawWireCube(this.transform.position, _wallCheckSize); + } + #endregion } diff --git a/Assets/Scripts/PlayerData.cs b/Assets/Scripts/PlayerData.cs index 6e777c9..0fc540b 100644 --- a/Assets/Scripts/PlayerData.cs +++ b/Assets/Scripts/PlayerData.cs @@ -4,11 +4,9 @@ using UnityEngine; 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. + [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. @@ -22,16 +20,12 @@ public class PlayerData : ScriptableObject [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. + [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 . + [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; + [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; @@ -40,13 +34,11 @@ public class PlayerData : ScriptableObject [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. + [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 + [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; @@ -55,10 +47,8 @@ public class PlayerData : ScriptableObject [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. + [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)] @@ -68,10 +58,8 @@ public class PlayerData : ScriptableObject 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. + [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 diff --git a/Assets/Scripts/PlayerMovementData.asset b/Assets/Scripts/PlayerMovementData.asset new file mode 100644 index 0000000..f7c0058 --- /dev/null +++ b/Assets/Scripts/PlayerMovementData.asset @@ -0,0 +1,44 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5ddb4766145463c75a48eeb29e77e0d3, type: 3} + m_Name: PlayerMovementData + m_EditorClassIdentifier: + gravityStrength: -28.57143 + gravityScale: 2.91248 + fallGravityMult: 1.5 + maxFallSpeed: 25 + fastFallGravityMult: 2 + maxFastFallSpeed: 30 + runMaxSpeed: 5 + runAcceleration: 2.5 + runAccelAmount: 25 + runDecceleration: 5 + runDeccelAmount: 50 + accelInAir: 0.65 + deccelInAir: 0.65 + doConserveMomentum: 1 + jumpHeight: 1.75 + jumpTimeToApex: 0.35 + jumpForce: 10 + jumpCutGravityMult: 2 + jumpHangGravityMult: 0.5 + jumpHangTimeThreshold: 1.02 + jumpHangAccelerationMult: 1.1 + jumpHangMaxSpeedMult: 1.3 + wallJumpForce: {x: 15, y: 25} + wallJumpRunLerp: 0.5 + wallJumpTime: 0.15 + doTurnOnWallJump: 0 + slideSpeed: 0 + slideAccel: 0 + coyoteTime: 0.1 + jumpInputBufferTime: 0.1 diff --git a/Assets/Scripts/PlayerMovementData.asset.meta b/Assets/Scripts/PlayerMovementData.asset.meta new file mode 100644 index 0000000..4830880 --- /dev/null +++ b/Assets/Scripts/PlayerMovementData.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fec218a9d55267dedac6ebe31eab6dcd +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: