init
This commit is contained in:
commit
3b4c6e0ec6
506 changed files with 434142 additions and 0 deletions
8
Assets/Scripts/AudioManager.meta
Normal file
8
Assets/Scripts/AudioManager.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: deba05c3348cf404bb0ba0a77380267a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
71
Assets/Scripts/AudioManager/AudioManager.cs
Normal file
71
Assets/Scripts/AudioManager/AudioManager.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
public class AudioManager : MonoBehaviour{
|
||||
|
||||
[SerializeField] Sound[] sounds = default;
|
||||
|
||||
public static AudioManager instance;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Awake(){
|
||||
if(instance == null){
|
||||
instance = this;
|
||||
}else{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
foreach(Sound s in sounds){
|
||||
s.source = gameObject.AddComponent<AudioSource>();
|
||||
s.source.clip = s.clip;
|
||||
|
||||
s.source.volume = s.volume;
|
||||
s.source.pitch = s.pitch;
|
||||
s.source.loop = s.loop;
|
||||
}
|
||||
}
|
||||
|
||||
public void Play(string name){
|
||||
Sound s = Array.Find(sounds, sound => sound.name == name);
|
||||
if (s == null){
|
||||
Debug.LogWarning("Sound: " + name + " not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
s.source.Play();
|
||||
}
|
||||
|
||||
public void PlayOneShot(string name){
|
||||
Sound s = Array.Find(sounds, sound => sound.name == name);
|
||||
if (s == null){
|
||||
Debug.LogWarning("Sound: " + name + " not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
s.source.PlayOneShot(s.clip);
|
||||
}
|
||||
|
||||
public void Stop(string name){
|
||||
Sound s = Array.Find(sounds, sound => sound.name == name);
|
||||
if (s == null){
|
||||
Debug.LogWarning("Sound: " + name + " not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
s.source.Stop();
|
||||
}
|
||||
|
||||
public void PlayWithRandomPitch(string name){
|
||||
Sound s = Array.Find(sounds, sound => sound.name == name);
|
||||
if (s == null){
|
||||
Debug.LogWarning("Sound: " + name + " not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
s.source.volume = s.volume * (1f + UnityEngine.Random.Range(-s.volumeVariance / 2f, s.volumeVariance / 2f));
|
||||
s.source.pitch = s.pitch * (1f + UnityEngine.Random.Range(-s.pitchVariance / 2f, s.pitchVariance / 2f));
|
||||
s.source.PlayOneShot(s.clip);
|
||||
}
|
||||
}
|
11
Assets/Scripts/AudioManager/AudioManager.cs.meta
Normal file
11
Assets/Scripts/AudioManager/AudioManager.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a6ad4d560a5e7c24480d454ea82006f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
17
Assets/Scripts/AudioManager/Sound.cs
Normal file
17
Assets/Scripts/AudioManager/Sound.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class Sound{
|
||||
public string name;
|
||||
|
||||
public AudioClip clip;
|
||||
|
||||
[Range(0f, 1f)] public float volume;
|
||||
[Range(0f, 1f)] public float volumeVariance;
|
||||
[Range(.1f, 3f)] public float pitch;
|
||||
[Range(0f, 1f)] public float pitchVariance;
|
||||
|
||||
public bool loop;
|
||||
|
||||
[HideInInspector] public AudioSource source;
|
||||
}
|
11
Assets/Scripts/AudioManager/Sound.cs.meta
Normal file
11
Assets/Scripts/AudioManager/Sound.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 42f73f4d81953754c96cc4e7a2a7bed5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
77
Assets/Scripts/BombController.cs
Normal file
77
Assets/Scripts/BombController.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
using Cinemachine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BombController : MonoBehaviour, IPooledObject{
|
||||
|
||||
[SerializeField, Range(0, 5f)] float timeToExplode = 1.5f;
|
||||
float currentTime;
|
||||
[SerializeField, Range(1, 10)] int maxDistance = 5;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, .3f)] float timeBetweenExplosions = .05f;
|
||||
bool exploded;
|
||||
|
||||
[SerializeField] LayerMask whatIsWall = -1;
|
||||
bool canRightSpawn, canLeftSpawn, canForwardSpawn, canBackSpawn;
|
||||
|
||||
public void OnObjectSpawn(){
|
||||
currentTime = 0;
|
||||
exploded = false;
|
||||
canRightSpawn = canLeftSpawn = canForwardSpawn = canBackSpawn = true;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update(){
|
||||
currentTime += Time.deltaTime;
|
||||
if(currentTime >= timeToExplode && !exploded){
|
||||
StartCoroutine(Explode());
|
||||
ScreenShakeCall.instance.ShakeCamera(10f, .4f);
|
||||
exploded = true;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator Explode(){
|
||||
for (int i = 0; i < maxDistance; i++){
|
||||
yield return new WaitForSeconds(timeBetweenExplosions);
|
||||
if (i == 0){
|
||||
ObjectPooler.instance.SpawnFromPool("Explosion", transform.position, Quaternion.identity);
|
||||
}else{
|
||||
if(!Physics.CheckSphere(transform.position + Vector3.right * i, .3f, whatIsWall) && canRightSpawn){
|
||||
ObjectPooler.instance.SpawnFromPool("Explosion", transform.position + Vector3.right * i, Quaternion.identity);
|
||||
}else{
|
||||
canRightSpawn = false;
|
||||
}
|
||||
|
||||
if (!Physics.CheckSphere(transform.position + Vector3.left * i, .3f, whatIsWall) && canLeftSpawn){
|
||||
ObjectPooler.instance.SpawnFromPool("Explosion", transform.position + Vector3.left * i, Quaternion.identity);
|
||||
}else{
|
||||
canLeftSpawn = false;
|
||||
}
|
||||
|
||||
if (!Physics.CheckSphere(transform.position + Vector3.forward * i, .3f, whatIsWall) && canForwardSpawn){
|
||||
ObjectPooler.instance.SpawnFromPool("Explosion", transform.position + Vector3.forward * i, Quaternion.identity);
|
||||
}else{
|
||||
canForwardSpawn = false;
|
||||
}
|
||||
|
||||
if (!Physics.CheckSphere(transform.position + Vector3.back * i, .3f, whatIsWall) && canBackSpawn){
|
||||
ObjectPooler.instance.SpawnFromPool("Explosion", transform.position + Vector3.back * i, Quaternion.identity);
|
||||
}else{
|
||||
canBackSpawn = false;
|
||||
}
|
||||
}
|
||||
AudioManager.instance.PlayWithRandomPitch("Explode");
|
||||
}
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawLine(transform.position, transform.position + Vector3.right * maxDistance);
|
||||
Gizmos.DrawLine(transform.position, transform.position + Vector3.left * maxDistance);
|
||||
Gizmos.DrawLine(transform.position, transform.position + Vector3.forward * maxDistance);
|
||||
Gizmos.DrawLine(transform.position, transform.position + Vector3.back * maxDistance);
|
||||
}
|
||||
}
|
11
Assets/Scripts/BombController.cs.meta
Normal file
11
Assets/Scripts/BombController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f2353ab88c05d124b9ccfd9cebf58df0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
38
Assets/Scripts/BombSpawner.cs
Normal file
38
Assets/Scripts/BombSpawner.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BombSpawner : MonoBehaviour{
|
||||
|
||||
[SerializeField, Range(1, 10)] float spawnRate = 5f;
|
||||
float currentTime;
|
||||
|
||||
[SerializeField] GameObject bomb = default;
|
||||
|
||||
SphereCollider col;
|
||||
PlayerController player;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Awake(){
|
||||
col = GetComponent<SphereCollider>();
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update(){
|
||||
currentTime -= Time.deltaTime;
|
||||
if(currentTime <= 0){
|
||||
col.enabled = true;
|
||||
bomb.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if(col.CompareTag("Player")){
|
||||
currentTime = spawnRate;
|
||||
this.col.enabled = false;
|
||||
bomb.SetActive(false);
|
||||
player.numberOfBombs++;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/BombSpawner.cs.meta
Normal file
11
Assets/Scripts/BombSpawner.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 27c73ea4a98056f4082879e332cd9b2f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
30
Assets/Scripts/CoinController.cs
Normal file
30
Assets/Scripts/CoinController.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class CoinController : MonoBehaviour{
|
||||
|
||||
GameController gameController;
|
||||
[SerializeField] GameObject child = default;
|
||||
|
||||
void Awake(){
|
||||
gameController = FindObjectOfType<GameController>();
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if (col.CompareTag("Player") || col.CompareTag("Explosion")){
|
||||
GetComponent<SphereCollider>().enabled = false;
|
||||
gameController.PlayButtonScale();
|
||||
gameController.numberOfCoins--;
|
||||
child.SetActive(true);
|
||||
GameOverCanvas.instance.tilesEnabled++;
|
||||
ObjectPooler.instance.SpawnFromPool("Light", new Vector3(transform.position.x, 0, transform.position.z), Quaternion.identity);
|
||||
}
|
||||
}
|
||||
|
||||
public void Disable(){
|
||||
if(GetComponent<SphereCollider>().enabled == true){
|
||||
child.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/CoinController.cs.meta
Normal file
11
Assets/Scripts/CoinController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ee0cf260523b1bc438ab7b65ee096400
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
307
Assets/Scripts/EnemyController.cs
Normal file
307
Assets/Scripts/EnemyController.cs
Normal file
|
@ -0,0 +1,307 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class EnemyController : MonoBehaviour {
|
||||
|
||||
[SerializeField, Range(0, 2)] int angryLevel = 0;
|
||||
[SerializeField] float[] speedLevels = new float[3];
|
||||
[SerializeField] SkinnedMeshRenderer meshRenderer = default;
|
||||
[SerializeField] Animator enemyAnimator = default;
|
||||
|
||||
[Space]
|
||||
[SerializeField] Material defaultMat = default;
|
||||
[SerializeField] Material angryMat = default;
|
||||
[SerializeField] Material reallyAngryMat = default;
|
||||
|
||||
[SerializeField] Material defaultAttackMat = default;
|
||||
[SerializeField] Material angryAttackMat = default;
|
||||
[SerializeField] Material reallyAngryAttackMat = default;
|
||||
|
||||
[Space]
|
||||
[SerializeField] float speed = 5f;
|
||||
[HideInInspector] public Vector3 directionLooking = Vector3.forward;
|
||||
|
||||
[SerializeField, Range(0, .2f)] float rotationTime = .1f;
|
||||
[HideInInspector] public float targetAngle;
|
||||
float rotationVelocity;
|
||||
|
||||
[SerializeField] LayerMask whatIsWall = -1;
|
||||
|
||||
Vector3 currentPosition;
|
||||
List<Vector3> possiblePositions;
|
||||
List<Vector3> availablePositions;
|
||||
[HideInInspector] public Vector3 positionToGo;
|
||||
|
||||
Transform player;
|
||||
bool dead;
|
||||
[HideInInspector] public bool canMove;
|
||||
|
||||
GameController gameController;
|
||||
|
||||
void Awake(){
|
||||
PlayerController playerController = FindObjectOfType<PlayerController>();
|
||||
player = playerController.transform;
|
||||
playerController.onDie.AddListener(() => OnPlayerDie());
|
||||
gameController = FindObjectOfType<GameController>();
|
||||
}
|
||||
|
||||
void Start(){
|
||||
positionToGo = currentPosition = transform.position;
|
||||
speed = speedLevels[angryLevel];
|
||||
}
|
||||
|
||||
public void OnPlayerDie(){
|
||||
positionToGo = currentPosition = transform.position;
|
||||
switch (angryLevel){
|
||||
case 0:
|
||||
meshRenderer.material = defaultMat;
|
||||
break;
|
||||
case 1:
|
||||
meshRenderer.material = angryMat;
|
||||
break;
|
||||
case 2:
|
||||
meshRenderer.material = reallyAngryMat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void EnterRespawn(){
|
||||
switch (angryLevel){
|
||||
case 0:
|
||||
angryLevel = 1;
|
||||
break;
|
||||
case 1:
|
||||
angryLevel = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (angryLevel){
|
||||
case 0:
|
||||
meshRenderer.material = defaultMat;
|
||||
break;
|
||||
case 1:
|
||||
meshRenderer.material = angryMat;
|
||||
break;
|
||||
case 2:
|
||||
meshRenderer.material = reallyAngryMat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Respawn(){
|
||||
positionToGo = currentPosition = transform.position;
|
||||
dead = false;
|
||||
speed = speedLevels[angryLevel];
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update(){
|
||||
enemyAnimator.SetBool("Attacking", !dead && canMove);
|
||||
|
||||
if (!dead && canMove){
|
||||
switch (angryLevel){
|
||||
case 0:
|
||||
meshRenderer.material = defaultAttackMat;
|
||||
break;
|
||||
case 1:
|
||||
meshRenderer.material = angryAttackMat;
|
||||
break;
|
||||
case 2:
|
||||
meshRenderer.material = reallyAngryAttackMat;
|
||||
break;
|
||||
}
|
||||
|
||||
if (transform.position == positionToGo){
|
||||
CalculateDirection();
|
||||
}
|
||||
|
||||
transform.position = Vector3.MoveTowards(transform.position, new Vector3(positionToGo.x, transform.position.y, positionToGo.z), speed * Time.deltaTime);
|
||||
|
||||
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref rotationVelocity, rotationTime);
|
||||
transform.rotation = Quaternion.Euler(0f, angle, 0f);
|
||||
}
|
||||
else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateDirection(){
|
||||
currentPosition = transform.position;
|
||||
|
||||
possiblePositions = new List<Vector3>();
|
||||
|
||||
Vector3 forward = Vector3.forward;
|
||||
Vector3 back = Vector3.back;
|
||||
Vector3 left = Vector3.left;
|
||||
Vector3 right = Vector3.right;
|
||||
|
||||
if (forward == -directionLooking){
|
||||
possiblePositions.Add(Vector3.back);
|
||||
possiblePositions.Add(Vector3.left);
|
||||
possiblePositions.Add(Vector3.right);
|
||||
}else if (back == -directionLooking){
|
||||
possiblePositions.Add(Vector3.forward);
|
||||
possiblePositions.Add(Vector3.left);
|
||||
possiblePositions.Add(Vector3.right);
|
||||
}else if (left == -directionLooking){
|
||||
possiblePositions.Add(Vector3.back);
|
||||
possiblePositions.Add(Vector3.forward);
|
||||
possiblePositions.Add(Vector3.right);
|
||||
}else if (right == -directionLooking){
|
||||
possiblePositions.Add(Vector3.back);
|
||||
possiblePositions.Add(Vector3.left);
|
||||
possiblePositions.Add(Vector3.forward);
|
||||
}
|
||||
|
||||
availablePositions = new List<Vector3>();
|
||||
foreach(Vector3 pos in possiblePositions){
|
||||
if(directionLooking == Vector3.forward || directionLooking == Vector3.back){
|
||||
if(pos == Vector3.right){
|
||||
if(player.position.x > transform.position.x){
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
|
||||
availablePositions.Add(directionLooking);
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(pos == Vector3.left){
|
||||
if (player.position.x < transform.position.x){
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
|
||||
availablePositions.Add(directionLooking);
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if (pos == Vector3.forward){
|
||||
if (player.position.z > transform.position.z){
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
|
||||
availablePositions.Add(directionLooking);
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if (pos == Vector3.back){
|
||||
if (player.position.z < transform.position.z){
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + directionLooking, .3f, whatIsWall)){
|
||||
availablePositions.Add(directionLooking);
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if (!Physics.CheckSphere(transform.position + pos, .3f, whatIsWall)){
|
||||
availablePositions.Add(pos);
|
||||
}*/
|
||||
}
|
||||
|
||||
float nearestDist = float.MaxValue;
|
||||
Vector3 nearestPos = new Vector3();
|
||||
|
||||
foreach (Vector3 v in availablePositions){
|
||||
if (v != Vector3.zero){
|
||||
float dist = Vector3.Distance(currentPosition + v, player.position);
|
||||
if (dist < nearestDist){
|
||||
nearestDist = dist;
|
||||
nearestPos = currentPosition + v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(nearestPos - currentPosition == Vector3.left){
|
||||
targetAngle = Mathf.Atan2(-1, 0) * Mathf.Rad2Deg;
|
||||
}else if (nearestPos - currentPosition == Vector3.right){
|
||||
targetAngle = Mathf.Atan2(1, 0) * Mathf.Rad2Deg;
|
||||
}else if (nearestPos - currentPosition == Vector3.forward){
|
||||
targetAngle = Mathf.Atan2(0, 1) * Mathf.Rad2Deg;
|
||||
}else if (nearestPos - currentPosition == Vector3.back){
|
||||
targetAngle = Mathf.Atan2(0, -1) * Mathf.Rad2Deg;
|
||||
}
|
||||
|
||||
directionLooking = nearestPos - currentPosition;
|
||||
|
||||
positionToGo = nearestPos;
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
Vector3 forward = Vector3.forward;
|
||||
Vector3 back = Vector3.back;
|
||||
Vector3 left = Vector3.left;
|
||||
Vector3 right = Vector3.right;
|
||||
|
||||
if(forward == -directionLooking){
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
|
||||
}else if(back == -directionLooking){
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
|
||||
}else if (left == -directionLooking){
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
|
||||
}else if (right == -directionLooking){
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.right, .15f);
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawSphere(transform.position + Vector3.back, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.left, .15f);
|
||||
Gizmos.DrawSphere(transform.position + Vector3.forward, .15f);
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if(col.gameObject.tag == "Explosion"){
|
||||
AudioManager.instance.PlayOneShot("EnemyDeath");
|
||||
GameOverCanvas.instance.enemiesKilled++;
|
||||
dead = true;
|
||||
canMove = false;
|
||||
gameController.EnemyDeath(this);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/EnemyController.cs.meta
Normal file
11
Assets/Scripts/EnemyController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e47f88b86432ef549a65f364b3382025
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
33
Assets/Scripts/ExplosionController.cs
Normal file
33
Assets/Scripts/ExplosionController.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ExplosionController : MonoBehaviour, IPooledObject{
|
||||
|
||||
float currentTime;
|
||||
[SerializeField, Range(0, 3)] float timeToDisappear = 1f;
|
||||
BoxCollider col;
|
||||
|
||||
void Start(){
|
||||
col = GetComponent<BoxCollider>();
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
public void OnObjectSpawn(){
|
||||
currentTime = 0;
|
||||
if(col != null){
|
||||
col.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update(){
|
||||
currentTime += Time.deltaTime;
|
||||
if(currentTime >= .05f){
|
||||
col.enabled = false;
|
||||
}
|
||||
if (currentTime >= timeToDisappear){
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/ExplosionController.cs.meta
Normal file
11
Assets/Scripts/ExplosionController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 631231dffee2743448ba2585062cd0b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
212
Assets/Scripts/GameController.cs
Normal file
212
Assets/Scripts/GameController.cs
Normal file
|
@ -0,0 +1,212 @@
|
|||
using Cinemachine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
[System.Serializable] public class StartGame : UnityEvent { }
|
||||
|
||||
public class GameController : MonoBehaviour{
|
||||
|
||||
[SerializeField] Vector3 playerStartPos = Vector3.zero;
|
||||
|
||||
[Space]
|
||||
public int numberOfCoins;
|
||||
[SerializeField] TextMeshProUGUI coinsText = default;
|
||||
|
||||
[Space]
|
||||
[SerializeField] Vector3 spawnerExitPosition = Vector3.zero;
|
||||
public List<Vector3> spawnerPositions;
|
||||
|
||||
List<EnemyController> deadEnemies;
|
||||
[SerializeField, Range(0f, 15f)] float timeBetweenSpawns = 7.5f;
|
||||
float currentTime;
|
||||
int currentEnemy;
|
||||
|
||||
public List<EnemyController> enemies = new List<EnemyController>();
|
||||
|
||||
[HideInInspector] public StartGame onStart;
|
||||
bool started;
|
||||
|
||||
[SerializeField] CinemachineVirtualCamera dollyTrackCamera = default;
|
||||
[SerializeField, Range(.1f, 5f)] float timeToStart = 3f;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start(){
|
||||
limboEnemies = new List<Vector3>();
|
||||
deadEnemies = new List<EnemyController>();
|
||||
currentTime = timeBetweenSpawns - 2;
|
||||
AudioManager.instance.Stop("Menu");
|
||||
AudioManager.instance.Play("Intro");
|
||||
StartCoroutine(StartGame());
|
||||
}
|
||||
|
||||
List<Vector3> limboEnemies;
|
||||
|
||||
public void EnemyDeath(EnemyController enemy){
|
||||
enemy.gameObject.SetActive(false);
|
||||
|
||||
foreach(Vector3 spawnPos in spawnerPositions){
|
||||
deadEnemies.Add(enemy);
|
||||
enemy.transform.position = spawnPos + Vector3.up;
|
||||
spawnerPositions.Remove(spawnPos);
|
||||
StartCoroutine(RespawnEnemy(enemy));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayerDeath(PlayerController player){
|
||||
player.gameObject.SetActive(false);
|
||||
player.transform.position = playerStartPos;
|
||||
player.Respawn();
|
||||
player.gameObject.SetActive(true);
|
||||
|
||||
for (int i = 0; i < spawnerPositions.Count; i++){
|
||||
enemies[i].gameObject.SetActive(false);
|
||||
enemies[i].transform.position = spawnerPositions[i] + Vector3.up;
|
||||
enemies[i].OnPlayerDie();
|
||||
enemies[i].gameObject.SetActive(true);
|
||||
enemies[i].directionLooking = Vector3.forward;
|
||||
enemies[i].canMove = false;
|
||||
}
|
||||
|
||||
deadEnemies.Clear();
|
||||
limboEnemies.Clear();
|
||||
currentEnemy = 0;
|
||||
currentTime = timeBetweenSpawns - 2;
|
||||
}
|
||||
|
||||
IEnumerator RespawnEnemy(EnemyController enemy){
|
||||
yield return new WaitForSeconds(.5f);
|
||||
spawnerPositions.Add(enemy.transform.position + Vector3.down);
|
||||
limboEnemies.Remove(enemy.transform.position + Vector3.down);
|
||||
enemy.EnterRespawn();
|
||||
enemy.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
bool won;
|
||||
|
||||
// Update is called once per frame
|
||||
void Update(){
|
||||
dollyTrackCamera.GetCinemachineComponent<CinemachineTrackedDolly>().m_PathPosition += Time.deltaTime / timeToStart * 2;
|
||||
if(dollyTrackCamera.GetCinemachineComponent<CinemachineTrackedDolly>().m_PathPosition >= 2){
|
||||
dollyTrackCamera.enabled = false;
|
||||
}
|
||||
|
||||
if (started){
|
||||
currentTime += Time.deltaTime;
|
||||
if(currentTime >= timeBetweenSpawns){
|
||||
if(currentEnemy < enemies.Count){
|
||||
enemies[currentEnemy].positionToGo = new Vector3(spawnerExitPosition.x, enemies[currentEnemy].positionToGo.y, spawnerExitPosition.z);
|
||||
enemies[currentEnemy].targetAngle = -90f;
|
||||
enemies[currentEnemy].directionLooking = Vector3.left;
|
||||
enemies[currentEnemy].canMove = true;
|
||||
currentEnemy++;
|
||||
currentTime = 0;
|
||||
}else if(deadEnemies.Count != 0){
|
||||
EnemyController enemy = deadEnemies[0];
|
||||
//EnemyController enemy = deadEnemies.Dequeue();
|
||||
enemy.Respawn();
|
||||
enemy.positionToGo = new Vector3(spawnerExitPosition.x, enemy.positionToGo.y, spawnerExitPosition.z);
|
||||
enemy.targetAngle = -90f;
|
||||
enemy.directionLooking = Vector3.left;
|
||||
enemy.canMove = true;
|
||||
deadEnemies.Remove(enemy);
|
||||
currentTime = 0;
|
||||
}
|
||||
}else if(deadEnemies.Count == 0 && currentEnemy >= enemies.Count){
|
||||
currentTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
coinsText.text = "x" + numberOfCoins;
|
||||
|
||||
if(numberOfCoins == 0 && !won){
|
||||
GameOverCanvas.instance.Win();
|
||||
won = true;
|
||||
}
|
||||
}
|
||||
|
||||
int currentScale;
|
||||
public void PlayButtonScale(){
|
||||
switch (currentScale){
|
||||
case 0:
|
||||
AudioManager.instance.PlayOneShot("Scale1");
|
||||
currentScale++;
|
||||
break;
|
||||
case 1:
|
||||
AudioManager.instance.PlayOneShot("Scale2");
|
||||
currentScale++;
|
||||
break;
|
||||
case 2:
|
||||
AudioManager.instance.PlayOneShot("Scale3");
|
||||
currentScale++;
|
||||
break;
|
||||
case 3:
|
||||
AudioManager.instance.PlayOneShot("Scale4");
|
||||
currentScale++;
|
||||
break;
|
||||
case 4:
|
||||
AudioManager.instance.PlayOneShot("Scale2");
|
||||
currentScale++;
|
||||
break;
|
||||
case 5:
|
||||
AudioManager.instance.PlayOneShot("Scale3");
|
||||
currentScale++;
|
||||
break;
|
||||
case 6:
|
||||
AudioManager.instance.PlayOneShot("Scale4");
|
||||
currentScale++;
|
||||
break;
|
||||
case 7:
|
||||
AudioManager.instance.PlayOneShot("Scale5");
|
||||
currentScale++;
|
||||
break;
|
||||
case 8:
|
||||
AudioManager.instance.PlayOneShot("Scale3");
|
||||
currentScale++;
|
||||
break;
|
||||
case 9:
|
||||
AudioManager.instance.PlayOneShot("Scale4");
|
||||
currentScale++;
|
||||
break;
|
||||
case 10:
|
||||
AudioManager.instance.PlayOneShot("Scale5");
|
||||
currentScale++;
|
||||
break;
|
||||
case 11:
|
||||
AudioManager.instance.PlayOneShot("Scale6");
|
||||
currentScale++;
|
||||
break;
|
||||
case 12:
|
||||
AudioManager.instance.PlayOneShot("Scale5");
|
||||
currentScale++;
|
||||
break;
|
||||
case 13:
|
||||
AudioManager.instance.PlayOneShot("Scale4");
|
||||
currentScale++;
|
||||
break;
|
||||
case 14:
|
||||
AudioManager.instance.PlayOneShot("Scale3");
|
||||
currentScale++;
|
||||
break;
|
||||
case 15:
|
||||
AudioManager.instance.PlayOneShot("Scale2");
|
||||
currentScale = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator StartGame(){
|
||||
yield return new WaitForSeconds(timeToStart + 2.5f);
|
||||
onStart.Invoke();
|
||||
AudioManager.instance.Play("Main");
|
||||
started = true;
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.DrawSphere(spawnerExitPosition, .2f);
|
||||
}
|
||||
}
|
11
Assets/Scripts/GameController.cs.meta
Normal file
11
Assets/Scripts/GameController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f1f41e7150dab964cb1d6d2ce50f7bb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Assets/Scripts/Light.cs
Normal file
18
Assets/Scripts/Light.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Light : MonoBehaviour {
|
||||
|
||||
[SerializeField, Range(0, 1)] float animationDuration = .5f;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void OnEnable(){
|
||||
StartCoroutine(Disable());
|
||||
}
|
||||
|
||||
IEnumerator Disable(){
|
||||
yield return new WaitForSeconds(animationDuration);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Light.cs.meta
Normal file
11
Assets/Scripts/Light.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3959e7125f29b614997ab1ce062d543e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
190
Assets/Scripts/MapCellCalculator.cs
Normal file
190
Assets/Scripts/MapCellCalculator.cs
Normal file
|
@ -0,0 +1,190 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class MapCellCalculator : MonoBehaviour{
|
||||
|
||||
[SerializeField] bool cutscene = false;
|
||||
[SerializeField] Vector3[] enemySpawnerPositions = new Vector3[9];
|
||||
|
||||
[Space]
|
||||
[SerializeField] Vector3 bottomLeftCorner = Vector3.zero;
|
||||
[SerializeField] Vector2 size = Vector2.zero;
|
||||
[SerializeField] LayerMask whatIsWall = -1;
|
||||
|
||||
[SerializeField] GameObject coin = default;
|
||||
[SerializeField, Range(0, 1)] float coinHeight = 1;
|
||||
|
||||
List<Vector3> positions;
|
||||
List<Vector3> availablePositions;
|
||||
|
||||
GameController gameController;
|
||||
|
||||
[Header("Powerups")]
|
||||
[SerializeField, Range(1, 10f)] float timeToSpawn = 5f;
|
||||
float currentTime;
|
||||
[SerializeField] bool canSpawnEnergy = true;
|
||||
[SerializeField] Vector2 energySpawnSize = Vector2.zero;
|
||||
[SerializeField] Vector3 energySpawnBottomLeftCorner = Vector3.zero;
|
||||
List<Vector3> energyPos;
|
||||
List<Vector3> energyAvailablePos;
|
||||
|
||||
[Space]
|
||||
[SerializeField] Vector3[] bombSpawnPositions = new Vector3[4];
|
||||
[SerializeField] GameObject bombSpawner = default;
|
||||
|
||||
void Awake(){
|
||||
gameController = FindObjectOfType<GameController>();
|
||||
gameController.spawnerPositions = new List<Vector3>();
|
||||
foreach(Vector3 v in enemySpawnerPositions){
|
||||
gameController.spawnerPositions.Add(v);
|
||||
}
|
||||
|
||||
positions = new List<Vector3>();
|
||||
availablePositions = new List<Vector3>();
|
||||
for (int i = 0; i < size.x; i++){
|
||||
for (int j = 0; j < size.y; j++){
|
||||
positions.Add(bottomLeftCorner + new Vector3(i, 0, j));
|
||||
}
|
||||
}
|
||||
positions = positions.Distinct().ToList();
|
||||
|
||||
foreach (Vector3 v in positions){
|
||||
if (!Physics.CheckSphere(v, .3f, whatIsWall)){
|
||||
availablePositions.Add(v);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < availablePositions.Count; i++){
|
||||
Vector3 temp = availablePositions[i];
|
||||
int randomIndex = Random.Range(i, availablePositions.Count);
|
||||
availablePositions[i] = availablePositions[randomIndex];
|
||||
availablePositions[randomIndex] = temp;
|
||||
}
|
||||
|
||||
gameController.numberOfCoins = availablePositions.Count;
|
||||
|
||||
StartCoroutine(SpawnCoins());
|
||||
|
||||
foreach (Vector3 v in bombSpawnPositions){
|
||||
Instantiate(bombSpawner, v, Quaternion.identity);
|
||||
}
|
||||
|
||||
energyPos = new List<Vector3>();
|
||||
energyAvailablePos = new List<Vector3>();
|
||||
for (int i = 0; i < energySpawnSize.x; i++){
|
||||
for (int j = 0; j < energySpawnSize.y; j++){
|
||||
energyPos.Add(energySpawnBottomLeftCorner + new Vector3(i, 0, j));
|
||||
}
|
||||
}
|
||||
energyPos = energyPos.Distinct().ToList();
|
||||
|
||||
foreach (Vector3 v in energyPos){
|
||||
if (!Physics.CheckSphere(v, .3f, whatIsWall)){
|
||||
energyAvailablePos.Add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Start(){
|
||||
gameController.enemies = new List<EnemyController>();
|
||||
foreach (Vector3 v in enemySpawnerPositions){
|
||||
GameObject enemy = ObjectPooler.instance.SpawnFromPool("Enemy", v + Vector3.up, Quaternion.identity);
|
||||
gameController.enemies.Add(enemy.GetComponent<EnemyController>());
|
||||
}
|
||||
}
|
||||
|
||||
public void CanSpawnEnergy(){
|
||||
canSpawnEnergy = true;
|
||||
}
|
||||
|
||||
void Update(){
|
||||
if (canSpawnEnergy){
|
||||
currentTime -= Time.deltaTime;
|
||||
if(currentTime <= 0){
|
||||
ObjectPooler.instance.SpawnFromPool("BulletPickup", energyAvailablePos[Random.Range(0, energyAvailablePos.Count)] + Vector3.up * coinHeight, Quaternion.identity);
|
||||
currentTime = timeToSpawn;
|
||||
canSpawnEnergy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator SpawnCoins(){
|
||||
List<CoinController> coins = new List<CoinController>();
|
||||
foreach (Vector3 v in availablePositions){
|
||||
GameObject coinController = Instantiate(coin, v + Vector3.up * coinHeight, Quaternion.identity, transform);
|
||||
coins.Add(coinController.GetComponent<CoinController>());
|
||||
}
|
||||
|
||||
if (cutscene){
|
||||
foreach (CoinController c in coins){
|
||||
yield return new WaitForSeconds(10 / availablePositions.Count);
|
||||
//Instantiate(coin, v + Vector3.up * coinHeight, Quaternion.identity, transform);
|
||||
c.Disable();
|
||||
}
|
||||
}else{
|
||||
foreach (CoinController c in coins){
|
||||
c.Disable();
|
||||
}
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
if (!Application.isPlaying){
|
||||
Gizmos.color = Color.yellow;
|
||||
|
||||
positions = new List<Vector3>();
|
||||
availablePositions = new List<Vector3>();
|
||||
for (int i = 0; i < size.x; i++){
|
||||
for (int j = 0; j < size.y; j++){
|
||||
positions.Add(bottomLeftCorner + new Vector3(i, 0, j));
|
||||
}
|
||||
}
|
||||
positions = positions.Distinct().ToList();
|
||||
|
||||
foreach (Vector3 v in positions){
|
||||
if (!Physics.CheckSphere(v, .3f, whatIsWall)){
|
||||
availablePositions.Add(v);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Vector3 v in availablePositions){
|
||||
Gizmos.DrawSphere(v + Vector3.up * coinHeight, .15f);
|
||||
}
|
||||
|
||||
|
||||
energyPos = new List<Vector3>();
|
||||
energyAvailablePos = new List<Vector3>();
|
||||
for (int i = 0; i < energySpawnSize.x; i++){
|
||||
for (int j = 0; j < energySpawnSize.y; j++){
|
||||
energyPos.Add(energySpawnBottomLeftCorner + new Vector3(i, 0, j));
|
||||
}
|
||||
}
|
||||
energyPos = energyPos.Distinct().ToList();
|
||||
|
||||
foreach (Vector3 v in energyPos){
|
||||
if (!Physics.CheckSphere(v, .3f, whatIsWall)){
|
||||
energyAvailablePos.Add(v);
|
||||
}
|
||||
}
|
||||
|
||||
Gizmos.color = Color.blue;
|
||||
foreach(Vector3 v in energyAvailablePos){
|
||||
Gizmos.DrawSphere(v + Vector3.up * coinHeight, .15f);
|
||||
}
|
||||
|
||||
Gizmos.color = Color.red;
|
||||
foreach(Vector3 v in bombSpawnPositions){
|
||||
Gizmos.DrawSphere(v + Vector3.up * coinHeight, .25f);
|
||||
}
|
||||
|
||||
|
||||
Gizmos.color = Color.magenta;
|
||||
foreach (Vector3 v in enemySpawnerPositions){
|
||||
Gizmos.DrawSphere(v + Vector3.up * coinHeight, .15f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/MapCellCalculator.cs.meta
Normal file
11
Assets/Scripts/MapCellCalculator.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c2d40d53b9c46ce4dae1595a2d53e69d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Menu.meta
Normal file
8
Assets/Scripts/Menu.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 877cf31755870984784d25ec0901e29f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
88
Assets/Scripts/Menu/GameOverCanvas.cs
Normal file
88
Assets/Scripts/Menu/GameOverCanvas.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class GameOverCanvas : MonoBehaviour{
|
||||
|
||||
public int enemiesKilled;
|
||||
public int tilesEnabled;
|
||||
public float timeSurvived;
|
||||
int finalScore;
|
||||
|
||||
[Header("Win Canvas")]
|
||||
[SerializeField] GameObject winCanvas = default;
|
||||
[Space]
|
||||
[SerializeField] GameObject maxScoreText = default;
|
||||
[SerializeField] TextMeshProUGUI enemiesText = default;
|
||||
[SerializeField] TextMeshProUGUI tilesText = default;
|
||||
[SerializeField] TextMeshProUGUI scoreText = default;
|
||||
|
||||
[Header("Game Over Canvas")]
|
||||
[SerializeField] GameObject gameOverCanvas = default;
|
||||
[Space]
|
||||
[SerializeField] GameObject gameOverMaxScoreText = default;
|
||||
[SerializeField] TextMeshProUGUI gameOverEnemiesText = default;
|
||||
[SerializeField] TextMeshProUGUI gameOverTilesText = default;
|
||||
[SerializeField] TextMeshProUGUI gameOverScoreText = default;
|
||||
|
||||
public static GameOverCanvas instance;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Awake(){
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public void Win(){
|
||||
PlayerPrefs.SetInt("Tutorial", 1);
|
||||
AudioManager.instance.Stop("Main");
|
||||
Time.timeScale = 0;
|
||||
winCanvas.SetActive(true);
|
||||
|
||||
enemiesText.text = enemiesKilled.ToString();
|
||||
tilesText.text = tilesEnabled.ToString();
|
||||
|
||||
if(enemiesKilled == 0){
|
||||
finalScore = Mathf.RoundToInt(2 * 8 * (tilesEnabled / 4) * (timeSurvived / 60));
|
||||
}else{
|
||||
finalScore = Mathf.RoundToInt(enemiesKilled * 8 * (tilesEnabled / 4) * (timeSurvived / 60));
|
||||
}
|
||||
scoreText.text = finalScore.ToString();
|
||||
|
||||
if (PlayerPrefs.HasKey("MaxScore")){
|
||||
if (PlayerPrefs.GetInt("MaxScore") >= finalScore){
|
||||
maxScoreText.SetActive(false);
|
||||
}else{
|
||||
PlayerPrefs.SetInt("MaxScore", finalScore);
|
||||
}
|
||||
}else{
|
||||
PlayerPrefs.SetInt("MaxScore", finalScore);
|
||||
}
|
||||
}
|
||||
|
||||
public void Lose(){
|
||||
PlayerPrefs.SetInt("Tutorial", 1);
|
||||
Time.timeScale = 0;
|
||||
gameOverCanvas.SetActive(true);
|
||||
|
||||
gameOverEnemiesText.text = enemiesKilled.ToString();
|
||||
gameOverTilesText.text = tilesEnabled.ToString();
|
||||
|
||||
if (enemiesKilled == 0){
|
||||
finalScore = Mathf.RoundToInt(2 * 8 * (tilesEnabled / 4) * (timeSurvived / 60));
|
||||
}else{
|
||||
finalScore = Mathf.RoundToInt(enemiesKilled * 8 * (tilesEnabled / 4) * (timeSurvived / 60));
|
||||
}
|
||||
gameOverScoreText.text = finalScore.ToString();
|
||||
|
||||
if (PlayerPrefs.HasKey("MaxScore")){
|
||||
if (PlayerPrefs.GetInt("MaxScore") >= finalScore){
|
||||
gameOverMaxScoreText.SetActive(false);
|
||||
}else{
|
||||
PlayerPrefs.SetInt("MaxScore", finalScore);
|
||||
}
|
||||
}else{
|
||||
PlayerPrefs.SetInt("MaxScore", finalScore);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/Menu/GameOverCanvas.cs.meta
Normal file
11
Assets/Scripts/Menu/GameOverCanvas.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 090f21fda4ea3c349a33fd2f5b5d5cf1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
28
Assets/Scripts/Menu/LevelLoader.cs
Normal file
28
Assets/Scripts/Menu/LevelLoader.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
public class LevelLoader : MonoBehaviour{
|
||||
|
||||
Animator anim;
|
||||
[SerializeField, Range(0f, 3f)] float fadeDuration = 1f;
|
||||
|
||||
public static LevelLoader instance;
|
||||
|
||||
void Awake(){
|
||||
instance = this;
|
||||
anim = GetComponent<Animator>();
|
||||
}
|
||||
|
||||
public void LoadScene(int scene){
|
||||
StartCoroutine(LoadLevel(scene));
|
||||
}
|
||||
|
||||
IEnumerator LoadLevel(int scene){
|
||||
anim.SetTrigger("Fade");
|
||||
yield return new WaitForSecondsRealtime(fadeDuration);
|
||||
SceneManager.LoadSceneAsync(scene);
|
||||
Time.timeScale = 1;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Menu/LevelLoader.cs.meta
Normal file
11
Assets/Scripts/Menu/LevelLoader.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fa9abfe5e6b6491418ec5cf5874c8960
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
80
Assets/Scripts/Menu/SettingsMenu.cs
Normal file
80
Assets/Scripts/Menu/SettingsMenu.cs
Normal file
|
@ -0,0 +1,80 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
public class SettingsMenu : MonoBehaviour{
|
||||
|
||||
[SerializeField] GameObject startButton;
|
||||
[SerializeField] GameObject[] mainMenu;
|
||||
|
||||
[Space]
|
||||
[SerializeField] TMP_Dropdown resolutionDropdown = default;
|
||||
Resolution[] resolutions;
|
||||
int currentResolutionIndex;
|
||||
|
||||
void Awake(){
|
||||
foreach(GameObject o in mainMenu){
|
||||
o.SetActive(false);
|
||||
}
|
||||
|
||||
if(resolutionDropdown != null){
|
||||
resolutions = Screen.resolutions.Select(resolution => new Resolution { width = resolution.width, height = resolution.height }).Distinct().ToArray();
|
||||
resolutionDropdown.ClearOptions();
|
||||
|
||||
List<string> options = new List<string>();
|
||||
for (int i = 0; i < resolutions.Length; i++){
|
||||
string option = resolutions[i].width + "x" + resolutions[i].height;
|
||||
options.Add(option);
|
||||
|
||||
if (resolutions[i].width == Screen.currentResolution.width && resolutions[i].height == Screen.currentResolution.height){
|
||||
currentResolutionIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
resolutions.Reverse();
|
||||
|
||||
resolutionDropdown.AddOptions(options);
|
||||
resolutionDropdown.value = currentResolutionIndex;
|
||||
resolutionDropdown.RefreshShownValue();
|
||||
}
|
||||
}
|
||||
|
||||
bool started;
|
||||
void Update(){
|
||||
if (Input.anyKeyDown && !started){
|
||||
AudioManager.instance.PlayOneShot("Start");
|
||||
AudioManager.instance.Play("Menu");
|
||||
startButton.SetActive(false);
|
||||
foreach(GameObject o in mainMenu){
|
||||
o.SetActive(true);
|
||||
}
|
||||
started = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetQuality(int qualityIndex){
|
||||
QualitySettings.SetQualityLevel(qualityIndex);
|
||||
}
|
||||
|
||||
public void SetResolution(int resolutionIndex){
|
||||
Resolution resolution = resolutions[resolutionIndex];
|
||||
|
||||
Screen.SetResolution(resolution.width, resolution.height, Screen.fullScreen);
|
||||
}
|
||||
|
||||
public void Play(){
|
||||
if (PlayerPrefs.HasKey("Tutorial")){
|
||||
LevelLoader.instance.LoadScene(2);
|
||||
}else{
|
||||
LevelLoader.instance.LoadScene(1);
|
||||
}
|
||||
AudioManager.instance.PlayOneShot("Play");
|
||||
}
|
||||
|
||||
public void Quit(){
|
||||
Application.Quit();
|
||||
}
|
||||
}
|
11
Assets/Scripts/Menu/SettingsMenu.cs.meta
Normal file
11
Assets/Scripts/Menu/SettingsMenu.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 49bb5047f0f5ba845a7bc043bafa8fab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/ObjectPooling.meta
Normal file
8
Assets/Scripts/ObjectPooling.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c78a38d7b34c0b845ab0d7eb05008991
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
Assets/Scripts/ObjectPooling/IPooledObject.cs
Normal file
3
Assets/Scripts/ObjectPooling/IPooledObject.cs
Normal file
|
@ -0,0 +1,3 @@
|
|||
public interface IPooledObject{
|
||||
void OnObjectSpawn();
|
||||
}
|
11
Assets/Scripts/ObjectPooling/IPooledObject.cs.meta
Normal file
11
Assets/Scripts/ObjectPooling/IPooledObject.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f2e800d3634e96c43aadb2187d5b1eea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
62
Assets/Scripts/ObjectPooling/ObjectPooler.cs
Normal file
62
Assets/Scripts/ObjectPooling/ObjectPooler.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ObjectPooler : MonoBehaviour{
|
||||
|
||||
[System.Serializable] public class Pool{
|
||||
public string tag;
|
||||
public GameObject prefab;
|
||||
public int size;
|
||||
}
|
||||
|
||||
public List<Pool> pools;
|
||||
public Dictionary<string, Queue<GameObject>> poolDictionary;
|
||||
|
||||
public static ObjectPooler instance;
|
||||
|
||||
void Awake(){
|
||||
instance = this;
|
||||
|
||||
poolDictionary = new Dictionary<string, Queue<GameObject>>();
|
||||
|
||||
foreach (Pool pool in pools){
|
||||
Queue<GameObject> objectPool = new Queue<GameObject>();
|
||||
for (int i = 0; i < pool.size; i++){
|
||||
GameObject obj = Instantiate(pool.prefab);
|
||||
obj.SetActive(false);
|
||||
obj.transform.parent = transform;
|
||||
objectPool.Enqueue(obj);
|
||||
}
|
||||
|
||||
poolDictionary.Add(pool.tag, objectPool);
|
||||
}
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start(){
|
||||
|
||||
}
|
||||
|
||||
public GameObject SpawnFromPool(string tag, Vector3 position, Quaternion rotation){
|
||||
if (!poolDictionary.ContainsKey(tag)){
|
||||
Debug.LogWarning("Pool with tag " + tag + " doesn't exist.");
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject objectToSpawn = poolDictionary[tag].Dequeue();
|
||||
|
||||
objectToSpawn.SetActive(true);
|
||||
objectToSpawn.transform.position = position;
|
||||
objectToSpawn.transform.rotation = rotation;
|
||||
|
||||
IPooledObject pooledObj = objectToSpawn.GetComponent<IPooledObject>();
|
||||
if(pooledObj != null){
|
||||
pooledObj.OnObjectSpawn();
|
||||
}
|
||||
|
||||
poolDictionary[tag].Enqueue(objectToSpawn);
|
||||
|
||||
return objectToSpawn;
|
||||
}
|
||||
}
|
11
Assets/Scripts/ObjectPooling/ObjectPooler.cs.meta
Normal file
11
Assets/Scripts/ObjectPooling/ObjectPooler.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3aa18ca9ca01041479594f2fa8dfa166
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
217
Assets/Scripts/PlayerController.cs
Normal file
217
Assets/Scripts/PlayerController.cs
Normal file
|
@ -0,0 +1,217 @@
|
|||
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);
|
||||
}
|
||||
}
|
11
Assets/Scripts/PlayerController.cs.meta
Normal file
11
Assets/Scripts/PlayerController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8fb3544b315535a44bcee63acb7583bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
60
Assets/Scripts/PortalBullet.cs
Normal file
60
Assets/Scripts/PortalBullet.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class PortalBullet : MonoBehaviour{
|
||||
|
||||
[SerializeField] float speed = 10f;
|
||||
[SerializeField, Range(1, 10)] float maxDistanceTravel = 5;
|
||||
|
||||
Transform verticalPortals;
|
||||
Transform horizontalPortals;
|
||||
Vector3 direction;
|
||||
Vector3 playerPosition;
|
||||
PlayerController player;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start(){
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update(){
|
||||
float targetAngle = Mathf.Atan2(1 * direction.x, 1 * direction.z) * Mathf.Rad2Deg;
|
||||
transform.rotation = Quaternion.Euler(0f, targetAngle, 0f);
|
||||
|
||||
transform.position = Vector3.MoveTowards(transform.position, new Vector3(playerPosition.x, transform.position.y, playerPosition.z) + direction * maxDistanceTravel, speed * Time.deltaTime);
|
||||
|
||||
if (transform.position == new Vector3(playerPosition.x, transform.position.y, playerPosition.z) + direction * maxDistanceTravel){
|
||||
player.canShoot = true;
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OnCollisionEnter(Collision col){
|
||||
if(col.gameObject.tag == "LateralWalls"){
|
||||
if(direction == Vector3.right || direction == Vector3.left){
|
||||
horizontalPortals.gameObject.SetActive(true);
|
||||
player.canShoot = true;
|
||||
gameObject.SetActive(false);
|
||||
}else if(direction == Vector3.forward || direction == Vector3.back){
|
||||
verticalPortals.gameObject.SetActive(true);
|
||||
player.canShoot = true;
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
AudioManager.instance.PlayOneShot("PortalPlace");
|
||||
}
|
||||
else{
|
||||
player.canShoot = true;
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetImportantThings(Transform vPortals, Transform hPortals, Vector3 dir, Vector3 playerPos, PlayerController player){
|
||||
verticalPortals = vPortals;
|
||||
horizontalPortals = hPortals;
|
||||
direction = dir;
|
||||
playerPosition = playerPos;
|
||||
this.player = player;
|
||||
}
|
||||
}
|
11
Assets/Scripts/PortalBullet.cs.meta
Normal file
11
Assets/Scripts/PortalBullet.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c67bbdab8e8d40d4e81575dc69d6644c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
24
Assets/Scripts/PortalBulletSpawner.cs
Normal file
24
Assets/Scripts/PortalBulletSpawner.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class PortalBulletSpawner : MonoBehaviour{
|
||||
|
||||
PlayerController player;
|
||||
MapCellCalculator map;
|
||||
|
||||
void Awake(){
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
map = FindObjectOfType<MapCellCalculator>();
|
||||
}
|
||||
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if (col.CompareTag("Player")){
|
||||
AudioManager.instance.PlayOneShot("Powerup");
|
||||
player.numberOfCharge++;
|
||||
map.CanSpawnEnergy();
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/PortalBulletSpawner.cs.meta
Normal file
11
Assets/Scripts/PortalBulletSpawner.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b122e433652ff964aa7795145464c372
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
68
Assets/Scripts/PortalController.cs
Normal file
68
Assets/Scripts/PortalController.cs
Normal file
|
@ -0,0 +1,68 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class PortalController : MonoBehaviour{
|
||||
|
||||
[System.Serializable] public enum Direction{Left, Right, Up, Down}
|
||||
[SerializeField] Direction direction = default;
|
||||
|
||||
[SerializeField] Transform exitPos = default;
|
||||
|
||||
|
||||
bool teleporting;
|
||||
PlayerController player;
|
||||
Animator anim;
|
||||
|
||||
void Awake(){
|
||||
anim = GetComponentInParent<Animator>();
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
}
|
||||
|
||||
void OnEnable(){
|
||||
anim.SetBool("Close", false);
|
||||
teleporting = false;
|
||||
}
|
||||
|
||||
void OnTriggerStay(Collider col){
|
||||
if (col.CompareTag("Player")){
|
||||
switch (direction){
|
||||
case Direction.Left:
|
||||
if (Input.GetAxisRaw("Horizontal") < 0 && !teleporting){
|
||||
player.Teleport(exitPos.position);
|
||||
StartCoroutine(ClosePortal());
|
||||
teleporting = true;
|
||||
}
|
||||
break;
|
||||
case Direction.Right:
|
||||
if (Input.GetAxisRaw("Horizontal") > 0 && !teleporting){
|
||||
player.Teleport(exitPos.position);
|
||||
StartCoroutine(ClosePortal());
|
||||
teleporting = true;
|
||||
}
|
||||
break;
|
||||
case Direction.Up:
|
||||
if (Input.GetAxisRaw("Vertical") > 0 && !teleporting){
|
||||
player.Teleport(exitPos.position);
|
||||
StartCoroutine(ClosePortal());
|
||||
teleporting = true;
|
||||
}
|
||||
break;
|
||||
case Direction.Down:
|
||||
if (Input.GetAxisRaw("Vertical") < 0 && !teleporting){
|
||||
player.Teleport(exitPos.position);
|
||||
StartCoroutine(ClosePortal());
|
||||
teleporting = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator ClosePortal(){
|
||||
yield return new WaitForSeconds(.25f);
|
||||
anim.SetBool("Close", true);
|
||||
yield return new WaitForSeconds(.5f);
|
||||
transform.parent.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
11
Assets/Scripts/PortalController.cs.meta
Normal file
11
Assets/Scripts/PortalController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 790d0b02696621b48aedc6f0c1cfd327
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
33
Assets/Scripts/ScreenShakeCall.cs
Normal file
33
Assets/Scripts/ScreenShakeCall.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using Cinemachine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ScreenShakeCall : MonoBehaviour{
|
||||
|
||||
CinemachineVirtualCamera vCam;
|
||||
float shakeTimer;
|
||||
float shakeTimerTotal;
|
||||
float startingIntensity;
|
||||
|
||||
public static ScreenShakeCall instance { get; private set; }
|
||||
|
||||
void Awake(){
|
||||
instance = this;
|
||||
vCam = GetComponent<CinemachineVirtualCamera>();
|
||||
}
|
||||
|
||||
public void ShakeCamera(float intensity, float time){
|
||||
CinemachineBasicMultiChannelPerlin multiChannelPerlin = vCam.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
|
||||
startingIntensity = intensity;
|
||||
shakeTimer = shakeTimerTotal = time;
|
||||
}
|
||||
|
||||
void Update(){
|
||||
if(shakeTimer > 0){
|
||||
shakeTimer -= Time.deltaTime;
|
||||
CinemachineBasicMultiChannelPerlin multiChannelPerlin = vCam.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
|
||||
multiChannelPerlin.m_AmplitudeGain = Mathf.Lerp(startingIntensity, 0f, 1 - (shakeTimer / shakeTimerTotal));
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/ScreenShakeCall.cs.meta
Normal file
11
Assets/Scripts/ScreenShakeCall.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1d74226738a791e43a762541fb0b2e71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue