This page contains interactive work for Project Anaximander.
Contents
Unity

We played around in Unity to practice coding.
Bellow is all the code that I made in this small test project in Unity. It includes: camera follow (2 types), player movement (walking, sprinting, jump, dash and teleport), player health, damage, checkpoints and projectiles.
Camera Follow Code
This code has the camera follow the player around.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
// THE BASIC CODE FOR A 2D CAMERA FOLLOW
// FOR FLOATY CAMERA THE CAMERA NEEDS A RIGIDBODY2D WITH EVERYTHING SET TO 0
// NEED TO SET THE RIGIDBODY2D TO BE THE PLAYERS RB2D (IN UNITY)
[SerializeField] Rigidbody2D player;
// SET THE SPEED OF THE FLOATY CAMERA
[SerializeField] float cameraSpeed = 1;
// BOOLEAN FOR FLOATY CAMERA
[SerializeField] bool floatyCamera = false;
Camera mainCamera;
Rigidbody2D cameraRB;
// START IS CALLED BEFORE THE FIRST FRAME UPDATE
void Start()
{
mainCamera = GetComponent<Camera>();
cameraRB = GetComponent<Rigidbody2D>();
}
// UPDATE IS CALLED ONCE PER FRAME
void Update()
{
if (floatyCamera == false)
{
// INSTANT CAMERA FOLLOW
mainCamera.transform.position = new Vector3(player.position.x, player.position.y, mainCamera.transform.position.z);
}
else
{
// FLOATY
cameraRB.velocity = new Vector2((player.position.x - mainCamera.transform.position.x) * cameraSpeed, (player.position.y - mainCamera.transform.position.y) * cameraSpeed);
}
}
}
Player Code
This code allowed the play to move around and interact with the world.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
// BASIC PLAYER MOVEMENT 2D
// THE PLAYER
Rigidbody2D playerRB;
// SETTINGS
[SerializeField] Canvas hUD;
[SerializeField] Rigidbody2D teleportCircleRB;
[Space]
[SerializeField] bool topDownCamera = false;
[Space]
[SerializeField] float health = 3;
[SerializeField] float deathTimer = 15;
[Space]
[SerializeField] float speed = 5;
[SerializeField] bool noSprint = false;
[SerializeField] float sprintMultiplier = 2;
[Space]
[SerializeField] bool noJump = false;
[SerializeField] float jumpPower = 5;
[SerializeField] float numberOfJumps = 2;
[Space]
[SerializeField] bool noDash = false;
[SerializeField] float dashPower = 5;
[SerializeField] float dashCooldown = 15;
[Space]
[SerializeField] float strength = 10;
[SerializeField] float teleportCooldown = 15;
// USED FOR DIFFERENT COOLDOWNS
System.DateTime deathStartTime;
System.DateTime dashTime;
System.DateTime teleportTime;
// STOPS MOVEMENT WHEN DEAD
bool disableMovement = false;
// STOPS DASH WHEN ON COOLDOWN
bool canDash = true;
// STOPS TELEPORT WHEN ON COOLDOWN
bool teleportOnCooldown = false;
// KEEPS COUNT OF THE AMOUNT OF JUMPS LEFT
float currentJumps;
// HOLDS THE RESPAWN LOCATION
Vector2 respawnLocation;
// STOPS THE PLAYER FROM USING OLD CHECKPOINTS
float checkPoint = 0;
// HOLDS THE HP AT FULL HP
float baseHealth;
// HOLDS THE START POSITION FOR THE TELEPORT CIRCLE
Vector2 startPosition;
// HOLDS THE UNIT VECTOR OF THE THROW
float unitVecX;
float unitVecY;
// IS THE CIRCLE IN MOVEMENT
bool calculatingProjectile = false;
// IS THE CIRCLE READY TO BE TELEPORTED TOO
bool readyToTeleport = false;
// START IS CALLED BEFORE THE FIRST FRAME UPDATE
void Start()
{
// SETS THE RIGIDBODY
playerRB = GetComponent<Rigidbody2D>();
respawnLocation = playerRB.position;
baseHealth = health;
}
// UPDATE IS CALLED ONCE PER FRAME
void Update()
{
// THIS STOPS MOVEMENT IF YOU'RE DEAD
if (disableMovement == false)
{
// CHANGES THE MOVEMENT FROM A SIDE SCROLLER TO A TOP DOWN GAME
if (topDownCamera == false)
{
// SIDE SCROLLER MOVEMENT WITH SPRINTING
if (Input.GetKey(KeyCode.LeftShift) && noSprint == false)
{
playerRB.velocity = new Vector2(Input.GetAxisRaw("Horizontal") * speed * sprintMultiplier, playerRB.velocityY);
}
else
{
playerRB.velocity = new Vector2(Input.GetAxisRaw("Horizontal") * speed, playerRB.velocityY);
}
if (noJump == false)
{
// JUMP
if (currentJumps > 0 && Input.GetButtonDown("Jump"))
{
playerRB.AddForce(new Vector2(0, jumpPower), ForceMode2D.Impulse);
currentJumps -= 1;
}
}
}
else
{
// TOP DOWN MOVEMENT WITH SPRINTING
if (Input.GetKey(KeyCode.LeftShift) && noSprint == false)
{
playerRB.velocity = new Vector2(Input.GetAxisRaw("Horizontal") * speed * sprintMultiplier, Input.GetAxisRaw("Vertical") * speed * sprintMultiplier);
}
else
{
playerRB.velocity = new Vector2(Input.GetAxisRaw("Horizontal") * speed, Input.GetAxisRaw("Vertical") * speed);
}
}
// DASH
if (noDash == false)
{
if (Input.GetKeyDown(KeyCode.LeftControl) && canDash == true)
{
playerRB.AddForce(new Vector2(dashPower * 1000, 0));
canDash = false;
dashTime = System.DateTime.Now;
hUD.GetComponent<HUD>().SendMessage("DeactivateDash");
}
// DASH COOLDOWN
if (canDash == false)
{
if (System.DateTime.Now - dashTime > System.TimeSpan.FromSeconds(dashCooldown))
{
canDash = true;
hUD.GetComponent<HUD>().SendMessage("ActivateDash", 1);
}
else
{
hUD.GetComponent<HUD>().SendMessage("ActivateDash", (System.DateTime.Now - dashTime).TotalSeconds / dashCooldown);
}
}
}
// TELEPORT
if (Input.GetKeyDown(KeyCode.E) && calculatingProjectile == false && readyToTeleport == false && teleportOnCooldown == false)
{
// CALCULATES THE UNIT VECTOR BETWEEN THE PLAYER AND MOUSE
startPosition = playerRB.position;
teleportCircleRB.GetComponent<SpriteRenderer>().enabled = true;
float vecX = Input.mousePosition.x - (Screen.width / 2);
float vecY = Input.mousePosition.y - (Screen.height / 2);
float magnitude = Mathf.Sqrt(Mathf.Pow(vecX, 2f) + Mathf.Pow(vecY, 2f));
unitVecX = vecX / (magnitude);
unitVecY = vecY / (magnitude);
teleportTime = System.DateTime.Now;
calculatingProjectile = true;
}
// CALCULATES THE PROJECTILE AND MOVES THE CIRCLE
else if (calculatingProjectile == true)
{
float timePasted = System.Convert.ToSingle((System.DateTime.Now - teleportTime).TotalSeconds);
teleportCircleRB.position = startPosition + new Vector2(strength * unitVecX * timePasted + 0.5f * Mathf.Pow(timePasted, 2f), strength * unitVecY * timePasted + 0.5f * -9.8f * Mathf.Pow(timePasted, 2f));
}
// TELEPORTS THE PLAYER
else if (Input.GetKeyDown(KeyCode.E) && readyToTeleport == true)
{
playerRB.position = teleportCircleRB.position;
teleportCircleRB.GetComponent<SpriteRenderer>().enabled = false;
readyToTeleport = false;
teleportTime = System.DateTime.Now;
teleportOnCooldown = true;
hUD.GetComponent<HUD>().SendMessage("DeactivateTeleport");
}
// TELEPORT COOLDOWN
else if (teleportOnCooldown == true)
{
if (System.DateTime.Now - teleportTime > System.TimeSpan.FromSeconds(teleportCooldown))
{
teleportOnCooldown = false;
hUD.GetComponent<HUD>().SendMessage("ActivateTeleport", 1);
}
else
{
hUD.GetComponent<HUD>().SendMessage("ActivateTeleport", (System.DateTime.Now - teleportTime).TotalSeconds / teleportCooldown);
}
}
}
else
{
// DEATH TIMER
if (System.DateTime.Now - deathStartTime > System.TimeSpan.FromSeconds(deathTimer))
{
disableMovement = false;
playerRB.position = respawnLocation;
health = baseHealth;
hUD.GetComponent<HUD>().SendMessage("DisplayHealth", health);
}
hUD.GetComponent<HUD>().SendMessage("UpdateDeathTimer", Mathf.Floor((float)(deathTimer - (System.DateTime.Now - deathStartTime).TotalSeconds)));
}
}
// CALLED ON EVERY COLLISION SET AS A TRIGGER
private void OnTriggerEnter2D(Collider2D collision)
{
// RESETS JUMPS WHEN YOU HIT THE GROUND
if (collision.gameObject.tag == "Ground")
{
currentJumps = numberOfJumps;
}
}
// DEALS DAMAGE AND CHECKS IF YOU'VE DIED
void DamageDealt(float healthRemoved)
{
if (health - healthRemoved > 0)
{
health -= healthRemoved;
}
else
{
disableMovement = true;
deathStartTime = System.DateTime.Now;
health = 0;
}
hUD.GetComponent<HUD>().SendMessage("DisplayHealth", health);
}
// CHANGES RESPAWN LOCATION
void SetRespawnLocation(Vector3 data)
{
float checkPointNum = data.z;
if (checkPointNum > checkPoint)
{
Vector2 newRespawn = new Vector2(data.x, data.y);
checkPoint = checkPointNum;
respawnLocation = newRespawn;
}
}
// STOPS TELEPORT CIRCLE FROM MOVING
void StopCircle()
{
calculatingProjectile = false;
readyToTeleport = true;
}
}
HUD Code
This code allowed other things to change object on the HUD.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEngine.Rendering.PostProcessing;
public class HUD : MonoBehaviour
{
[SerializeField] RawImage dashBar;
[SerializeField] RawImage teleportBar;
[SerializeField] TextMeshProUGUI healthText;
[SerializeField] TextMeshProUGUI deathText;
[SerializeField] TextMeshProUGUI deathTimer;
[SerializeField] Camera mainCamera;
void ActivateDash(float decimalLength)
{
dashBar.rectTransform.sizeDelta = new Vector2(100 * decimalLength, 25f);
if (decimalLength == 1)
{
dashBar.color = Color.white;
}
}
void DeactivateDash()
{
dashBar.rectTransform.sizeDelta = new Vector2(0, 25f);
dashBar.color = Color.red;
}
void ActivateTeleport(float decimalLength)
{
teleportBar.rectTransform.sizeDelta = new Vector2(100 * decimalLength, 25f);
if (decimalLength == 1)
{
teleportBar.color = Color.white;
}
}
void DeactivateTeleport()
{
teleportBar.rectTransform.sizeDelta = new Vector2(0, 25f);
teleportBar.color = Color.red;
}
void DisplayHealth(float health)
{
healthText.text = "Health: " + health.ToString();
if (health == 0)
{
deathText.enabled = true;
deathTimer.enabled = true;
mainCamera.GetComponent<PostProcessLayer>().enabled = true;
}
else
{
deathText.enabled = false;
deathTimer.enabled = false;
mainCamera.GetComponent<PostProcessLayer>().enabled = false;
}
}
void UpdateDeathTimer(float time)
{
deathTimer.text = time.ToString();
}
}
Checkpoints Code
This code allowed objects to be checkpoints and to send their location to the player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Checkpoint : MonoBehaviour
{
[SerializeField] float checkPointNumber;
// WHEN THE PLAYER TOUCHES THE CHECKPOINT IT SENDS THE NECESSARY INFORMATION TO THE PLAYER SO IT CAN SET ITS NEW RESPAWN IF ITS A FUTHER CHECKPOINT
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Player")
{
Vector3 parameter = new Vector3(GetComponent<PolygonCollider2D>().transform.position.x, GetComponent<PolygonCollider2D>().transform.position.y, checkPointNumber);
collision.gameObject.SendMessage("SetRespawnLocation", parameter);
}
}
}
Projectile Code
This code stopped a projectile from moving once it has hit the ground.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : MonoBehaviour
{
[SerializeField] Rigidbody2D playerRB;
// TELLS THE PLAYER THAT THE CIRCLE HAS TOUCHED GROUND
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Ground")
{
playerRB.SendMessage("StopCircle");
}
}
}
Damage Code
This code allowed object to damage the player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DealDamage : MonoBehaviour
{
[SerializeField] float damage = 1;
// TELLS THE PLAYER THAT DAMAGE WAS DEALT AND HOW MUCH WAS DEALT
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Player")
{
collision.gameObject.GetComponent<PlayerControl>().SendMessage("DamageDealt", damage);
}
}
}
