This commit is contained in:
Gerard Gascón 2025-04-24 17:26:56 +02:00
commit e0a842f222
796 changed files with 361371 additions and 0 deletions

View file

@ -0,0 +1,58 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyBehavior : MonoBehaviour
{
public float speed = 0;
public static int enemyAmount;
private bool alive = true;
// Start is called before the first frame update
void Awake()
{
enemyAmount++;
}
private void Start()
{
//StartCoroutine(walk(Random.Range(1, 3))); //grid base walk. Deprecated
}
// Update is called once per frame
void Update()
{
if(alive)
transform.position += Vector3.Normalize(GameManager.Instance.player.GetComponent<PlayerManager>().getClosestPlayer(transform.position).transform.position - transform.position) * speed * Time.deltaTime;
}
public void Kill()
{
alive = false;
GameManager.Instance.enemies.Remove(gameObject);
if (GameManager.Instance.enemies.Count == 0)
{
GameManager.Instance.nextRound();
}
//disable enemy capabilitiyes
GetComponent<Collider>().enabled = false; //prevent player kill
GetComponent<LookAtMovement>().enabled = false; //prevent rotation
GetComponentInChildren<Animator>().SetBool("Die", true); //fire anim
LeanTween.moveY(gameObject, transform.position.y + .5f, 0.1f).setEaseOutQuint();
LeanTween.moveY(gameObject, transform.position.y - .5f, 0.35f).setEaseInQuint().setDelay(0.1f);
LeanTween.moveY(gameObject, transform.position.y - 1, 1.1f).setEaseInQuint().setDelay(0.45f);
//add score
GameManager.Instance.ScoreSys.AddScore(MyVars.enemyKillScore, true);
StartCoroutine(DestroyGameObject(1.5f));
}
IEnumerator DestroyGameObject(float t)
{
yield return new WaitForSeconds(t);
Destroy(gameObject);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3b122c0d6f8cfc49a0ccbe420c4598b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,235 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyTypes;
using TMPro;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
static GameManager _instance;
public static GameManager Instance
{
get
{
if (_instance == null)
{
_instance = GameObject.FindObjectOfType<GameManager>();
if (_instance == null)
{
GameObject container = new GameObject("GameManager");
_instance = container.AddComponent<GameManager>();
}
}
return _instance;
}
}
//game references
private MyTypes.MyGrid grid;
public MyTypes.MyGrid Grid
{
get
{
return grid;
}
}
[System.NonSerialized]
public GameObject player;
public List<GameObject> enemies;
public List<GameObject> spikes;
public GameObject scoreCanvas;
private ScoreSystem scoreSys;
public ScoreSystem ScoreSys { get { return scoreSys; } }
public Animator fade;
public LevelGeneration levelGeneration;
public bool autoStart = false;
//Testing
public bool hardStart = false;
private int round = 0;
private bool gameActive = false;
private void Start()
{
CreateGrid();
InitializeScore();
if (SceneManager.GetActiveScene().buildIndex == 1)
{
Debug.Log(SceneManager.GetActiveScene().buildIndex);
StartGame();
}else if (hardStart){
StartGame();
}
AudioManager.instance.Play("MainMusic");
}
public void Lose(){
AudioManager.instance.Play("GameOver");
PlayerPrefs.SetInt("Score", scoreSys.Score);
StartCoroutine(Lose(2f));
}
IEnumerator Lose(float delay){
yield return new WaitForSeconds(delay);
fade.SetTrigger("FadeIn");
yield return new WaitForSeconds(1f);
Loader.Load(4);
}
private float timeSinceStart = 0;
private void Update()
{
if (gameActive) {
timeSinceStart += (Time.deltaTime*(round+1));
if (timeSinceStart>=1)
{
timeSinceStart = 0;
scoreSys.AddScore(1);
}
}
}
private void InitializeScore()
{
scoreSys = scoreCanvas.GetComponentInChildren<ScoreSystem>();
}
private void CreateGrid()
{
//grid initialization
grid = new MyTypes.MyGrid(MyVars.gridWidth, MyVars.gridHeight);
//grid population
for (int i = 0; i < MyVars.gridWidth; ++i)
{
for (int j = 0; j < MyVars.gridHeight; ++j)
{
grid.grid[i, j] = new MyCell(i, j);
grid.AddAvailableCell(grid.grid[i, j]);
}
}
}
public void StopGame()
{
GameManager.Instance.gameActive = false;
}
public void StartGame(){
GameManager.Instance.player = Spawner.Instance.SpawnPlayer();
GameManager.Instance.spikes = new List<GameObject>(Spawner.Instance.SpawnSpike((int)MyVars.spikeAmount));
GameManager.Instance.enemies = new List<GameObject>(Spawner.Instance.SpawnEnemy((int)MyVars.minEnemyAmount)); //add the enemies last since it is relevant for grid cell purposes
GameManager.Instance.scoreCanvas.SetActive(true);
GameManager.Instance.gameActive = true;
if(levelGeneration!=null)
levelGeneration.StartGeneration();
}
public void movePawn(MyPawn pawn, MyCell targetCell)
{
grid.movePawn(pawn, targetCell);
}
public void movePawn(MyPawn pawn, MyDirection dir)
{
Vector2Int pawnPos = pawn.CurrentCell.position;
//prevent movement if you are on the edge of the screen
if (pawnPos.x == MyVars.gridWidth - 1 && dir == MyDirection._RIGHT)
return;
else if (pawnPos.x == 0 && dir == MyDirection._LEFT)
return;
else if (pawnPos.y == MyVars.gridHeight - 1 && dir == MyDirection._UP)
return;
else if (pawnPos.y == 0 && dir == MyDirection._DOWN)
return;
//look up destination cell
MyCell targetCell;
switch (dir)
{
default:
case MyDirection._UP:
targetCell = grid.grid[pawn.CurrentCell.position.x, pawn.CurrentCell.position.y+1];
break;
case MyDirection._DOWN:
targetCell = grid.grid[pawn.CurrentCell.position.x, pawn.CurrentCell.position.y - 1];
break;
case MyDirection._RIGHT:
targetCell = grid.grid[pawn.CurrentCell.position.x+1, pawn.CurrentCell.position.y];
break;
case MyDirection._LEFT:
targetCell = grid.grid[pawn.CurrentCell.position.x-1, pawn.CurrentCell.position.y];
break;
}
//if cell is empty, proceed
if (targetCell.Pawn == null)
{
grid.movePawn(pawn, targetCell);
}
}
public void SlowTime(bool slowmo)
{
if (slowmo)
Time.timeScale = MyVars.slowTime;
else
Time.timeScale = MyVars.defaultTime;
}
public void nextRound()
{
round++;
enemies.AddRange(Spawner.Instance.SpawnEnemy((int)Mathf.Min(MyVars.minEnemyAmount+round*MyVars.enemyAmountGrowth, MyVars.maxEnemyAmount), Mathf.Min(MyVars.enemyMaxSpeed, round* MyVars.enemySpeedGrowth)));
}
private void ClearGame()
{
foreach (GameObject go in enemies)
Destroy(go);
enemies.Clear();
foreach (GameObject go in spikes)
Destroy(go);
spikes.Clear();
scoreSys.Score = 0;
Destroy(player);
CreateGrid();
}
public void PlayAgain()
{
ClearGame();
StartGame();
round = 0;
}
public void Exit()
{
#if UNITY_STANDALONE
//Quit the application
Application.Quit();
#endif
//If we are running in the editor
#if UNITY_EDITOR
//Stop playing the scene
UnityEditor.EditorApplication.isPlaying = false;
#endif
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9ffa56f0b742c2b45a5b1f54c28f6340
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class GameOverScreen : MonoBehaviour{
[SerializeField] Animator fade;
[SerializeField] TMP_Text scoreText;
// Start is called before the first frame update
void Awake(){
int score = Mathf.Min(99999999, PlayerPrefs.GetInt("Score", 0));
string scoreStr = string.Empty;
for (int i = 0; i < 8 - score.ToString().Length; i++){
scoreStr += "0";
}
scoreStr += score.ToString();
scoreText.text = scoreStr;
}
public void Retry(){
AudioManager.instance.PlayOneShot("LevelStart");
StartCoroutine(Fade(3));
}
public void Quit(){
AudioManager.instance.FadeOut("MainMusic", 1f);
AudioManager.instance.PlayOneShot("MenuClick");
StartCoroutine(Fade(0));
}
IEnumerator Fade(int scene){
fade.SetTrigger("FadeIn");
yield return new WaitForSeconds(1f);
Loader.Load(scene);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2316a5018c84df54fa8b237dde8777e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5a5c41ee621270748b2767f1e4f75da8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,63 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyTypes;
public class LevelGeneration : MonoBehaviour{
[SerializeField] GameObject levelPrefab;
[SerializeField] bool spawnGrid = true;
[Space]
[SerializeField] Material black;
[SerializeField] Material white;
// Start is called before the first frame update
void Start(){
if (GameManager.Instance.autoStart)
StartGeneration();
}
public void StartGeneration(){
if(spawnGrid)
StartCoroutine(SpawnGrid());
}
IEnumerator SpawnGrid(){
/*for (int i = 0; i < MyVars.gridWidth; i++){
for (int j = 0; j < MyVars.gridHeight; j++){
MeshRenderer mesh = Instantiate(levelPrefab, new Vector3(i, -1.5f, j), Quaternion.identity).GetComponentInChildren<MeshRenderer>();
mesh.material = (i + j) % 2 == 0 ? black : white;
yield return new WaitForSecondsRealtime(0.015625f);
}
}*/
List<Vector3> positions = new List<Vector3>();
for (int i = 0; i < MyVars.gridWidth; i++){
for (int j = 0; j < MyVars.gridHeight; j++){
positions.Add(new Vector3(i, -1.5f, j));
}
}
for (int i = 0; i < MyVars.gridWidth * MyVars.gridHeight; i += 3){
if (i < MyVars.gridWidth * MyVars.gridHeight){
Vector3 pos = positions[Random.Range(0, positions.Count)];
MeshRenderer mesh = Instantiate(levelPrefab, pos, Quaternion.identity).GetComponentInChildren<MeshRenderer>();
mesh.material = (pos.x + pos.z) % 2 == 0 ? black : white;
positions.Remove(pos);
}
if (i + 1 < MyVars.gridWidth * MyVars.gridHeight){
Vector3 pos = positions[Random.Range(0, positions.Count)];
MeshRenderer mesh = Instantiate(levelPrefab, pos, Quaternion.identity).GetComponentInChildren<MeshRenderer>();
mesh.material = (pos.x + pos.z) % 2 == 0 ? black : white;
positions.Remove(pos);
}
if (i + 2 < MyVars.gridWidth * MyVars.gridHeight){
Vector3 pos = positions[Random.Range(0, positions.Count)];
MeshRenderer mesh = Instantiate(levelPrefab, pos, Quaternion.identity).GetComponentInChildren<MeshRenderer>();
mesh.material = (pos.x + pos.z) % 2 == 0 ? black : white;
positions.Remove(pos);
}
yield return new WaitForSecondsRealtime(0.01f);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27e33b608f219f5478ca25ba58aa4d2e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,158 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyTypes;
using Cinemachine;
public class Spawner : MonoBehaviour{
static Spawner _instance;
public static Spawner Instance{
get{
if (_instance == null){
_instance = FindObjectOfType<Spawner>();
if (_instance == null){
GameObject container = new GameObject("GameManager");
_instance = container.AddComponent<Spawner>();
}
}
return _instance;
}
}
[SerializeField] PlayerManager players;
//[SerializeField] CinemachineVirtualCamera virtualCamera;
public GameObject enemy;
public GameObject spike;
public GameObject SpawnPlayer(){
PlayerManager playerManager = Instantiate(players);
//playerManager.followCamera = virtualCamera;
playerManager.Init();
GameManager.Instance.Grid.grid[MyVars.p1StartPos.x, MyVars.p1StartPos.y].Pawn = playerManager.Player1;
GameManager.Instance.Grid.grid[MyVars.p2StartPos.x, MyVars.p2StartPos.y].Pawn = playerManager.Player2;
GameManager.Instance.Grid.RemoveAvailableCell(playerManager.Player1.CurrentCell);
GameManager.Instance.Grid.RemoveAvailableCell(playerManager.Player2.CurrentCell);
return playerManager.gameObject;
}
public List<GameObject> SpawnEnemy(int amount)
{
List<MyCell> safetyCells = new List<MyCell>();
if (GameManager.Instance.player != null)
{
for(int i=-1; i<2; i++)
{
for(int j=-1; j<2; j++)
{
if (!(i == 0 && j == 0)) //prevent self cell check (player is there)
{
MyCell aux = GameManager.Instance.Grid.getCell(GameManager.Instance.player.GetComponent<PlayerManager>().Player1.CurrentCell.position, new Vector2Int(i, j));
if (aux.Pawn == null)
{
safetyCells.Add(aux);
GameManager.Instance.Grid.RemoveAvailableCell(aux);
}
}
}
} //check surrounding player1 cells
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
if (!(i == 0 && j == 0)) //prevent self cell check (player is there)
{
MyCell aux = GameManager.Instance.Grid.getCell(GameManager.Instance.player.GetComponent<PlayerManager>().Player2.CurrentCell.position, new Vector2Int(i, j));
if (aux.Pawn == null)
{
safetyCells.Add(aux);
GameManager.Instance.Grid.RemoveAvailableCell(aux);
}
}
}
} //check surrounding player2 cells
//Safety cells have been removed from the available cells list. At the end of the methods, these cells will be fed back into the available cell list.
}
List<GameObject> enemies = new List<GameObject>();
List<MyCell> cellsToAddBack = new List<MyCell>();
for (int i = 0; i < amount; ++i)
{
GameObject auxEnemy = Instantiate(enemy, Vector3.zero, Quaternion.identity);
enemies.Add(auxEnemy);
MyCell auxCell = GameManager.Instance.Grid.GetAvailableCell();
auxEnemy.transform.position = new Vector3 (auxCell.position.x*MyVars.cellSize, 0, auxCell.position.y * MyVars.cellSize);
cellsToAddBack.Add(auxCell);
}
//pushing cells where the enemies spawned back into the available cell list since the enemies movement isnt grid-based and said cells should be occupiable by the player later on.
for(int i=0; i<amount; ++i)
{
GameManager.Instance.Grid.AddAvailableCell(cellsToAddBack[cellsToAddBack.Count - 1]);
cellsToAddBack.RemoveAt(cellsToAddBack.Count-1);
}
//feeding back the safety cells into the available cells list
foreach(MyCell c in safetyCells)
{
GameManager.Instance.Grid.AddAvailableCell(c);
}
return enemies;
}
public List<GameObject> SpawnEnemy(int amount, float speed)
{
List<GameObject> enemies = new List<GameObject>();
List<MyCell> cellsToAddBack = new List<MyCell>();
for (int i = 0; i < amount; ++i)
{
GameObject auxEnemy = Instantiate(enemy, Vector3.zero, Quaternion.identity);
auxEnemy.GetComponent<EnemyBehavior>().speed = speed;
enemies.Add(auxEnemy);
MyCell auxCell = GameManager.Instance.Grid.GetAvailableCell();
auxEnemy.transform.position = new Vector3(auxCell.position.x * MyVars.cellSize, 0, auxCell.position.y * MyVars.cellSize);
cellsToAddBack.Add(auxCell);
}
//pushing cells where the enemies spawned back into the available cell list since the enemies movement isnt grid-based and said cells should be occupiable by the player later on.
for (int i = 0; i < amount; ++i)
{
GameManager.Instance.Grid.AddAvailableCell(cellsToAddBack[cellsToAddBack.Count - 1]);
cellsToAddBack.RemoveAt(cellsToAddBack.Count - 1);
}
return enemies;
}
public List<GameObject> SpawnSpike(int amount)
{
List<GameObject> ans = new List<GameObject>();
for (int i = 0; i < amount; ++i)
{
MyPawn auxSpike = Instantiate(spike, Vector3.zero, Quaternion.identity).GetComponent<SpikeBehavior>();
GameManager.Instance.Grid.GetAvailableCell().Pawn = auxSpike;
ans.Add(auxSpike.gameObject);
}
return ans;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 295df3d001cb49145a48e4d5c7cb3b90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,20 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtMovement : MonoBehaviour
{
private Vector3 lastPos = Vector3.zero;
public float slerpAlpha = 0.025f;
// Update is called once per frame
void Update()
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(transform.position - lastPos, Vector3.up), slerpAlpha);
}
private void LateUpdate()
{
lastPos = transform.position;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 882bfbfdf87a3da49b7a660bfe8dbdd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

194
Assets/Scripts/MyTypes.cs Normal file
View file

@ -0,0 +1,194 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class MyVars
{
public static float cellSize = 1;
public static int gridWidth = 15;
public static int gridHeight = 12;
public static float slowTime = .1f;
public static float defaultTime = 1;
public static Vector2Int p1StartPos = new Vector2Int((gridWidth-1)/2, 2);
public static Vector2Int p2StartPos = new Vector2Int((gridWidth+1)/2, 2);
public static float enemyMaxSpeed = 3;
public static float enemySpeedGrowth = 0.2f;
public static float minEnemyAmount = 2;
public static float maxEnemyAmount = 5;
public static float enemyAmountGrowth = 0.25f;
public static int enemyKillScore = 1000;
public static float spikeAmount = 3;
}
public static class MyMethods
{
private static System.Random rng = new System.Random();
public static float Remap(this float value, float from1, float to1, float from2, float to2)
{
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
}
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
namespace MyTypes
{
public enum MyDirection
{
_UP, _DOWN, _RIGHT, _LEFT, _MAX
}
public class MyPawn : MonoBehaviour
{
protected MyCell currentCell=null;
public MyCell CurrentCell
{
get
{
return currentCell;
}
set
{
currentCell = value;
}
}
}
public class MyCell
{
public Vector2Int position;
private MyPawn pawn;
public MyPawn Pawn
{
get
{
return pawn;
}
set
{
//pawn = value;
if (value != null) //if value does not equal null, the pawn is moving into this cell
{
if (pawn == null) //I am an empty cell
{
if(value.CurrentCell!=null)
value.CurrentCell.pawn = null;
pawn = value;
pawn.CurrentCell = this;
LeanTween.move(pawn.gameObject, new Vector3(position.x * MyVars.cellSize, 0, position.y * MyVars.cellSize), 0.1f).setEaseOutCirc();
pawn.gameObject.transform.localScale = new Vector3(.75f, .75f, 1.25f);
//LeanTween.scaleZ(pawn.gameObject, 1.5f, 0).setEaseOutBack();
//LeanTween.scaleX(pawn.gameObject, .75f, 0).setEaseOutBack();
//LeanTween.scaleY(pawn.gameObject, .75f, 0).setEaseOutBack();
LeanTween.scaleZ(pawn.gameObject, 1, .35f).setEaseOutBack();
LeanTween.scaleX(pawn.gameObject, 1, .35f).setEaseOutBack();
LeanTween.scaleY(pawn.gameObject, 1, .35f).setEaseOutBack();
//pawn.gameObject.transform.position = new Vector3(position.x * MyVars.cellSize, 0, position.y * MyVars.cellSize);
}
else
{
Debug.LogError("Assigned pawn to an occupied cell: " + position);
EnemyBehavior.enemyAmount--;
}
}
}
}
public MyCell (Vector2Int position)
{
this.position = position;
pawn = null;
}
public MyCell (int x, int y)
{
position = new Vector2Int(x, y);
pawn = null;
}
}
[System.Serializable]
public class MyGrid
{
public int width=MyVars.gridWidth;
public int height=MyVars.gridHeight;
public float cellSize = MyVars.cellSize;
public MyCell[,] grid;
public List<MyCell> availableCells;
public MyGrid(int width, int height)
{
this.width = width;
this.height = height;
grid = new MyCell[width, height];
availableCells = new List<MyCell>();
}
public MyCell getCell(Vector2Int pos)
{
return grid[pos.x , pos.y];
}
public MyCell getCell(Vector2Int pos, Vector2Int offset)
{
return grid[pos.x+offset.x, pos.y+offset.y];
}
public void AddAvailableCell(MyCell cell)
{
availableCells.Add(cell);
}
public MyCell GetAvailableCell()
{
MyMethods.Shuffle(availableCells);
MyCell aux = availableCells[availableCells.Count-1];
availableCells.Remove(aux);
return aux;
}
public void RemoveAvailableCell(MyCell cell)
{
if(availableCells.Contains(cell))
availableCells.Remove(cell);
}
public void movePawn(MyPawn pawnToMove, MyCell targetCell)
{
AddAvailableCell(pawnToMove.CurrentCell);
RemoveAvailableCell(targetCell);
//pawnToMove.CurrentCell = targetCell;
targetCell.Pawn = pawnToMove; //this also updates former cell's pawn reference and pawn's cell reference
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0fe2d36af78d28b4c8128724ff984e75
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 00120b883d48db24e9e823049d8b169c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,41 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerDeath : MonoBehaviour
{
bool invincible = true;
private void Start()
{
StartCoroutine(vincible(0.3f));
}
IEnumerator vincible(float t)
{
yield return new WaitForSeconds(t);
invincible = false;
}
private void OnTriggerEnter(Collider other)
{
if (!invincible)
{
if (other.gameObject.layer == 6)
{
Kill();
}
}
}
public void Kill()
{
GetComponentInChildren<Animator>().SetBool("Die", true);
GameManager.Instance.player.GetComponent<PlayerManager>().Player1.enabled = false;
GameManager.Instance.player.GetComponent<PlayerManager>().Player2.enabled = false;
Instantiate(GameManager.Instance.player.GetComponent<PlayerManager>().impactParticles, transform.position, Quaternion.identity);
GameManager.Instance.StopGame();
GetComponent<PlayerMovement>().enabled = false;
Debug.Log("You lose");
GameManager.Instance.Lose();
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a033c899e7de82e439d272b5ebc82dfb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,91 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class PlayerManager : MonoBehaviour{
//public CinemachineVirtualCamera followCamera;
public ParticleSystem impactParticles;
PlayerMovement currentPlayer;
[Space]
[SerializeField] PlayerMovement player1;
[SerializeField] PlayerMovement player2;
public PlayerMovement Player1
{
get
{
return player1;
}
}
public PlayerMovement Player2
{
get
{
return player2;
}
}
[Space]
[SerializeField, Range(0f, 1f)] float defaultTime = 1f;
[SerializeField, Range(0f, 1f)] float slowTime = .1f;
[HideInInspector] public PlayerMovement playerMoving;
// Start is called before the first frame update
public void Init(){
currentPlayer = player1;
//followCamera.Follow = player1.transform;
}
// Update is called once per frame
void Update(){
}
private void ActivityHandle()
{
//if (Input.GetKeyDown(KeyCode.Space))
//{
// if (currentPlayer == player1)
// {
// //followCamera.Follow = player2.transform;
// currentPlayer.active = false;
// currentPlayer = player2;
// currentPlayer.active = true;
// }
// else
// {
// //followCamera.Follow = player1.transform;
// currentPlayer.active = false;
// currentPlayer = player1;
// currentPlayer.active = true;
// }
//}
}
public void Move(PlayerMovement player){
Time.timeScale = defaultTime;
playerMoving = player;
}
public void Stop(){
Time.timeScale = slowTime;
playerMoving = null;
}
public GameObject getClosestPlayer(Vector3 position)
{
if (Vector3.Magnitude(position - player1.transform.position) < Vector3.Magnitude(position - player2.transform.position))
return player1.gameObject;
return player2.gameObject;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e213d3a02631a474f8046be5a688d1f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,139 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MyTypes.MyPawn{
public bool player1;
[Space]
[SerializeField] PlayerManager playerManager;
Vector2 velocity;
bool moving;
Vector2 positionToGo;
Vector2 directionFacing = Vector2.up;
float rotationVelocity;
// Start is called before the first frame update
void Awake(){
positionToGo = new Vector2(transform.position.x, transform.position.z);
}
// Update is called once per frame
void Update(){
if (!player1)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
positionToGo += Vector2.up;
directionFacing = Vector2.up;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._UP);
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
positionToGo += Vector2.down;
directionFacing = Vector2.down;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._DOWN);
}
else if (Input.GetKeyDown(KeyCode.LeftArrow))
{
positionToGo += Vector2.left;
directionFacing = Vector2.left;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._LEFT);
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
positionToGo += Vector2.right;
directionFacing = Vector2.right;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._RIGHT);
}
if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.RightArrow))
AudioManager.instance.PlayOneShot("Pez");
}
else
{
if (Input.GetKeyDown(KeyCode.W))
{
positionToGo += Vector2.up;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._UP);
directionFacing = Vector2.up;
}
else if (Input.GetKeyDown(KeyCode.S))
{
positionToGo += Vector2.down;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._DOWN);
directionFacing = Vector2.down;
}
else if (Input.GetKeyDown(KeyCode.A))
{
positionToGo += Vector2.left;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._LEFT);
directionFacing = Vector2.left;
}
else if (Input.GetKeyDown(KeyCode.D))
{
positionToGo += Vector2.right;
GameManager.Instance.movePawn(this, MyTypes.MyDirection._RIGHT);
directionFacing = Vector2.right;
}
if(Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.W))
AudioManager.instance.PlayOneShot("Pez");
}
//Vector2 currentPosition = Vector2.SmoothDamp(new Vector2(transform.position.x, transform.position.z), positionToGo, ref velocity, .1f, Mathf.Infinity, Time.unscaledDeltaTime);
//transform.position = new Vector3(currentPosition.x, transform.position.y, currentPosition.y);
float targetAngle = Mathf.Atan2(directionFacing.x, directionFacing.y) * Mathf.Rad2Deg;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref rotationVelocity, .1f, Mathf.Infinity, Time.unscaledDeltaTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
}
private void oldMovement()
{
if (playerManager.playerMoving == null || playerManager.playerMoving == this)
{
if (!moving)
{
Vector2 movement = Vector2.zero;
if (Input.GetButtonDown("Up"))
movement = Vector2.up;
else if (Input.GetButtonDown("Down"))
movement = Vector2.down;
else if (Input.GetButtonDown("Left"))
movement = Vector2.left;
else if (Input.GetButtonDown("Right"))
movement = Vector2.right;
if (movement.sqrMagnitude > .1f)
{
moving = true;
directionFacing = movement;
playerManager.Move(this);
}
positionToGo = new Vector2(positionToGo.x + movement.x, positionToGo.y + movement.y);
}
else
{
Vector2 currentPosition = Vector2.SmoothDamp(new Vector2(transform.position.x, transform.position.z), positionToGo, ref velocity, .1f, Mathf.Infinity, Time.unscaledDeltaTime);
transform.position = new Vector3(currentPosition.x, transform.position.y, currentPosition.y);
if (Vector2.Distance(currentPosition, positionToGo) < .05f)
{
transform.position = new Vector3(positionToGo.x, transform.position.y, positionToGo.y);
moving = false;
playerManager.Stop();
}
}
}
float targetAngle = Mathf.Atan2(directionFacing.x, directionFacing.y) * Mathf.Rad2Deg;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref rotationVelocity, .1f, Mathf.Infinity, Time.unscaledDeltaTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 645bc137feec1104a9aa937afda9ba5e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,50 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerRope : MonoBehaviour{
[SerializeField] Transform player1, player2;
LineRenderer rope;
[SerializeField] LayerMask enemyMask = -1;
[SerializeField] LayerMask spikesMask = -1;
[SerializeField] PlayerManager playerManager;
// Start is called before the first frame update
void Awake(){
rope = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update(){
float toleranceThreshold = .5f;
Vector3[] points = new Vector3[2];
points[0] = player1.position;
points[1] = player2.position;
rope.SetPositions(points);
Vector3 dir = (player2.position - player1.position).normalized;
Physics.Raycast(player1.position+dir*toleranceThreshold, dir, out RaycastHit enemyHit, Vector3.Distance(player1.position, player2.position)-toleranceThreshold*2, enemyMask);
if (enemyHit.collider){
ScreenShake.Shake(1f, .25f);
AudioManager.instance.PlayOneShot("KillPenguin");
Instantiate(playerManager.impactParticles, enemyHit.collider.transform.position, Quaternion.identity);
enemyHit.collider.gameObject.GetComponent<EnemyBehavior>().Kill();
}
Physics.Raycast(player1.position, dir, out RaycastHit spikeHit, Vector3.Distance(player1.position, player2.position), spikesMask);
if (spikeHit.collider && spikeHit.collider.gameObject.GetComponent<SpikeBehavior>().Harming){
AudioManager.instance.PlayOneShot("Cuerda");
ScreenShake.Shake(2f, .5f);
GameManager.Instance.player.GetComponent<PlayerManager>().Player1.gameObject.GetComponent<PlayerDeath>().Kill();
GameManager.Instance.player.GetComponent<PlayerManager>().Player2.gameObject.GetComponent<PlayerDeath>().Kill();
Destroy(gameObject);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5a0c81a25f3791a43b822ff75d775fd4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class ScoreSystem : MonoBehaviour{
int score;
string scoreStr;
TMP_Text scoreText;
public int Score { get { return score; }
set {
score = value;
score = Mathf.Min(99999999, score);
scoreStr = string.Empty;
scoreStr += score.ToString();
scoreText.text = scoreStr;
}
}
// Start is called before the first frame update
void Awake(){
scoreText = GetComponent<TMP_Text>();
}
public void AddScore(int amount, bool tween=true){
score = Mathf.Min(99999999, score + amount);
scoreStr = string.Empty;
for (int i = 0; i < 8 - score.ToString().Length; i++){
scoreStr += "0";
}
scoreStr += score.ToString();
scoreText.text = scoreStr;
if (tween)
{
float scaleOffset = MyMethods.Remap(amount, 1, MyVars.enemyKillScore, 1.04f, 1.1f);
LeanTween.scale(gameObject, new Vector3(scaleOffset, scaleOffset, scaleOffset), 0.05f).setEaseOutElastic();
LeanTween.scale(gameObject, Vector3.one, 0.075f).setDelay(0.05f).setEaseInSine();
}
}
public void RemoveScore(int amount){
score = Mathf.Max(0, score - amount);
scoreStr = string.Empty;
for (int i = 0; i < 8 - score.ToString().Length; i++){
scoreStr += "0";
}
scoreStr += score.ToString();
scoreText.text = scoreStr;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 895bde58b45e1e1458929f5bb4564dba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,50 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpikeBehavior : MyTypes.MyPawn{
public static int spikeAmount;
private Animator anim;
private bool harming = false;
public bool Harming
{
get
{
return harming;
}
set
{
GetComponent<PlaySound>().PlayOneShot(value?"ErizoIn":"ErizoOut");
harming = value;
}
}
void updateAnimation(bool value)
{
anim.SetBool("harming", value);
}
// Start is called before the first frame update
void Awake(){
spikeAmount++;
anim = GetComponentInChildren<Animator>();
}
private void Start(){
StartCoroutine(ToggleState(3));
}
IEnumerator ToggleState(float time)
{
yield return new WaitForSeconds(time);
updateAnimation(!Harming);
StartCoroutine(ToggleState(3));
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b21e22dadf8099247a1c9686784995e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpikeEventAnswerer : MonoBehaviour
{
private SpikeBehavior sb;
// Start is called before the first frame update
void Start()
{
sb = GetComponentInParent<SpikeBehavior>();
}
public void SpikeToggle()
{
sb.Harming = !sb.Harming;
Debug.Log("Spike toggle event called");
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 753d11d4f65ddc34893f79e841f24d72
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartGameDelay : MonoBehaviour{
[SerializeField] Animator fade;
void Start(){
AudioManager.instance.Play("MenuMusic");
}
public void StartGame(float delay){
AudioManager.instance.FadeOut("MenuMusic", 1f);
StartCoroutine(DelayedStart(delay));
}
IEnumerator DelayedStart(float delay){
yield return new WaitForSeconds(delay - 1f);
fade.SetTrigger("FadeIn");
yield return new WaitForSeconds(1f);
Loader.Load(3);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec9a8d56d812a304ab257c066e8a9444
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: