These C# scripts are for a small game where the goal of the player is to time jumps and hit targets consistently. The project was created in Unity from scratch.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Target : MonoBehaviour
{
public float movementSpeed = 1.0f;
public float movementDistance = 1.0f;
public float movementSpeedMin = 0.5f;
public float movementSpeedMax = 2.0f;
public float movementDistanceMin = 0.5f;
public float movementDistanceMax = 2.0f;
public int targetPoints = 1;
public ParticleSystem targetDestroyedParticles;
public ScoreManager scoreManager;
public GameplayPolish polish;
private Vector3 startPosition;
private Vector3 newPosition;
private Vector3 movementWave;
private Animator animator;
private int patternNumber;
// Start is called before the first frame update
void Start()
{
startPosition = transform.position;
scoreManager = GameObject.Find("Game Manager").GetComponent<ScoreManager>();
polish = GameObject.Find("Game Manager").GetComponent<GameplayPolish>();
animator = GetComponent<Animator>();
// Randomization code for Target's speed and magnitude
movementSpeed = Random.Range(movementSpeedMin, movementSpeedMax);
movementDistance = Random.Range(movementDistanceMin, movementDistanceMax);
patternNumber = RandomizeTargetPattern();
}
// Update is called once per frame
void Update()
{
float ySin = Mathf.Sin(Time.time * movementSpeed) * movementDistance;
float xCos = Mathf.Cos(Time.time * movementSpeed) * movementDistance;
//Debug.Log("Sin = " + ySin);
//Debug.Log("Cos = " + xCos);
switch (patternNumber)
{
case 0:
// Vertical Pattern
//Debug.Log("Pattern 0 selected");
newPosition = new Vector3(0.0f, ySin, transform.position.z);
movementWave = Vector3.zero;
break;
case 1:
// Horizontal Pattern
//Debug.Log("Pattern 1 selected");
newPosition = new Vector3(xCos, 0.0f, transform.position.z);
movementWave = Vector3.zero;
break;
case 2:
// Circle Pattern
//Debug.Log("Pattern 2 selected");
newPosition = new Vector3(xCos, ySin, transform.position.z);
movementWave = Vector3.zero;
break;
default:
break;
}
transform.position = newPosition + startPosition + movementWave;
}
// This destroys both the projectile and the target. An animator event instantiates
// Target particle effects. After the object is destroyed, the score is increased.
void OnTriggerEnter2D(Collider2D collision)
{
animator.SetBool("TargetDestroyed", true);
Destroy(gameObject, 0.5f);
if (collision.CompareTag("Projectile"))
{
Destroy(collision.gameObject);
}
scoreManager.IncreaseScore(targetPoints);
}
// This method exists for the sake of an animation event only being able to call functions with 0 or 1 parameters
public void InstantiateParticles()
{
Instantiate(targetDestroyedParticles, transform.position, transform.rotation);
}
// This is purely for returning a random number for the switch statement in Update
int RandomizeTargetPattern()
{
int x = Random.Range(0, 3);
return x;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject gameOverScreen;
public GameObject player;
private bool gameIsOver = false;
private ScoreManager scoreManager;
private HealthManager healthManager;
// Start is called before the first frame update
void Start()
{
gameIsOver = false;
if (gameOverScreen == null)
{
gameOverScreen = GameObject.FindWithTag("Game Over");
}
if (player == null)
{
player = GameObject.FindWithTag("Player");
player.SetActive(true);
}
scoreManager = gameObject.GetComponent<ScoreManager>();
healthManager = gameObject.GetComponent<HealthManager>();
}
//Displays the Game Over screen and disables the player
public void GameOver()
{
gameIsOver = true;
gameOverScreen.SetActive(true);
player.SetActive(false);
}
public void RestartGame()
{
gameIsOver = false;
gameOverScreen.SetActive(false);
player.SetActive(true);
scoreManager.ResetScore();
healthManager.ResetHealth();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class HealthManager : MonoBehaviour
{
public int startingHealth = 3;
public int damage = 1;
private int currentHealth;
private TextMeshProUGUI healthText;
private GameManager gameManager;
// Start is called before the first frame update
void Start()
{
if (healthText == null)
{
healthText = GameObject.FindWithTag("Health").GetComponent<TextMeshProUGUI>();
}
if (gameManager == null)
{
gameManager = GameObject.Find("Game Manager").GetComponent<GameManager>();
}
currentHealth = startingHealth;
healthText.text = "Lives: " + startingHealth;
}
public void UpdateHealth()
{
currentHealth -= damage;
if (currentHealth < 1)
{
gameManager.GameOver();
}
healthText.text = "Lives: " + currentHealth;
}
public void ResetHealth()
{
currentHealth = startingHealth;
healthText.text = "Lives: " + currentHealth;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public int jumpSpeed = 5;
public float shotDelayTime = 0.5f;
public Projectile projectile;
public AudioClip projectileSound;
bool jumpPressed = false;
bool canShoot = true;
Rigidbody2D playerRigidBody;
Animator playerAnimator;
AudioSource playerAudio;
// Start is called before the first frame update
void Start()
{
playerRigidBody = GetComponent<Rigidbody2D>();
playerAnimator = GetComponent<Animator>();
playerAudio = GetComponent<AudioSource>();
}
//Allows the player to jump and shoot with the specified controls
void Update()
{
jumpPressed = Input.GetKey(KeyCode.Space);
if (Input.GetKeyDown(KeyCode.Mouse0) && canShoot == true)
{
Instantiate(projectile, transform.position, transform.rotation);
playerAudio.PlayOneShot(projectileSound);
canShoot = false;
StartCoroutine(DelayShot(shotDelayTime));
}
}
//FixedUpdate is being used to make sure that jumping happens as smoothly as possible
void FixedUpdate()
{
if (jumpPressed == true)
{
playerRigidBody.velocity = new Vector2(0, jumpSpeed);
playerAnimator.SetBool("Jumping", true);
}
}
//A simple coroutine which keeps the player from spamming bullets
IEnumerator DelayShot(float delayTime)
{
yield return new WaitForSeconds(delayTime);
canShoot = true;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
playerAnimator.SetBool("Jumping", false);
}
}
}
Website concept art by Tyler Osgood. You can find him at TylerOsgoodArt.com.
Copyright 2022 Daniel Hassett. All Rights Reserved.