Skip to content

Instantly share code, notes, and snippets.

@polygonalcube
Last active February 8, 2026 15:54
Show Gist options
  • Select an option

  • Save polygonalcube/bdc63dc4b6c48eab4d7fc73dbfbd8fea to your computer and use it in GitHub Desktop.

Select an option

Save polygonalcube/bdc63dc4b6c48eab4d7fc73dbfbd8fea to your computer and use it in GitHub Desktop.
Power Forsaker (Unity, C#)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AbilityLossGate : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Player")
{
PlayerLogic playerScript = col.gameObject.GetComponent<PlayerLogic>();
playerScript.spawnPoint = col.gameObject.transform.position;
AbilityMenu.choosingAbility = true;
Destroy(gameObject);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraLogic : MonoBehaviour
{
public Camera cam;
public Transform target;
public Vector3 offset;
public float orthoSize = 5f;
void Start()
{
cam = GetComponent<Camera>();
cam.orthographicSize = orthoSize;
}
void LateUpdate()
{
transform.position = target.position + offset;
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EndScreen : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerLogic : MonoBehaviour
{
Rigidbody2D rb;
public SpriteRenderer playerGraphic;
public Animator anim;
enum states
{
regular,
dash,
groundPound,
wallJump
}
states state;
public float accel = 10f;
public float decel = 10f;
float xSpeed;
float ySpeed;
public Vector2 maxSpeed = new Vector2(7f, 99f);
public float jumpHeight = 2f;
bool isGrounded = false;
public Transform groundCheck;
public float groundDistance = 0.55f;
public LayerMask groundMask;
public bool canWalk = true;
public bool canJump = true;
public bool canDoubleJump = true;
bool usedExtraJump = false;
public bool canDash = true;
bool hasDashed = false;
int dirFacing = 1;
public float dashDist = 15f;
public float dashDecel = 30f;
public bool canWallJump = true;
bool wallLeft = false;
bool wallRight = false;
float wallJumpTimer = 0f;
public float wallJumpTimerSet = 1f;
public Transform wallCheckLeft;
public Transform wallCheckRight;
public Vector2 wallDistance = new Vector2(.2f, .5f);
public bool canGroundPound = true;
public float gPGravityScale = 10f;
public bool canGlide = true;
float defaultGravityScale;
public float newGravityScale = .3f;
public float maxGlideYVelocity = 5f;
public Vector3 spawnPoint;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
state = states.regular;
canWalk = true;
canJump = true;
canDoubleJump = true;
usedExtraJump = false;
canDash = true;
canWallJump = true;
canGroundPound = true;
canGlide = true;
defaultGravityScale = rb.gravityScale;
spawnPoint = transform.position;
}
void Update()
{
switch (state)
{
case states.regular:
float xAxis = Input.GetAxisRaw("Horizontal"); //variable that represents horizontal input
if (xAxis < 0) //determines direction player is facing from input
{
dirFacing = -1;
}
else if (xAxis > 0)
{
dirFacing = 1;
}
UpdateGraphic();
if (canWalk)
{
if (Mathf.Abs(xAxis) != 0)
{
xSpeed += accel * xAxis * Time.deltaTime;
}
else
{
xSpeed += decel * Sign(-xSpeed) * Time.deltaTime;
if ((Mathf.Abs(xSpeed) <= decel * Time.deltaTime) || (Mathf.Abs(xSpeed) <= 0.1f))
{
xSpeed = 0;
}
}
}
//state changing actions
if (canDash && !hasDashed && Input.GetButtonDown("Dash")) //change state to dash
{
hasDashed = true;
xSpeed = dashDist * dirFacing;
rb.velocity = new Vector2(xSpeed, 0);
rb.gravityScale = 0;
state = states.dash;
break;
}
if (canGroundPound && Input.GetButtonDown("Down") && !isGrounded) //change state to ground pound
{
xSpeed = 0;
rb.gravityScale = gPGravityScale;
state = states.groundPound;
break;
}
wallLeft = Physics2D.OverlapBox(wallCheckLeft.position, wallDistance, 0f, groundMask);
wallRight = Physics2D.OverlapBox(wallCheckRight.position, wallDistance, 0f, groundMask);
if (canWallJump && Input.GetButton("Jump") && (wallLeft || wallRight)) //change state to wall jump
{
if (wallLeft)
{
dirFacing = 1;
}
else
{
dirFacing = -1;
}
UpdateGraphic();
rb.velocity = new Vector2(maxSpeed.x * dirFacing, Mathf.Sqrt(Mathf.Abs(jumpHeight * -2f * (Physics2D.gravity.y * rb.gravityScale))));
wallJumpTimer = wallJumpTimerSet;
state = states.wallJump;
break;
}
//caps the speed of the player on both axes
if (Mathf.Abs(xSpeed) > maxSpeed.x * Mathf.Abs(xAxis))
{
xSpeed = maxSpeed.x * Sign(xAxis);
}
if (Mathf.Abs(ySpeed) > maxSpeed.y)
{
ySpeed = maxSpeed.y * Sign(ySpeed);
}
if ((Input.GetButton("Extra") && canGlide) && (Mathf.Abs(ySpeed) > maxGlideYVelocity))
{
ySpeed = maxGlideYVelocity * Sign(ySpeed);
}
rb.velocity = new Vector2(xSpeed, rb.velocity.y); //sets horizontal velocity
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundDistance, groundMask);
if (isGrounded)
{
hasDashed = false;
usedExtraJump = false;
if (Input.GetButtonDown("Jump") && canJump)
{
rb.velocity = new Vector2(rb.velocity.x, Mathf.Sqrt(Mathf.Abs(jumpHeight * -2f * (Physics2D.gravity.y * rb.gravityScale))));
}
}
else
{
if (Input.GetButtonDown("Jump") && canDoubleJump && !usedExtraJump)
{
usedExtraJump = true;
rb.velocity = new Vector2(rb.velocity.x, Mathf.Sqrt(Mathf.Abs(jumpHeight * -2f * (Physics2D.gravity.y * rb.gravityScale))));
}
if (Input.GetButton("Extra") && canGlide && rb.velocity.y < -1f)
{
rb.gravityScale = newGravityScale;
}
else
{
rb.gravityScale = defaultGravityScale;
}
}
break;
case states.dash: //player dash state
xSpeed += dashDecel * Sign((float)-dirFacing) * Time.deltaTime;
if ((Mathf.Abs(xSpeed) <= dashDecel * Time.deltaTime) || (Mathf.Abs(xSpeed) <= 0.1f))
{
xSpeed = 0;
rb.gravityScale = defaultGravityScale;
state = states.regular;
break;
}
rb.velocity = new Vector2(xSpeed, 0);
break;
case states.groundPound: //player ground pound state
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundDistance, groundMask);
if (isGrounded)
{
rb.gravityScale = defaultGravityScale;
state = states.regular;
break;
}
break;
case states.wallJump: ///player wall jump state
wallJumpTimer -= Time.deltaTime;
wallLeft = Physics2D.OverlapBox(wallCheckLeft.position, wallDistance, 0f, groundMask);
wallRight = Physics2D.OverlapBox(wallCheckRight.position, wallDistance, 0f, groundMask);
if (canWallJump && Input.GetButton("Jump") && (wallLeft || wallRight))
{
if ((dirFacing == 1) && wallRight)
{
dirFacing = -1;
rb.velocity = new Vector2(maxSpeed.x * dirFacing, Mathf.Sqrt(Mathf.Abs(jumpHeight * -2f * (Physics2D.gravity.y * rb.gravityScale))));
wallJumpTimer = wallJumpTimerSet;
}
else if ((dirFacing == -1) && wallLeft)
{
dirFacing = 1;
rb.velocity = new Vector2(maxSpeed.x * dirFacing, Mathf.Sqrt(Mathf.Abs(jumpHeight * -2f * (Physics2D.gravity.y * rb.gravityScale))));
wallJumpTimer = wallJumpTimerSet;
}
UpdateGraphic();
}
if (wallJumpTimer <= 0)
{
state = states.regular;
break;
}
break;
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Out of Bounds")
{
xSpeed = 0;
ySpeed = 0;
transform.position = spawnPoint;
}
if (col.gameObject.tag == "End Goal")
{
SceneManager.LoadScene(2);
}
if (col.gameObject.tag == "Enemy")
{
if ((state == states.dash) || (state == states.groundPound))
{
Destroy(col.gameObject);
}
else
{
transform.position = spawnPoint;
}
}
if (col.gameObject.tag == "Destructible")
{
if (state == states.groundPound)
{
Destroy(col.gameObject);
}
}
}
void UpdateGraphic()
{
if (dirFacing == -1)
{
playerGraphic.flipX = true;
}
if (dirFacing == 1)
{
playerGraphic.flipX = false;
}
if ((state == states.regular) && (Mathf.Abs(xSpeed) > 0))
{
anim.Play("Player_Walk");
}
else
{
anim.Play("Player_Idle");
}
}
//proper sign method that makes 0 act like 0
int Sign(float var)
{
if (var < 0)
{
return -1;
}
else if (var > 0)
{
return 1;
}
else
{
return 0;
}
}
//allows for the player ground check sphere and wall check boxes to be seen in the editor
void OnDrawGizmosSelected()
{
if (groundCheck == null)
{
return;
}
Gizmos.DrawWireSphere(groundCheck.position, groundDistance);
if (wallCheckLeft == null)
{
return;
}
Gizmos.DrawWireCube(wallCheckLeft.position, wallDistance);
if (wallCheckRight == null)
{
return;
}
Gizmos.DrawWireCube(wallCheckRight.position, wallDistance);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class TitleScreen : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
SceneManager.LoadScene(1);
}
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment