Finished overhaul of movement controller
This commit is contained in:
parent
775bfd76ea
commit
ded2d4e1da
@ -1,123 +1,418 @@
|
||||
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; }
|
||||
|
||||
[Header("State Control:")]
|
||||
[SerializeField] private StateController stateController;
|
||||
//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; }
|
||||
|
||||
PlayerBehavior playerBehavior;
|
||||
//Jump
|
||||
private bool _isJumpCut;
|
||||
private bool _isJumpFalling;
|
||||
|
||||
void OnValidate()
|
||||
//Wall Jump
|
||||
private float _wallJumpStartTime;
|
||||
private int _lastWallJumpDir;
|
||||
|
||||
private Vector2 _moveInput;
|
||||
public float LastPressedJumpTime { get; private set; }
|
||||
|
||||
//Set all of these up in the inspector
|
||||
[Header("Checks")]
|
||||
[SerializeField] private Transform _groundCheckPoint;
|
||||
//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 Transform _frontWallCheckPoint;
|
||||
[SerializeField] private Transform _backWallCheckPoint;
|
||||
[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<Rigidbody2D>();
|
||||
}
|
||||
|
||||
void Start()
|
||||
private void Start()
|
||||
{
|
||||
playerBehavior = this.gameObject.GetComponent<PlayerBehavior>();
|
||||
this.rb = this.GetComponent<Rigidbody2D>();
|
||||
stateController = GameObject.Find("StateController").GetComponent<StateController>();
|
||||
SetGravityScale(Data.gravityScale);
|
||||
IsFacingRight = true;
|
||||
}
|
||||
|
||||
void OnMove(InputValue value)
|
||||
{
|
||||
this.movement = value.Get<Vector2>();
|
||||
//Debug.Log(this.movement);
|
||||
this._moveInput = value.Get<Vector2>();
|
||||
}
|
||||
|
||||
void OnJump() {
|
||||
if (IsGrounded()) {
|
||||
rb.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse);
|
||||
}
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
void OnJump()
|
||||
{
|
||||
OnJumpInput();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
#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
|
||||
|
||||
#region COLLISION CHECKS
|
||||
if (!IsJumping)
|
||||
{
|
||||
//Ground Check
|
||||
if (Physics2D.OverlapBox(_groundCheckPoint.position, _groundCheckSize, 0, _groundLayer) && !IsJumping) //checks if set box overlaps with ground
|
||||
{
|
||||
LastOnGroundTime = Data.coyoteTime; //if so sets the lastGrounded to coyoteTime
|
||||
}
|
||||
|
||||
//Right Wall Check
|
||||
if (((Physics2D.OverlapBox(_frontWallCheckPoint.position, _wallCheckSize, 0, _groundLayer) && IsFacingRight)
|
||||
|| (Physics2D.OverlapBox(_backWallCheckPoint.position, _wallCheckSize, 0, _groundLayer) && !IsFacingRight)) && !IsWallJumping)
|
||||
LastOnWallRightTime = Data.coyoteTime;
|
||||
|
||||
//Right Wall Check
|
||||
if (((Physics2D.OverlapBox(_frontWallCheckPoint.position, _wallCheckSize, 0, _groundLayer) && !IsFacingRight)
|
||||
|| (Physics2D.OverlapBox(_backWallCheckPoint.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;
|
||||
|
||||
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();
|
||||
}
|
||||
//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
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
//Handle Run
|
||||
if (IsWallJumping)
|
||||
Run(Data.wallJumpRunLerp);
|
||||
else
|
||||
Run(1);
|
||||
|
||||
//Handle Slide
|
||||
if (IsSliding)
|
||||
Slide();
|
||||
}
|
||||
|
||||
float AccelerationRate()
|
||||
#region INPUT CALLBACKS
|
||||
//Methods which whandle input detected in Update()
|
||||
public void OnJumpInput()
|
||||
{
|
||||
return this.runAcceleration / this.maxRunSpeed;
|
||||
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)
|
||||
{
|
||||
//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()
|
||||
{
|
||||
return LastOnGroundTime > 0 && !IsJumping;
|
||||
}
|
||||
|
||||
private bool CanWallJump()
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endregion
|
||||
|
||||
void OnDrawGizmos()
|
||||
|
||||
#region EDITOR METHODS
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawCube(transform.position - transform.up * maxDistanceFromGround, boxSize);
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.DrawWireCube(_groundCheckPoint.position, _groundCheckSize);
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawWireCube(_frontWallCheckPoint.position, _wallCheckSize);
|
||||
Gizmos.DrawWireCube(_backWallCheckPoint.position, _wallCheckSize);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -4,10 +4,8 @@ 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).
|
||||
[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.
|
||||
@ -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
|
||||
|
44
Assets/Scripts/PlayerMovementData.asset
Normal file
44
Assets/Scripts/PlayerMovementData.asset
Normal file
@ -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: -20.408163
|
||||
gravityScale: 2.0803428
|
||||
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: 5
|
||||
jumpTimeToApex: 0.7
|
||||
jumpForce: 14.285714
|
||||
jumpCutGravityMult: 2
|
||||
jumpHangGravityMult: 0.5
|
||||
jumpHangTimeThreshold: 1
|
||||
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
|
8
Assets/Scripts/PlayerMovementData.asset.meta
Normal file
8
Assets/Scripts/PlayerMovementData.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fec218a9d55267dedac6ebe31eab6dcd
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user