217 lines
9.1 KiB
C#
217 lines
9.1 KiB
C#
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<Animator>();
|
|
FindObjectOfType<GameController>().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<PortalBullet>().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<PortalBullet>().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<PortalBullet>().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<PortalBullet>().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<PortalBullet>().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<GameController>().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);
|
|
}
|
|
}
|