using System; using System.Collections.Generic; using UnityEngine; public class playerController : MonoBehaviour { #region Imported Variables private GroundCheck groundCheck; private DoubleCheck doubleCheck; private WallCheck wallCheck; private Rigidbody2D body; private Collider2D hBox; public GameObject attackHitbox; public GameObject gun; #endregion #region Keybinds / Controls private KeyCode hop, up, down, left, right, dash, lightAttack, heavyAttack, ultimateAttack, forward; private String currentDirection; private int directionsHeld; private bool RIGHT, LEFT, UP, DOWN, moveLock; #endregion #region Timers private float coyoteTimeAmount = .1f, airjumpTurnaroundWindow = .1f, jumpBufferAmount = .2f, clickBufferAmount = .1f, wallStallAmount = .15f, dashLength = .15f, waveDashWindow = .18f, scrollSpeed = .15f; private float CoyoteTimer, jumpBufferTimer, clickBufferTimer, airjumpTurnTimer, wallStallTimer, dashCooldownTimer, dashLeftTimer, dashRightTimer, waveDashTimer, hitboxTimer, scrollTimer, reloadTimer; private float tempMaxSpeedTimer, dashCooldownAmount = 1, moveLockTimer, sideDashTimer, pauseGravTimer, dashEndTimer; #endregion #region Player Booleans private bool allowedToWalk = true, allowedToJump = true, allowedToWallSlide = true, allowedToDash = true, speedClampingActive = true, canScroll = true; public bool isGrounded, isWallSlide, canJumpAgain, isFacingRight = true, canDash, dashingLeft, dashingRight, alreadyAirDashed, waveDashing = false; [SerializeField] private bool canDie = true; #endregion #region Player Floats private float defaultMaxSpeed = 10f, defaultMoveSpeed = 10f, defaultJumpPower = 30f, defaultDashPower = 60f, defaultTurnResponsiveness = 4f, defaultExtraJumps = 1f; //Permanent Upgrades Will Affect These private float tempMaxSpeed = 10f, tempMoveSpeed = 10f, tempJumpPower = 30f, tempDashPower = 60f, tempTurnResponsiveness = 8f, tempExtraJumps; //Temporary Upgrades/Debuffs Will Affect These private float velocityDirection = 1, turnaround; [SerializeField] private float playerHealth; #endregion #region Characters/Inventory Management private List playerInventory; public int equippedIndex = 2; public String equippedItem, SelectedPlayer; #endregion void Start() { body = GetComponent(); hBox = transform.GetComponent(); body.gravityScale = 6; #region Character Movesets switch (SelectedPlayer) { case "Cade": playerInventory = new List { "StaffSwing", "Fireball", "DragonBreath" }; break; case "Sloane": playerInventory = new List { "Knife", "Grenade", "Rifle", "Shotgun" }; break; case "Leo": playerInventory = new List { "ChargeFist", "JunkToss", "Grabble" }; break; case "Gamma": playerInventory = new List { "ArmStab", "BlubberBomb", "BodyThrow" }; break; default: playerInventory = new List { "Gun", "Melee"}; break; } equippedItem = playerInventory[equippedIndex]; #endregion #region Character Controls switch (SelectedPlayer) { case "Cade": case "Sloane": default: hop = KeyCode.W; up = KeyCode.W; down = KeyCode.S; left = KeyCode.A; right = KeyCode.D; dash = KeyCode.LeftShift; break; case "Leo": case "Gamma": hop = KeyCode.Space; up = KeyCode.UpArrow; down = KeyCode.DownArrow; left = KeyCode.LeftArrow; right = KeyCode.RightArrow; dash = KeyCode.LeftShift; lightAttack = KeyCode.X; heavyAttack = KeyCode.C; break; } forward = right; #endregion } void Update() { StateCheck(); if (playerHealth > 0) { PhysicsTimersHandler(); Movement(); ControllerTimersHandler(); CheckFaceDirection(); RangedCombat(); } } #region BEHIND-THE-SCENES STUFF void StateCheck() { #region Ground Check groundCheck = GetComponentInChildren(); doubleCheck = GetComponentInChildren(); if (groundCheck.isGrounded && !doubleCheck.isInsideGround) isGrounded = true; else isGrounded = false; #endregion #region Wall Check wallCheck = GetComponentInChildren(); if ((wallCheck.touchingWall) && !isGrounded && Input.GetKey(forward)) isWallSlide = true; else isWallSlide = false; #endregion #region Reload Air Jumps if (isGrounded && (tempExtraJumps < defaultExtraJumps)) tempExtraJumps = defaultExtraJumps; if (tempExtraJumps > 0) canJumpAgain = true; else canJumpAgain = false; #endregion #region Reload Dash if (isGrounded) alreadyAirDashed = false; #endregion #region Health Update playerHealth = GameObject.Find("GameData").GetComponent().CurrentHealth; if (playerHealth <= 0) body.linearVelocityX = 0; #endregion #region Most Recent Direction Input if (moveLock == false) LEFT = Input.GetKey(left); if (moveLock == false) RIGHT = Input.GetKey(right); UP = Input.GetKey(up); DOWN = Input.GetKey(down); directionsHeld = 0; if (LEFT) directionsHeld++; if (RIGHT) directionsHeld++; if (UP) directionsHeld++; if (DOWN) directionsHeld++; if (UP) currentDirection = "up"; else if (DOWN) currentDirection = "down"; else if (LEFT || RIGHT) { if (LEFT && left != forward || RIGHT && right != forward) currentDirection = "backward"; if (LEFT && left == forward || RIGHT && right == forward) currentDirection = "forward"; } else currentDirection = "neutral"; #endregion #region Gravity Updates if (pauseGravTimer <= 0) { if (DOWN && !UP) body.gravityScale = 8; else body.gravityScale = 6; } #endregion } void CheckFaceDirection() { if ((body.linearVelocity.x > 0 && !isFacingRight || body.linearVelocity.x < 0 && isFacingRight) && isGrounded) Flip(); } public void Flip() { if (forward == left) forward = right; else if (forward == right) forward = left; isFacingRight = !isFacingRight; velocityDirection *= -1; #region Change Player Orientation Vector3 currentScale = transform.localScale; currentScale.x *= -1; transform.localScale = currentScale; Vector3 gunScale = gun.transform.localScale; gunScale.x *= -1; gunScale.y *= -1; gun.transform.localScale = gunScale; #endregion } void PhysicsTimersHandler() { #region Coyote Time if (isGrounded && !(body.linearVelocity.y > 0)) CoyoteTimer = coyoteTimeAmount; if (CoyoteTimer > 0) CoyoteTimer -= Time.deltaTime; #endregion #region Jump Buffering if (Input.GetKeyDown(hop)) jumpBufferTimer = jumpBufferAmount; if (jumpBufferTimer > 0) jumpBufferTimer -= Time.deltaTime; #endregion #region Window To Change Directions After Air Jump if (airjumpTurnTimer > 0) airjumpTurnTimer -= Time.deltaTime; #endregion #region Wall Stall if (!isWallSlide || body.linearVelocity.y >= 0) wallStallTimer = wallStallAmount; if (wallStallTimer > 0) wallStallTimer -= Time.deltaTime; #endregion #region WaveDashing if (isGrounded && waveDashing) waveDashTimer -= Time.deltaTime; if (waveDashTimer > 0) waveDashing = true; else waveDashing = false; #endregion #region Resetting Speed Clamping if (tempMaxSpeedTimer <= 0) { tempMaxSpeed = defaultMaxSpeed; body.linearVelocity = new Vector2(Mathf.Clamp(body.linearVelocity.x, -tempMaxSpeed, tempMaxSpeed), Mathf.Clamp(body.linearVelocity.y, -tempJumpPower, tempJumpPower)); } else { tempMaxSpeedTimer -= Time.deltaTime; body.linearVelocity = new Vector2(Mathf.Clamp(body.linearVelocity.x, -tempMaxSpeed, tempMaxSpeed), Mathf.Clamp(body.linearVelocity.y, -tempMaxSpeed, tempMaxSpeed)); } #endregion #region Gravity if (pauseGravTimer > 0) pauseGravTimer -= Time.deltaTime; #endregion #region Physics After A Dash Ends if (dashEndTimer > 0) dashEndTimer -= Time.deltaTime; if (dashEndTimer < 0) { dashEndTimer = 0; if (body.linearVelocity.y > 0) body.linearVelocity = new Vector2(body.linearVelocity.x, 10); } #endregion } void ControllerTimersHandler() { #region Click Buffer & Reload Timers if (Input.GetMouseButtonDown(0)) clickBufferTimer = clickBufferAmount; if (clickBufferTimer > 0) clickBufferTimer -= Time.deltaTime; if (reloadTimer > 0) reloadTimer -= Time.deltaTime; #endregion #region Dash Cooldown if (dashCooldownTimer > 0) dashCooldownTimer -= Time.deltaTime; if (dashCooldownTimer <= 0) canDash = true; else canDash = false; #endregion #region Dash Input Window /* if (dashLeftTimer > 0 && Input.GetKeyDown(left) && canDash && !alreadyAirDashed) dashingLeft = true; if (Input.GetKeyDown(left)) { dashLeftTimer = dashWindowAmount; dashRightTimer = 0; } if (dashRightTimer > 0 && Input.GetKeyDown(right) && canDash && !alreadyAirDashed) dashingRight = true; if (Input.GetKeyDown(right)) { dashRightTimer = dashWindowAmount; dashLeftTimer = 0; } if (dashLeftTimer > 0) dashLeftTimer -= Time.deltaTime; if (dashRightTimer > 0) dashRightTimer -= Time.deltaTime; */ #endregion #region Attack Window if (hitboxTimer >= 0) hitboxTimer -= Time.deltaTime; if (hitboxTimer < 0) attackHitbox.SetActive(false); #endregion #region Inventory Scrolling if (scrollTimer > 0) scrollTimer -= Time.deltaTime; if (scrollTimer > 0) canScroll = false; else canScroll = true; #endregion #region Left/Right Locks if (moveLockTimer > 0) { moveLockTimer -= Time.deltaTime; moveLock = true; } else moveLock = false; #endregion } #endregion #region PLAYER CONTROLLED ASPECTS void Movement() { if (allowedToWalk) { #region Walking if (!(LEFT && RIGHT)) { #region Control Responsiveness if (!isGrounded) turnaround = tempTurnResponsiveness * .75f; else turnaround = tempTurnResponsiveness; if (airjumpTurnTimer > 0) turnaround = tempTurnResponsiveness * 5f; #endregion #region Moving Left if (LEFT) body.linearVelocity += new Vector2(-tempMoveSpeed * turnaround * Time.deltaTime, 0); #endregion #region Moving Right if (RIGHT) body.linearVelocity += new Vector2(tempMoveSpeed * turnaround * Time.deltaTime, 0); #endregion } #endregion #region Friction if (!(Input.GetKey(left) || Input.GetKey(right)) || (Input.GetKey(left) && Input.GetKey(right))) { float fric; if (Math.Abs(body.linearVelocity.x) > 5f) { fric = .97f; } else { fric = .92f; } body.linearVelocity = new Vector2(body.linearVelocity.x * fric, body.linearVelocity.y); if (Math.Abs(body.linearVelocity.x) < .4f) body.linearVelocity = new Vector2(0, body.linearVelocity.y); } #endregion } if (allowedToJump) { #region Normal Jumps if (CoyoteTimer > 0 && jumpBufferTimer > 0) { body.linearVelocity = new Vector2(body.linearVelocity.x, tempJumpPower); jumpBufferTimer = 0; CoyoteTimer = 0; if(waveDashTimer > 0) waveDashTimer = waveDashWindow; Debug.Log("normalJump"); } #endregion #region Air Jumps else if (canJumpAgain && Input.GetKeyDown(hop) && !isWallSlide) { Debug.Log("doubleJump"); jumpBufferTimer = 0; Debug.Log("CHECKDOUBLE"); body.linearVelocity = new Vector2(body.linearVelocity.x, tempJumpPower * .8f); tempExtraJumps--; airjumpTurnTimer = airjumpTurnaroundWindow; } #endregion #region Releasing Jump if (!Input.GetKey(hop) && body.linearVelocity.y > 0) { body.linearVelocity = new Vector2(body.linearVelocity.x, body.linearVelocity.y * .97f); } #endregion } if (allowedToWallSlide) { #region Wall Sliding Friction if (isWallSlide && wallStallTimer > 0 && body.linearVelocity.y < 0) { body.linearVelocity = new Vector2(body.linearVelocity.x, body.linearVelocity.y * .95f); body.gravityScale = 0; } else if (isWallSlide && body.linearVelocity.y < 0) body.gravityScale = 2; #endregion #region Wall Jumps if (isWallSlide && jumpBufferTimer > 0) { moveLockTimer = 0.15f; body.linearVelocity = new Vector2(tempMoveSpeed * -velocityDirection, 20f); if (velocityDirection < 0) { RIGHT = true; LEFT = false; } else if (velocityDirection > 0) { LEFT = true; RIGHT = false; } jumpBufferTimer = 0; } #endregion } if (allowedToDash) { #region Dashing if (Input.GetKeyDown(dash) && canDash && !alreadyAirDashed) { tempMaxSpeed = tempDashPower; tempMaxSpeedTimer = dashLength; moveLockTimer = dashLength; pauseGravTimer = dashLength; body.linearVelocity = new Vector2(body.linearVelocity.x, 0); body.gravityScale = 0; dashCooldownTimer = dashCooldownAmount; alreadyAirDashed = true; if ((LEFT && DOWN || LEFT && UP || RIGHT && DOWN || RIGHT && UP) && directionsHeld == 2) tempDashPower = 0.70710678f * tempDashPower; #region Neutral Dashing if (!LEFT && !RIGHT && directionsHeld % 2 == 0) { if (forward == right) { RIGHT = true; LEFT = false; } else if (forward == left) { LEFT = true; RIGHT = false; } } #endregion #region Directional Dashes if (LEFT && !RIGHT) body.linearVelocity = new Vector2(-tempDashPower, body.linearVelocity.y); if (!LEFT && RIGHT) body.linearVelocity = new Vector2(tempDashPower, body.linearVelocity.y); if (UP && !DOWN) { body.linearVelocity = new Vector2(body.linearVelocity.x, 2f * tempDashPower); dashEndTimer = .15f; } if (!UP && DOWN) body.linearVelocity = new Vector2(body.linearVelocity.x, -2f * tempDashPower); #endregion if ((DOWN && RIGHT || DOWN && LEFT) && directionsHeld == 2) waveDashTimer = waveDashWindow; tempDashPower = defaultDashPower; } #endregion } } public void RangedCombat() { #region Weapon Wheel float scrollInput = Input.GetAxis("Mouse ScrollWheel"); if (scrollInput != 0 && canScroll) { int scrollDirection = Math.Sign(scrollInput); int nextIndex = equippedIndex + scrollDirection; scrollTimer = scrollSpeed; equippedIndex = (nextIndex % playerInventory.Count + playerInventory.Count) % playerInventory.Count; equippedItem = playerInventory[equippedIndex]; reloadTimer = 0; } #endregion #region Shooting if (clickBufferTimer > 0 && reloadTimer <= 0) { switch (equippedItem) { #region Cade's Weapons case "StaffSwing": break; case "Fireball": break; case "DragonBreath": break; #endregion #region Sloane's Weapons case "Knife": break; case "Grenade": break; case "Rifle": break; case "Shotgun": break; #endregion #region Leo's Weapons case "ChargeFist": break; case "JunkToss": break; case "Grabble": break; #endregion #region Gamma's Weapons case "ArmStab": break; case "BlubberBomb": break; case "BodyThrow": break; #endregion #region Test Weapons case "Melee": attackHitbox.SetActive(true); hitboxTimer = .2f; reloadTimer = .3f; Debug.Log("swing"); break; case "Gun": GetComponent().Shoot("Bullet", 2000f, 15f, 25f, .25f, 3, .05f); reloadTimer = .5f; break; #endregion } } #endregion } public void DirectionalCombat() { if (Input.GetKeyDown(lightAttack) && reloadTimer <= 0) { switch (currentDirection) { case ("up"): break; case ("down"): break; case ("backward"): break; case ("forward"): break; case ("right"): break; } } if (Input.GetKeyDown(heavyAttack) && reloadTimer <= 0) { switch (currentDirection) { case ("up"): break; case ("down"): break; case ("left"): break; case ("right"): break; } } } #endregion }