Skip to content

Instantly share code, notes, and snippets.

@kurtdekker
Created July 8, 2021 16:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurtdekker/48940fd577d9b4b94230c29aab688bf9 to your computer and use it in GitHub Desktop.
Save kurtdekker/48940fd577d9b4b94230c29aab688bf9 to your computer and use it in GitHub Desktop.
Simple attack sequencing, timers, no coroutines, just state machine with timers
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// @kurtdekker
//
// from Unity forums: https://forum.unity.com/threads/logic-to-create-turns-of-attacks.1137946/
//
// goal: a random attack starts in 2-5 seconds, you have 1 second to defend against it
//
// implementation: simple state machine based on timers
//
// To use:
// - make an empty scene
// - add a single GameObject
// - put this script on it
// - press PLAY
// - pay attention to the console
//
public class AttackSequencingDemo : MonoBehaviour
{
// how long between attacks
float randomCooldownTimer;
// if greater than zero, an attack is inbound
float attackIsUnderwayCountdown;
// goes up if you defend
int score;
// needed to win
const int ScoreRequired = 5;
// goes down if you fail to defend, game over at 0 hp
int lifeHitpoints = 3;
// it will choose one of these keys to defend
KeyCode[] possibleDefenseKeys = new KeyCode[]
{
KeyCode.A, KeyCode.S, KeyCode.D,
};
KeyCode chosenDefenseKey;
string GameStateDetails()
{
return "Score: " + score + ", HP: " + lifeHitpoints;
}
void UpdatePossiblyInitiateAttack()
{
// handles first and subsequent timer-before-attack-initiates
if (randomCooldownTimer <= 0)
{
Debug.Log( "Get ready for a random attack... incoming...");
// choose a random time before attack begins
randomCooldownTimer = Random.Range( 2.0f, 5.0f);
}
bool itIsTimeToAttack = false;
// are we preparing to initiate attack?
if (randomCooldownTimer > 0)
{
randomCooldownTimer -= Time.deltaTime;
// detects transition from greater than zero to zero or below
if (randomCooldownTimer <= 0)
{
randomCooldownTimer = 0;
itIsTimeToAttack = true;
}
}
// it is on like Donkey Kong
if (itIsTimeToAttack)
{
// start countdown
attackIsUnderwayCountdown = 1.0f;
// choose how to defend
chosenDefenseKey = possibleDefenseKeys[ Random.Range( 0, possibleDefenseKeys.Length)];
Debug.Log( "ATTACK BEGINS! Attack pending in 1 second! Press " + chosenDefenseKey + " to defend!!");
}
}
void CheckForSpammedKeys()
{
foreach( var key in possibleDefenseKeys)
{
if (Input.GetKeyDown( key))
{
score--;
if (score < 0)
{
score = 0;
}
Debug.Log( "PENALTY FOR SPAMMING! " + GameStateDetails());
// NOTE: even if you spam, the attack continues!
}
}
}
void UpdatePlayerResponseToAttacks()
{
// an attack countdown is in progress!
if (attackIsUnderwayCountdown > 0)
{
if (Input.GetKeyDown( chosenDefenseKey))
{
attackIsUnderwayCountdown = 0;
score++;
Debug.Log( "DEFENDED! " + GameStateDetails());
return;
}
else
{
CheckForSpammedKeys();
}
attackIsUnderwayCountdown -= Time.deltaTime;
if (attackIsUnderwayCountdown <= 0)
{
attackIsUnderwayCountdown = 0;
lifeHitpoints--;
Debug.Log( "YOU GOT HIT!! " + GameStateDetails());
return;
}
}
else // you are spamming keys... naughty!
{
CheckForSpammedKeys();
}
}
void UpdateHandleWinLose()
{
if (lifeHitpoints <= 0)
{
Debug.Log( "YOU DIED!");
Destroy(this);
return;
}
if (score >= ScoreRequired)
{
Debug.Log( "YOU WIN!");
Destroy(this);
return;
}
}
void Update()
{
// only if no attack is pending
if (attackIsUnderwayCountdown <= 0)
{
UpdatePossiblyInitiateAttack();
}
UpdatePlayerResponseToAttacks();
UpdateHandleWinLose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment