Selection of scripts regarding the main character, board generation, and game juice
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class BoardGeneration : MonoBehaviour { | |
public int sizeOfHexBoard = 7; | |
public int[,] boardState; | |
public GameObject basicHexagon; | |
public Transform boardParent; | |
public int maxTrailLength = 10; | |
public LinkedList<GameObject> trail; | |
public GameObject[,] boardStateGO; | |
// Start is called before the first frame update | |
void Start() { | |
trail = new LinkedList<GameObject>(); | |
boardState = new int[sizeOfHexBoard, sizeOfHexBoard]; | |
boardStateGO = new GameObject[sizeOfHexBoard, sizeOfHexBoard]; | |
// | |
//Hexagon Generation | |
// | |
int xCoord = 0; | |
int yCoord = 0; | |
Vector3 tempPos = new Vector3(0, 0, 0); | |
GameObject backgroundHex = Instantiate(basicHexagon, tempPos, Quaternion.Euler(0, 0, 30f), boardParent); | |
backgroundHex.GetComponent<SpriteRenderer>().color = Color.black; | |
backgroundHex.GetComponent<SpriteRenderer>().sortingOrder = -1; | |
backgroundHex.transform.localScale *= sizeOfHexBoard; | |
backgroundHex.name = "Background Hex"; | |
Camera.main.orthographicSize = sizeOfHexBoard / 2 + 1.5f; | |
// | |
//Starts at the bottom, then draws in collums coming up, mirroring across the center line | |
// | |
for (int rawX = 0; rawX < (boardState.GetLength(1) + 1) / 2; rawX++) { | |
yCoord = 0; | |
xCoord = rawX; | |
for (int verticalPos = 0; verticalPos < boardState.GetLength(1) - rawX; verticalPos++) { | |
//Calculate position | |
tempPos = getWorldCoords(xCoord, yCoord); | |
//Right side of the center line | |
GameObject tempHex = Instantiate(basicHexagon, tempPos, Quaternion.identity, boardParent); | |
tempHex.name = xCoord + ", " + yCoord; | |
boardState[xCoord, yCoord] = 1; | |
boardStateGO[xCoord, yCoord] = tempHex; | |
//Left side of the center line | |
if (xCoord != yCoord) { | |
tempPos.x *= -1; | |
tempHex = Instantiate(basicHexagon, tempPos, Quaternion.identity, boardParent); | |
tempHex.name = yCoord + ", " + xCoord; | |
boardState[yCoord, xCoord] = 1; | |
boardStateGO[yCoord, xCoord] = tempHex; | |
} | |
xCoord++; | |
yCoord++; | |
} | |
} | |
} | |
public Vector2 getWorldCoords(int xIndex, int yIndex) { | |
Vector2 tempVector = new Vector2(0, 0); | |
tempVector.x = xIndex * (Mathf.Sqrt(3) * basicHexagon.transform.localScale.x / 2f) - (yIndex * Mathf.Sqrt(3) * basicHexagon.transform.localScale.y / 2f); | |
tempVector.y = xIndex * .5f + yIndex * .5f - (sizeOfHexBoard - 1) / 2; | |
tempVector *= 1.05f; | |
return tempVector; | |
} | |
public bool isInBounds(int xCoord, int yCoord) { | |
if (xCoord >= boardState.GetLength(1) || yCoord >= boardState.GetLength(0)) { return false; } | |
if (xCoord < 0 || yCoord < 0) { return false; } | |
if (boardState[xCoord, yCoord] == 0) { | |
return false; | |
} | |
return true; | |
} | |
public bool ColorBounds(int xCoord, int yCoord) { | |
if(!isInBounds(xCoord, yCoord)) { | |
return false; | |
} | |
if(boardStateGO[xCoord, yCoord].GetComponent<SpriteRenderer>().color != Color.white) { | |
return false; | |
} | |
return true; | |
} | |
public void DebugColorChange(int xIndex, int yIndex, Color newColor) { | |
if(ColorBounds(xIndex, yIndex)) { | |
boardStateGO[xIndex, yIndex].GetComponent<SpriteRenderer>().color = newColor; | |
AddToList(boardStateGO[xIndex, yIndex]); | |
} | |
} | |
public void AllColorChange() { | |
for(int x = 0; x < boardStateGO.GetLength(1); x++) { | |
for(int y = 0; y < boardStateGO.GetLength(0); y++) { | |
if (ColorBounds(x, y)) { | |
boardStateGO[x, y].GetComponent<SpriteRenderer>().color = Color.green; | |
} | |
} | |
} | |
} | |
public void AddToList(GameObject newTrail) { | |
trail.AddFirst(newTrail); | |
if(trail.Count > maxTrailLength) { | |
trail.Last.Value.GetComponent<SpriteRenderer>().color = Color.white; | |
trail.RemoveLast(); | |
} | |
} | |
} | |
/* | |
* | |
* Square Generation | |
* | |
for(int yCoord = 0; yCoord < boardState.GetLength(1); yCoord++) { | |
for(int xCoord = 0; xCoord < boardState.GetLength(0); xCoord++) { | |
tempPos.x = xCoord * (Mathf.Sqrt(3) * basicHexagon.transform.localScale.x / 2f) - (yCoord * Mathf.Sqrt(3) * basicHexagon.transform.localScale.y / 2f); | |
tempPos.y = xCoord * .5f + yCoord * .5f; | |
GameObject tempHex = Instantiate(basicHexagon, tempPos, Quaternion.identity); | |
tempHex.name = xCoord + ", " + yCoord; | |
} | |
} | |
*/ |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class CameraController : MonoBehaviour | |
{ | |
public Transform player; | |
public float timeToZoomIn = .25f; | |
public float strongestDilationMultiplier = .1f; | |
public AnimationCurve zoomAnimation; | |
public int numShakes = 5; | |
public float unboundTimeForScreenShake = .3f; | |
public float shakeStrength = 1f; | |
public EnemyManager enemyMaster; | |
private Camera viewer; | |
float initialCameraSize; | |
Vector3 initialLocation; | |
AudioSource SFXPlayer; | |
private void Start() { | |
viewer = Camera.main; | |
initialLocation = transform.position; | |
SFXPlayer = GetComponent<AudioSource>(); | |
StartCoroutine(LateStart()); | |
} | |
IEnumerator LateStart() { | |
yield return new WaitForSeconds(0.1f); | |
initialCameraSize = viewer.orthographicSize; | |
} | |
private void Update() { | |
} | |
public void StartCollisionImpact(ParticleSystem explosionEffect) { | |
StartCoroutine(CollisionJuice(explosionEffect)); | |
} | |
float timeSinceStart = 0f; | |
IEnumerator CollisionJuice(ParticleSystem explosionEffect) { | |
//Zoom In Section | |
// | |
explosionEffect.Play(); | |
explosionEffect.gameObject.GetComponent<AudioSource>().Play(); | |
Time.timeScale = strongestDilationMultiplier; | |
Vector3 tempV = transform.position; | |
while (timeSinceStart < timeToZoomIn) { | |
timeSinceStart += Time.unscaledDeltaTime; | |
yield return null; | |
float curveResult = zoomAnimation.Evaluate(timeSinceStart / timeToZoomIn); | |
//Zoom in | |
viewer.orthographicSize = Mathf.Lerp(initialCameraSize, 2f, curveResult); | |
tempV = Vector2.Lerp(initialLocation, player.transform.position, curveResult); | |
tempV.z = -10; | |
transform.position = tempV; | |
//Slow Down | |
} | |
//Camera Shake and Sound Played Section | |
// | |
timeSinceStart = 0f; | |
float shakeTimerSinceStart = 0; | |
float timePerShake = unboundTimeForScreenShake / numShakes; | |
Vector2 initialOffset = transform.position; | |
Vector2 currentOffset = initialOffset; | |
Vector2 targetOffset = initialOffset + (Random.insideUnitCircle * shakeStrength); | |
tempV = currentOffset; | |
while(timeSinceStart < unboundTimeForScreenShake) { | |
timeSinceStart += Time.unscaledDeltaTime; | |
yield return null; | |
if(shakeTimerSinceStart > timePerShake) { | |
shakeTimerSinceStart = 0f; | |
currentOffset = targetOffset; | |
targetOffset = initialOffset + (Random.insideUnitCircle * shakeStrength); | |
} | |
else { | |
tempV = Vector2.Lerp(currentOffset, targetOffset, shakeTimerSinceStart / timePerShake); | |
shakeTimerSinceStart += Time.unscaledDeltaTime; | |
tempV.z = -10; | |
transform.position = tempV; | |
} | |
} | |
//Zoom Out Section | |
// | |
timeSinceStart = timeToZoomIn; | |
tempV = transform.position; | |
while (timeSinceStart > 0) { | |
timeSinceStart -= Time.unscaledDeltaTime; | |
yield return null; | |
float curveResult = zoomAnimation.Evaluate(timeSinceStart / timeToZoomIn); | |
//Zoom in | |
viewer.orthographicSize = Mathf.Lerp(initialCameraSize, 2f, curveResult); | |
tempV = Vector2.Lerp(initialLocation, player.transform.position, curveResult); | |
tempV.z = -10; | |
transform.position = tempV; | |
//Slow Down | |
} | |
Time.timeScale = 1; | |
GameObject explosionObject = explosionEffect.gameObject; | |
explosionObject.GetComponent<SpriteRenderer>().enabled = false; | |
if(explosionObject.GetComponent<CircleCollider2D>()) | |
explosionObject.GetComponent<CircleCollider2D>().enabled = false; | |
if(explosionObject.GetComponent<TrailRenderer>()) | |
{ | |
explosionObject.GetComponent<TrailRenderer>().enabled = false; | |
} | |
SFXPlayer.Play(); | |
while (explosionEffect.isPlaying) { | |
yield return null; | |
} | |
if(!explosionObject.tag.Equals("Player")) { | |
Destroy(explosionObject); | |
} | |
enemyMaster.EnemyKilled(); | |
} | |
} |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class PlayerController : MonoBehaviour { | |
public BoardGeneration boardInformation; | |
public CameraController cameraMaster; | |
public float UnboundCollisionSlowdownTime = .5f; | |
public int currentXPos = 0; | |
public int currentYPos = 0; | |
public int currentSpeed = 2; | |
public float lastKnownRotation = 0f; | |
public float timeToTurn = .5f; | |
public float timeToMove = .5f; | |
public AnimationCurve rotationTimeline; | |
public AnimationCurve movementTimeline; | |
public AudioClip[] turnSounds; | |
public AudioClip yesMove; | |
public AudioClip noMove; | |
public AudioClip deathSound; | |
public AudioClip hitSound; | |
AudioSource SFXPlayer; | |
public bool isDead = false; | |
void Start() { | |
//Establish values | |
currentXPos = currentYPos = (boardInformation.sizeOfHexBoard - 1) / 2 ; | |
transform.position = boardInformation.getWorldCoords(currentXPos, currentYPos); | |
SFXPlayer = GetComponent<AudioSource>(); | |
} | |
void Update() { | |
// | |
//Gets Input from the player | |
// | |
if(Time.timeScale > .95f && !isDead) { | |
if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) { | |
StartRotation(false); | |
} | |
if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) { | |
StartRotation(true); | |
} | |
if (Input.GetKeyDown(KeyCode.Space)) { | |
StartMove(); | |
} | |
} | |
if(Input.GetKeyDown(KeyCode.Escape)) | |
{ | |
Application.Quit(); | |
Debug.Log("Game Quit"); | |
} | |
} | |
// | |
//Handles Rotation of the player | |
// | |
#region Player Rotation | |
float timeSinceStart = 0f; | |
int inProgressValue = 0; | |
public void StartRotation(bool shouldRotateClockwise) { | |
timeSinceStart = 0; | |
//Animation Cancelling | |
StopAllCoroutines(); | |
FinishRotation(); | |
FinishMove(); | |
SFXPlayer.clip = turnSounds[Random.Range(0, turnSounds.Length - 1)]; | |
SFXPlayer.Play(); | |
StartCoroutine(rotationLerp(shouldRotateClockwise)); | |
} | |
//Actually finish the rotation process | |
void FinishRotation() { | |
//Round it to the nearest 60 degrees just in case | |
transform.rotation = Quaternion.Euler(0, 0, Mathf.Round((lastKnownRotation + 60 * inProgressValue) / 60) * 60f); | |
lastKnownRotation = transform.eulerAngles.z; | |
inProgressValue = 0; | |
} | |
IEnumerator rotationLerp(bool shouldRotateClockwise) { | |
timeSinceStart = 0; | |
//Set up values to determine direction of rotation | |
Quaternion initialRotation = transform.rotation; | |
float difference = (shouldRotateClockwise) ? -60f : 60f; | |
inProgressValue = (int)difference / 60; | |
//Non linear LERPing | |
while (timeSinceStart < timeToTurn) { | |
transform.rotation = Quaternion.Euler(0, 0, initialRotation.eulerAngles.z + rotationTimeline.Evaluate(timeSinceStart / timeToTurn) * difference); | |
yield return null; | |
timeSinceStart += Time.deltaTime; | |
} | |
FinishRotation(); | |
} | |
#endregion | |
// | |
//Handles Movement of the Player | |
// | |
float timeSinceMoveStart = 0f; | |
Vector2 moveInProgressValue = new Vector2(); | |
Vector2 lastKnownPosition = new Vector2(); | |
Vector2 positionChange = new Vector2(); | |
public void StartMove() { | |
timeSinceMoveStart = 0f; | |
//Animation Cancelling | |
StopAllCoroutines(); | |
FinishRotation(); | |
FinishMove(); | |
//Establish direction based on rotation | |
int deltaX = 0; | |
int deltaY = 0; | |
switch (Mathf.RoundToInt(lastKnownRotation / 60)) { | |
case 0: deltaX = deltaY = 1; break; | |
case 1: deltaY = 1; break; | |
case 2: deltaX = -1; break; | |
case 3: deltaX = deltaY = -1; break; | |
case 4: deltaY = -1; break; | |
case 5: deltaX = 1; break; | |
default: throw new System.Exception("Abnormal Angle Found"); | |
} | |
//Account for amount to travel | |
deltaX *= currentSpeed; | |
deltaY *= currentSpeed; | |
if (boardInformation.ColorBounds(currentXPos + deltaX, currentYPos + deltaY)) { | |
StartCoroutine(MovementLerp(deltaX, deltaY)); | |
} | |
else { | |
SFXPlayer.clip = noMove; | |
SFXPlayer.Play(); | |
} | |
} | |
//Update the current position of the player | |
void UpdatePosition(int deltaX, int deltaY) { | |
currentXPos += deltaX; | |
currentYPos += deltaY; | |
positionChange.x -= deltaX; | |
positionChange.y -= deltaY; | |
boardInformation.DebugColorChange(currentXPos, currentYPos, Color.red); | |
// | |
//::TO DO:: | |
//Check to see if there are enemies at the same coordinate set as the player | |
//If so, destroy them | |
// | |
} | |
void FinishMove() { | |
//Safety catch for default values | |
if (moveInProgressValue != new Vector2(-1, -1)) { | |
transform.position = moveInProgressValue; | |
UpdatePosition((int)positionChange.x, (int)positionChange.y); | |
SFXPlayer.clip = yesMove; | |
SFXPlayer.Play(); | |
} | |
moveInProgressValue = new Vector2(-1, -1); | |
positionChange = new Vector2(0, 0); | |
} | |
IEnumerator MovementLerp(int xDifference, int yDifference) { | |
timeSinceMoveStart = 0f; | |
// | |
//Set up information indicating current location, where the player is going, and making sure the appropriate variables are accessable outside of the function | |
// | |
Vector2 inProgressLocation = boardInformation.getWorldCoords(currentXPos, currentYPos); | |
lastKnownPosition = inProgressLocation; | |
Vector2 targetLocation = boardInformation.getWorldCoords(currentXPos + xDifference, currentYPos + yDifference); | |
Vector2 directionVector = targetLocation - inProgressLocation; | |
moveInProgressValue = targetLocation; | |
positionChange = new Vector2(xDifference, yDifference); | |
int currentMovementThresholdIndex = 1; | |
//The nonLERP-LERP | |
while (timeSinceMoveStart < timeToMove) { | |
//Get the result of the animation curve | |
float animationCurveResult = movementTimeline.Evaluate(timeSinceMoveStart / timeToMove); | |
//Use that value as the "Lerped" value | |
inProgressLocation.x = lastKnownPosition.x + animationCurveResult * directionVector.x; | |
inProgressLocation.y = lastKnownPosition.y + animationCurveResult * directionVector.y; | |
transform.position = inProgressLocation; | |
yield return null; | |
//Increment | |
timeSinceMoveStart += Time.deltaTime; | |
//Update the info on where the player is whenever they cross into a new hex | |
if(animationCurveResult > (float)currentMovementThresholdIndex / (2 * currentSpeed)) { | |
currentMovementThresholdIndex += 2; | |
int changeInX = (xDifference == 0) ? 0 : xDifference / Mathf.Abs(xDifference); | |
int changeInY = (yDifference == 0) ? 0 : yDifference / Mathf.Abs(yDifference); | |
UpdatePosition(changeInX, changeInY); | |
} | |
} | |
//Actually finish the movement | |
FinishMove(); | |
} | |
private void OnTriggerEnter2D(Collider2D collision) { | |
//Some time to zoom in on the player | |
//Zoom camera to 2 | |
//Play the sound, screen shake starts, particle system starts | |
//Zoom back out, return to normal speed | |
if(collision.tag.Equals("Enemy")) { | |
if(moveInProgressValue != new Vector2(-1, -1)) | |
{ | |
ParticleSystem enemy = collision.GetComponent<ParticleSystem>(); | |
cameraMaster.StartCollisionImpact(enemy); | |
} | |
} | |
else if(collision.tag.Equals("Pillar")) | |
{ | |
PlayerDeath(); | |
} | |
} | |
public void PlayerDeath() | |
{ | |
isDead = true; | |
SFXPlayer.clip = hitSound; | |
SFXPlayer.Play(); | |
cameraMaster.StartCollisionImpact(GetComponent<ParticleSystem>()); | |
//GetComponent<SpriteRenderer>().enabled = false; | |
GetComponent<BoxCollider2D>().enabled = false; | |
//GetComponent<ParticleSystem>().Play(); | |
SFXPlayer.clip = deathSound; | |
SFXPlayer.Play(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment