Merge branch 'combining'
This commit is contained in:
		@@ -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}
 | 
			
		||||
 
 | 
			
		||||
@@ -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: []
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Rigidbody2D>();
 | 
			
		||||
        grapplingRope = this.gameObject.GetComponent<PlayerBehavior>().grapplingRope;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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())
 | 
			
		||||
        {
 | 
			
		||||
            //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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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: -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
 | 
			
		||||
							
								
								
									
										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: 
 | 
			
		||||
		Reference in New Issue
	
	Block a user