295 lines
9.9 KiB
C#
295 lines
9.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class Player : MonoBehaviour
|
|
{
|
|
[SerializeField] private float runSpeed = 10f;
|
|
[SerializeField] private float jumpSpeed = 35f;
|
|
[SerializeField] private float runFasterFactor = 1.5f;
|
|
[SerializeField] private float groundErrorThreshold = 1.5f;
|
|
[SerializeField] private float wallErrorThreshold = 1.5f;
|
|
[SerializeField] private float wallLineCaseDistance = 0.5f;
|
|
[SerializeField] private float runErrorThreshold = 0.05f;
|
|
[SerializeField] private int startHealth = 3;
|
|
[SerializeField] private int startStamina = 100;
|
|
[SerializeField] private int coffeValuePercent = 25;
|
|
[SerializeField] private int bugStaminaDamagePercent = 15;
|
|
[SerializeField] private float hurtVelocity = 15f;
|
|
[SerializeField] private int fightSoundLength = 5;
|
|
|
|
private int currentHealth;
|
|
private int currentStamina;
|
|
private float staminaInitialSize;
|
|
|
|
[SerializeField] private SpriteRenderer healthBar;
|
|
[SerializeField] private SpriteRenderer staminaBar;
|
|
|
|
private Rigidbody2D rigidBody;
|
|
new private Collider2D collider;
|
|
private Animator animator;
|
|
private bool isMovementEnabled = true;
|
|
private bool isFighting = false;
|
|
private bool isHurt = false;
|
|
private int fightSoundAccumalator = 0;
|
|
private bool isPlayerHurt = false;
|
|
|
|
private void Start()
|
|
{
|
|
rigidBody = GetComponent<Rigidbody2D>();
|
|
collider = GetComponent<Collider2D>();
|
|
animator = GetComponent<Animator>();
|
|
|
|
currentHealth = startHealth;
|
|
healthBar.size = new Vector2(1.5f * startHealth, healthBar.size.y);
|
|
|
|
currentStamina = startStamina;
|
|
staminaInitialSize = staminaBar.size.x;
|
|
staminaBar.size = new Vector2(staminaInitialSize, staminaBar.size.y);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
MovePlayer();
|
|
}
|
|
|
|
public void OnConsumable(Collider2D collision)
|
|
{
|
|
if (collision.gameObject.tag == "Pizza")
|
|
{
|
|
SoundManagerScript.PlaySound("eat");
|
|
Destroy(collision.gameObject);
|
|
currentHealth += currentHealth < startHealth ? 1 : 0;
|
|
healthBar.size = new Vector2(1.5f * currentHealth, this.healthBar.size.y);
|
|
}
|
|
else if (collision.gameObject.tag == "Coffee")
|
|
{
|
|
Destroy(collision.gameObject);
|
|
DrinkCoffee();
|
|
}
|
|
}
|
|
|
|
private void DrinkCoffee()
|
|
{
|
|
SoundManagerScript.PlaySound("drink");
|
|
int result = currentStamina + GetStaminaValueChange(coffeValuePercent);
|
|
currentStamina = result < startStamina ? result : startStamina;
|
|
float multiplier = currentStamina * 1f / startStamina;
|
|
staminaBar.size = new Vector2(staminaInitialSize * multiplier, staminaBar.size.y);
|
|
}
|
|
|
|
private void DecreaseStaminaAfterBugFight()
|
|
{
|
|
int result = currentStamina - GetStaminaValueChange(bugStaminaDamagePercent);
|
|
currentStamina = result < 0 ? 0 : result;
|
|
float multiplier = currentStamina * 1f / startStamina;
|
|
staminaBar.size = new Vector2(staminaInitialSize * multiplier, staminaBar.size.y);
|
|
}
|
|
|
|
private int GetStaminaValueChange(int percentage)
|
|
{
|
|
return currentStamina <= startStamina ? (startStamina * percentage / 100) : 0;
|
|
}
|
|
|
|
private void Hurt()
|
|
{
|
|
currentHealth -= currentHealth > 0 ? 1 : 0;
|
|
healthBar.size = new Vector2(1.5f * currentHealth, this.healthBar.size.y);
|
|
|
|
if (currentHealth <= 0) GameOver();
|
|
}
|
|
|
|
private void GameOver()
|
|
{
|
|
SceneManager.LoadScene("GameOver");
|
|
}
|
|
|
|
|
|
private void MovePlayer()
|
|
{
|
|
if (isMovementEnabled)
|
|
{
|
|
Jump();
|
|
Run();
|
|
FlipSprite();
|
|
}
|
|
|
|
if (Mathf.Abs(rigidBody.velocity.y) < runErrorThreshold)
|
|
{
|
|
isHurt = false;
|
|
};
|
|
|
|
PlayFightSound();
|
|
HandleAnimations();
|
|
}
|
|
|
|
private void Jump()
|
|
{
|
|
// Jump
|
|
if (Input.GetKeyDown(KeyCode.Space) && IsPlayerOnGround())
|
|
{
|
|
SoundManagerScript.PlaySound("jump");
|
|
rigidBody.velocity += new Vector2(0, jumpSpeed);
|
|
rigidBody.velocity = new Vector2(rigidBody.velocity.x,
|
|
Mathf.Clamp(rigidBody.velocity.y, 0, jumpSpeed));
|
|
}
|
|
}
|
|
|
|
private void Run()
|
|
{
|
|
var actualRunSpeed = runSpeed;
|
|
|
|
// Speed Run Increase
|
|
if (Input.GetKey(KeyCode.W))
|
|
{
|
|
actualRunSpeed *= runFasterFactor;
|
|
}
|
|
if (IsPlayerOnWall())
|
|
{
|
|
actualRunSpeed = 0;
|
|
}
|
|
|
|
// Run
|
|
if (Input.GetKey(KeyCode.RightArrow))
|
|
{
|
|
rigidBody.velocity = new Vector2(actualRunSpeed, rigidBody.velocity.y);
|
|
}
|
|
else if (Input.GetKey(KeyCode.LeftArrow))
|
|
{
|
|
rigidBody.velocity = new Vector2(actualRunSpeed * -1, rigidBody.velocity.y);
|
|
}
|
|
|
|
// Run
|
|
if (Input.GetKeyUp(KeyCode.RightArrow))
|
|
{
|
|
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
|
|
}
|
|
else if (Input.GetKeyUp(KeyCode.LeftArrow))
|
|
{
|
|
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
|
|
}
|
|
}
|
|
|
|
private bool IsPlayerOnGround()
|
|
{
|
|
return IsPointOnGround(transform.position + new Vector3(collider.bounds.extents.x * 0.96f, 0, 0)) ||
|
|
IsPointOnGround(transform.position) ||
|
|
IsPointOnGround(transform.position - new Vector3(collider.bounds.extents.x * 0.99f, 0, 0));
|
|
}
|
|
|
|
private bool IsPointOnGround(Vector2 position)
|
|
{
|
|
Debug.DrawLine(position, position - new Vector2(0, collider.bounds.extents.y * groundErrorThreshold));
|
|
|
|
RaycastHit2D hit = Physics2D.Raycast(position,
|
|
-Vector2.up,
|
|
collider.bounds.extents.y * groundErrorThreshold,
|
|
LayerMask.GetMask(LayerNames.Ground));
|
|
|
|
return hit.collider != null && hit.collider.IsTouching(collider);
|
|
}
|
|
|
|
private bool IsPlayerOnWall(bool ignoreGround = false)
|
|
{
|
|
return IsPointOnWall(transform.position + new Vector3(0, collider.bounds.extents.y * 0.52f, 0), ignoreGround) ||
|
|
IsPointOnWall(transform.position - new Vector3(0, collider.bounds.extents.y * 0.24f, 0), ignoreGround) ||
|
|
IsPointOnWall(transform.position - new Vector3(0, collider.bounds.extents.y * 0.8f, 0), ignoreGround) ||
|
|
IsPointOnWall(transform.position - new Vector3(0, collider.bounds.extents.y * 1.45f, 0), ignoreGround);
|
|
}
|
|
|
|
private bool IsPointOnWall(Vector2 position, bool ignoreGround = false)
|
|
{
|
|
Debug.DrawLine(position, position + new Vector2(collider.bounds.extents.x * wallErrorThreshold, 0), Color.green);
|
|
Debug.DrawLine(position, position - new Vector2(collider.bounds.extents.x * wallErrorThreshold, 0), Color.green);
|
|
|
|
var rightHit = Physics2D.Linecast(position,
|
|
position + new Vector2(collider.bounds.extents.x * wallErrorThreshold, 0),
|
|
LayerMask.GetMask(LayerNames.Ground));
|
|
var leftHit = Physics2D.Linecast(position,
|
|
position - new Vector2(collider.bounds.extents.x * wallErrorThreshold, 0),
|
|
LayerMask.GetMask(LayerNames.Ground));
|
|
|
|
return ((rightHit.collider != null && rightHit.collider.IsTouching(collider)) ||
|
|
(leftHit.collider != null && leftHit.collider.IsTouching(collider))) && (!IsPlayerOnGround() || ignoreGround);
|
|
}
|
|
|
|
private bool HasEncounteredEnemy()
|
|
{
|
|
return rigidBody.IsTouchingLayers(LayerMask.GetMask(LayerNames.Enemies));
|
|
}
|
|
|
|
private void FlipSprite()
|
|
{
|
|
if (Mathf.Abs(rigidBody.velocity.x) > runErrorThreshold && (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.LeftArrow)))
|
|
{
|
|
transform.localScale = new Vector2(Mathf.Sign(rigidBody.velocity.x), 1f);
|
|
}
|
|
}
|
|
|
|
private void HandleAnimations()
|
|
{
|
|
animator.SetBool("IsRunning", Mathf.Abs(rigidBody.velocity.x) > runErrorThreshold);
|
|
animator.SetBool("IsGround", IsPlayerOnGround());
|
|
animator.SetFloat("YVelocity", rigidBody.velocity.y);
|
|
animator.SetBool("IsFighting", isFighting);
|
|
animator.SetBool("IsHurt", isHurt);
|
|
}
|
|
|
|
private void PlayFightSound()
|
|
{
|
|
if (isFighting && !isPlayerHurt)
|
|
{
|
|
if (fightSoundAccumalator >= fightSoundLength)
|
|
{
|
|
SoundManagerScript.PlaySound(GetRandomFightClipName());
|
|
fightSoundAccumalator = 0;
|
|
}
|
|
else
|
|
{
|
|
fightSoundAccumalator++;
|
|
}
|
|
}
|
|
}
|
|
|
|
private string GetRandomFightClipName()
|
|
{
|
|
var fightClipNames = new List<string> { "punch", "hard punch", "slap", "hard slap" };
|
|
var randomNumber = UnityEngine.Random.Range(0, fightClipNames.Count);
|
|
return fightClipNames[randomNumber];
|
|
}
|
|
|
|
public void StartEncounter()
|
|
{
|
|
isPlayerHurt = false;
|
|
isFighting = true;
|
|
isMovementEnabled = false;
|
|
rigidBody.gravityScale = 0f;
|
|
rigidBody.velocity = Vector2.zero;
|
|
}
|
|
|
|
public void EndEncounter()
|
|
{
|
|
isPlayerHurt = false;
|
|
isFighting = false;
|
|
isMovementEnabled = true;
|
|
rigidBody.gravityScale = 1f;
|
|
DecreaseStaminaAfterBugFight();
|
|
}
|
|
|
|
public void ThrowUserInTheAirHurt()
|
|
{
|
|
isPlayerHurt = true;
|
|
GetComponent<Rigidbody2D>().velocity += new Vector2(Mathf.Sign(transform.localScale.x) * -1 * hurtVelocity, hurtVelocity);
|
|
isFighting = false;
|
|
isHurt = true;
|
|
Hurt();
|
|
}
|
|
|
|
public float GetStaminaDifficultyFactor()
|
|
{
|
|
return Mathf.Clamp(currentStamina / (startStamina * 1f), 0.1f, 1);
|
|
}
|
|
}
|