using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.Events; [System.Serializable] public class OnDie : UnityEvent { } public class PlayerController : MonoBehaviour{ [HideInInspector] public OnDie onDie; [SerializeField] int numberOfLifes = 3; [SerializeField] TextMeshProUGUI lifesText = default; public int numberOfBombs = 0; [SerializeField] TextMeshProUGUI bombsText = default; public int numberOfCharge = 1; [SerializeField] TextMeshProUGUI chargeText = default; [Space] [SerializeField] float speed = 5; [SerializeField] LayerMask whatIsWall = -1; Vector3 targetPosition; [SerializeField, Range(0, .2f)] float rotationTime = .1f; float targetAngle; float rotationVelocity; [Space] [SerializeField] LayerMask whereCannotSpawnBombs = -1; [Space] [SerializeField] Transform verticalPortals = default; [SerializeField] Transform horizontalPortals = default; Vector2 lookDirection; Vector2 lastPressed; [HideInInspector] public bool canShoot = true; bool teleporting; bool canMove; [SerializeField] GameObject explosion = default; Animator anim; bool dead; void Awake(){ anim = GetComponent(); FindObjectOfType().onStart.AddListener(() => GameStart()); } // Start is called before the first frame update void Start(){ lookDirection = Vector2.up; targetPosition = transform.position; verticalPortals.gameObject.SetActive(false); horizontalPortals.gameObject.SetActive(false); } public void Respawn(){ anim.SetBool("Dead", false); dead = false; lookDirection = Vector2.up; targetPosition = transform.position; verticalPortals.gameObject.SetActive(false); horizontalPortals.gameObject.SetActive(false); } float timeSurvived; bool alreadyDead; // Update is called once per frame void Update(){ if (!dead){ timeSurvived += Time.deltaTime; }else{ GameOverCanvas.instance.timeSurvived = timeSurvived; } if (!teleporting && canMove && !dead){ transform.position = Vector3.MoveTowards(transform.position, new Vector3(targetPosition.x, transform.position.y, targetPosition.z), speed * Time.deltaTime); if(targetPosition == new Vector3(transform.position.x, targetPosition.y, transform.position.z)){ if (!CheckCollision(new Vector3(lookDirection.x, 0, lookDirection.y))){ if(!CheckCollision(new Vector3(lastPressed.x, 0, lastPressed.y)) && lastPressed != Vector2.zero){ lookDirection = lastPressed; targetPosition += new Vector3(lookDirection.x, 0, lookDirection.y); targetAngle = Mathf.Atan2(1 * lookDirection.x, 1 * lookDirection.y) * Mathf.Rad2Deg; lastPressed = Vector2.zero; }else{ targetPosition += new Vector3(lookDirection.x, 0, lookDirection.y); } }else if(!CheckCollision(new Vector3(lastPressed.x, 0, lastPressed.y)) && lastPressed != Vector2.zero){ lookDirection = lastPressed; targetPosition += new Vector3(lookDirection.x, 0, lookDirection.y); targetAngle = Mathf.Atan2(1 * lookDirection.x, 1 * lookDirection.y) * Mathf.Rad2Deg; lastPressed = Vector2.zero; }else{ lastPressed = Vector2.zero; } } } Vector2 axisDirection = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")); if(axisDirection.magnitude > .1f && !teleporting && canMove && !dead){ if(axisDirection.x != 0 && axisDirection.x == -lookDirection.x || axisDirection.x != 0 && (lookDirection == Vector2.up || lookDirection == Vector2.down)){ lastPressed = Vector2.right * axisDirection.x; } if (axisDirection.y != 0 && axisDirection.y == -lookDirection.y || axisDirection.y != 0 && (lookDirection == Vector2.right || lookDirection == Vector2.left)){ lastPressed = Vector2.up * axisDirection.y; } } if (Input.GetMouseButtonDown(1) && canShoot && canMove && numberOfCharge > 0 && !dead && !alreadyDead){ horizontalPortals.gameObject.SetActive(false); verticalPortals.gameObject.SetActive(false); AudioManager.instance.PlayOneShot("Bullet"); if (lookDirection == Vector2.right){ GameObject bullet = ObjectPooler.instance.SpawnFromPool("Bullet", transform.position + Vector3.right, Quaternion.Euler(55, 0, 0)); bullet.GetComponent().SetImportantThings(verticalPortals, horizontalPortals, Vector3.right, targetPosition, this); }else if (lookDirection == Vector2.left){ GameObject bullet = ObjectPooler.instance.SpawnFromPool("Bullet", transform.position + Vector3.left, Quaternion.Euler(55, 0, 0)); bullet.GetComponent().SetImportantThings(verticalPortals, horizontalPortals, Vector3.left, targetPosition, this); }else if (lookDirection == Vector2.up){ GameObject bullet = ObjectPooler.instance.SpawnFromPool("Bullet", transform.position + Vector3.forward, Quaternion.Euler(55, 0, 0)); bullet.GetComponent().SetImportantThings(verticalPortals, horizontalPortals, Vector3.forward, targetPosition, this); }else if (lookDirection == Vector2.down){ GameObject bullet = ObjectPooler.instance.SpawnFromPool("Bullet", transform.position + Vector3.back, Quaternion.Euler(55, 0, 0)); bullet.GetComponent().SetImportantThings(verticalPortals, horizontalPortals, Vector3.back, targetPosition, this); }else{ GameObject bullet = ObjectPooler.instance.SpawnFromPool("Bullet", transform.position + Vector3.forward, Quaternion.Euler(55, 0, 0)); bullet.GetComponent().SetImportantThings(verticalPortals, horizontalPortals, Vector3.forward, targetPosition, this); } horizontalPortals.position = new Vector3(horizontalPortals.position.x, horizontalPortals.position.y, targetPosition.z); verticalPortals.position = new Vector3(targetPosition.x, verticalPortals.position.y, verticalPortals.position.z); canShoot = false; numberOfCharge--; } float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref rotationVelocity, rotationTime); transform.rotation = Quaternion.Euler(0f, angle, 0f); if (Input.GetMouseButtonDown(0) && canMove && numberOfBombs > 0 && !dead && !alreadyDead){ if (!Physics.CheckSphere(new Vector3(targetPosition.x, transform.position.y - .5f, targetPosition.z), .3f, whereCannotSpawnBombs)){ ObjectPooler.instance.SpawnFromPool("Bomb", new Vector3(targetPosition.x, transform.position.y - .5f, targetPosition.z), Quaternion.identity); AudioManager.instance.PlayOneShot("DropBomb"); numberOfBombs--; } } chargeText.text = "x" + numberOfCharge; bombsText.text = "x" + numberOfBombs; lifesText.text = "x" + numberOfLifes; } public void Teleport(Vector3 position){ teleporting = true; targetPosition = new Vector3(position.x, transform.position.y, position.z); StartCoroutine(StopTeleporting()); AudioManager.instance.PlayOneShot("PortalEnter"); } void GameStart(){ canMove = true; } IEnumerator Damage(){ dead = true; ScreenShakeCall.instance.ShakeCamera(10f, .8f); Instantiate(explosion, transform.position, Quaternion.identity); anim.SetBool("Dead", true); AudioManager.instance.PlayWithRandomPitch("Explode"); yield return new WaitForSeconds(1f); if(numberOfLifes == 1){ AudioManager.instance.Stop("Main"); onDie.Invoke(); GameOverCanvas.instance.Lose(); alreadyDead = true; numberOfLifes--; }else if (numberOfLifes > 1){ numberOfLifes--; } FindObjectOfType().PlayerDeath(this); AudioManager.instance.Play("Death"); } void OnTriggerEnter(Collider col){ if (col.CompareTag("Explosion")){ if (dead) return; StartCoroutine(Damage()); } } void OnCollisionEnter(Collision col){ if (col.gameObject.tag == "Enemy"){ if (dead) return; StartCoroutine(Damage()); } } IEnumerator StopTeleporting(){ yield return new WaitForSeconds(.1f); transform.position = targetPosition; yield return new WaitForSeconds(.1f); teleporting = false; } bool CheckCollision(Vector3 dir){ return Physics.Raycast(transform.position, dir, 1, whatIsWall); } }