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(); canvasManager = FindObjectOfType(); } // 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(); KnightController knight = col.gameObject.GetComponent(); PawnController pawn = col.gameObject.GetComponent(); RookController rook = col.gameObject.GetComponent(); 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); } } }