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);
        }
    }
}

Project Anaximander Demo Video

Game Download