399 lines
17 KiB
C#
399 lines
17 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.Rendering;
|
|
|
|
[System.Serializable] public class Move : UnityEvent { }
|
|
|
|
public class PlayerController : MonoBehaviour{
|
|
|
|
[SerializeField] GameObject deathParticles;
|
|
[SerializeField] GameObject visualContainer;
|
|
bool dead;
|
|
[HideInInspector] public Move onMove;
|
|
bool canMove = true;
|
|
bool isWinding;
|
|
|
|
[Range(0f, .3f)] [SerializeField] float movementSmoothingTime;
|
|
[HideInInspector] public Vector3 positionToGo;
|
|
Vector3 currentPosition;
|
|
Vector3 velocity;
|
|
|
|
Vector2 movementInput;
|
|
bool hasMoved;
|
|
bool moveAllowed;
|
|
|
|
Animator anim;
|
|
|
|
[SerializeField] LayerMask whatIsEnemy;
|
|
|
|
[Space]
|
|
bool alreadyBeenDamaged;
|
|
bool lowHealth;
|
|
[SerializeField] Volume damageVolume;
|
|
[SerializeField] Volume lowHealthVolume;
|
|
[SerializeField] int health = 9;
|
|
[SerializeField] GameObject[] hearts;
|
|
|
|
[SerializeField] GameOverCanvas gameOverCanvas;
|
|
CanvasManager canvasManager;
|
|
int movementsDone;
|
|
int enemiesKilled;
|
|
|
|
void Awake(){
|
|
anim = GetComponent<Animator>();
|
|
canvasManager = FindObjectOfType<CanvasManager>();
|
|
}
|
|
|
|
// Start is called before the first frame update
|
|
void Start(){
|
|
positionToGo = currentPosition = transform.position;
|
|
}
|
|
|
|
public void SetDifficulty(){
|
|
moveAllowed = canvasManager.difficulty != CanvasManager.CanvasDifficulty.Hard;
|
|
if (!moveAllowed){
|
|
canvasManager.onHardMoveIn.AddListener(() => AllowHardMovment());
|
|
canvasManager.onHardMoveOut.AddListener(() => DenyHardMovement());
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update(){
|
|
movementInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
|
|
|
|
if (moveAllowed){
|
|
if (canMove && !isWinding && !dead){
|
|
if (movementInput == Vector2.zero){
|
|
hasMoved = false;
|
|
}else if (movementInput != Vector2.zero && !hasMoved){
|
|
StartCoroutine(GetMovementDirection());
|
|
hasMoved = true;
|
|
canMove = false;
|
|
}
|
|
}
|
|
}
|
|
if(Vector3.Distance(transform.position, positionToGo) > .1f){
|
|
transform.position = Vector3.SmoothDamp(transform.position, positionToGo, ref velocity, movementSmoothingTime);
|
|
}else if(Vector3.Distance(transform.position, positionToGo) < .1f){
|
|
transform.position = positionToGo;
|
|
}
|
|
|
|
damageVolume.weight -= Time.deltaTime;
|
|
if (lowHealth){
|
|
lowHealthVolume.weight = Mathf.PingPong(Time.time, 1);
|
|
}
|
|
|
|
if (health <= 0 && !dead){
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
canvasManager.dead = true;
|
|
|
|
hearts[0].SetActive(false);
|
|
lowHealth = false;
|
|
lowHealthVolume.weight = 0;
|
|
|
|
gameOverCanvas.movementsDone = movementsDone;
|
|
gameOverCanvas.enemiesKilled = enemiesKilled;
|
|
gameOverCanvas.gameObject.SetActive(true);
|
|
|
|
visualContainer.SetActive(false);
|
|
Instantiate(deathParticles, transform.position + Vector3.up, Quaternion.identity);
|
|
dead = true;
|
|
}
|
|
}
|
|
|
|
IEnumerator GetMovementDirection(){
|
|
movementsDone += 1;
|
|
if(canvasManager.difficulty == CanvasManager.CanvasDifficulty.Hard){
|
|
moveAllowed = false;
|
|
}
|
|
|
|
alreadyBeenDamaged = false;
|
|
|
|
if(movementInput.x > 0){
|
|
yield return new WaitForSeconds(.1f);
|
|
if (movementInput.y > 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(1.25f, 0, 0);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if(cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else if(movementInput.y < 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(0, 0, -1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else{
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(1.25f, 0, -1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
anim.SetTrigger("Moving");
|
|
onMove.Invoke();
|
|
yield return new WaitForSeconds(.2f);
|
|
canMove = true;
|
|
}else if(movementInput.x < 0){
|
|
yield return new WaitForSeconds(.1f);
|
|
if (movementInput.y > 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(0, 0, 1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else if (movementInput.y < 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(-1.25f, 0, 0);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else{
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(-1.25f, 0, 1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
anim.SetTrigger("Moving");
|
|
onMove.Invoke();
|
|
yield return new WaitForSeconds(.2f);
|
|
canMove = true;
|
|
}else{
|
|
if (movementInput.y > 0){
|
|
yield return new WaitForSeconds(.1f);
|
|
if (movementInput.x > 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(1.25f, 0, 0);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else if (movementInput.x < 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(0, 0, 1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else{
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(1.25f, 0, 1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
anim.SetTrigger("Moving");
|
|
onMove.Invoke();
|
|
yield return new WaitForSeconds(.2f);
|
|
canMove = true;
|
|
}else if(movementInput.y < 0){
|
|
yield return new WaitForSeconds(.1f);
|
|
if (movementInput.x > 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(0, 0, -1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else if (movementInput.x < 0){
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(-1.25f, 0, 0);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}else{
|
|
currentPosition = positionToGo;
|
|
positionToGo = currentPosition + new Vector3(-1.25f, 0, -1.25f);
|
|
Collider[] cols = Physics.OverlapSphere(positionToGo, .3f, whatIsEnemy);
|
|
if (cols.Length != 0){
|
|
yield return new WaitForSeconds(.05f);
|
|
ObjectPooler.instance.SpawnFromPool("EnemyDeath", new Vector3(positionToGo.x, 1, positionToGo.z), Quaternion.identity);
|
|
PlayYesOrYeah();
|
|
AudioManager.instance.PlayOneShot("Death", true);
|
|
enemiesKilled += 1;
|
|
cols[0].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
anim.SetTrigger("Moving");
|
|
onMove.Invoke();
|
|
yield return new WaitForSeconds(.2f);
|
|
canMove = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PlayYesOrYeah(){
|
|
float canRandomPlay = Random.Range(0, 100);
|
|
if (canRandomPlay > 20 && canRandomPlay < 80){
|
|
float whichPlay = Random.Range(0, 100);
|
|
if (whichPlay > 50){
|
|
AudioManager.instance.Play("Yes", true);
|
|
}else{
|
|
AudioManager.instance.Play("Yeah", true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void PlayMoveSoundRandomPitch(){
|
|
AudioManager.instance.Play("PlayerStep", true);
|
|
}
|
|
|
|
public void StartWind(){
|
|
currentPosition = positionToGo;
|
|
isWinding = true;
|
|
alreadyBeenDamaged = false;
|
|
}
|
|
|
|
public void MoveWind(Vector3 direction, int grids){
|
|
positionToGo = transform.position + direction * grids;
|
|
AudioManager.instance.Play("WindMove", true);
|
|
}
|
|
|
|
public void EndWind(){
|
|
isWinding = false;
|
|
}
|
|
|
|
public void Damage(){
|
|
if (!alreadyBeenDamaged){
|
|
if (health > 0){
|
|
hearts[health - 1].SetActive(false);
|
|
health--;
|
|
if (health <= 3){
|
|
lowHealth = true;
|
|
}
|
|
if (health > 1){
|
|
damageVolume.weight = 1;
|
|
}
|
|
|
|
alreadyBeenDamaged = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnCollisionEnter(Collision col){
|
|
if (col.gameObject.layer == Mathf.RoundToInt(Mathf.Log(whatIsEnemy.value, 2)) && isWinding){
|
|
BishopController bishop = col.gameObject.GetComponent<BishopController>();
|
|
KnightController knight = col.gameObject.GetComponent<KnightController>();
|
|
PawnController pawn = col.gameObject.GetComponent<PawnController>();
|
|
RookController rook = col.gameObject.GetComponent<RookController>();
|
|
if (bishop != null){
|
|
if (bishop.positionToGo == positionToGo){
|
|
positionToGo = currentPosition;
|
|
Damage();
|
|
}
|
|
}else if (knight != null){
|
|
if (knight.positionToGo == positionToGo){
|
|
positionToGo = currentPosition;
|
|
Damage();
|
|
}
|
|
}else if (pawn != null){
|
|
if (pawn.positionToGo == positionToGo){
|
|
positionToGo = currentPosition;
|
|
Damage();
|
|
}
|
|
}else if (rook != null){
|
|
if (rook.positionToGo == positionToGo){
|
|
positionToGo = currentPosition;
|
|
Damage();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void AllowHardMovment(){
|
|
moveAllowed = true;
|
|
}
|
|
|
|
void DenyHardMovement(){
|
|
if (moveAllowed){
|
|
onMove.Invoke();
|
|
moveAllowed = false;
|
|
}
|
|
}
|
|
|
|
void OnTriggerEnter(Collider col){
|
|
if (col.CompareTag("Limits")){
|
|
positionToGo = currentPosition;
|
|
}
|
|
}
|
|
|
|
void OnDrawGizmos(){
|
|
if (!Application.isPlaying){
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(0, 0, 1.25f), .3f);
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(0, 0, -1.25f), .3f);
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(1.25f, 0, 1.25f), .3f);
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(1.25f, 0, -1.25f), .3f);
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(1.25f, 0, 0), .3f);
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(-1.25f, 0, 1.25f), .3f);
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(-1.25f, 0, -1.25f), .3f);
|
|
Gizmos.DrawWireSphere(transform.position + new Vector3(-1.25f, 0, 0), .3f);
|
|
}
|
|
}
|
|
}
|