From 0843c3619923614493bbcbb460ff232da5518aa7 Mon Sep 17 00:00:00 2001 From: Adrian Paschkowski <git@wasdennnoch.me> Date: Sun, 18 Apr 2021 19:28:24 +0200 Subject: [PATCH] Document Classes --- Assets/Scripts/BaseCameraController.cs | 5 +- Assets/Scripts/Fighters/AntiPlayer.cs | 16 +++-- Assets/Scripts/Fighters/Archer.cs | 17 +---- Assets/Scripts/Fighters/Bandit.cs | 2 - Assets/Scripts/Fighters/Enemy.cs | 8 ++- Assets/Scripts/Fighters/Fighter.cs | 29 +++++---- Assets/Scripts/Fighters/Tank.cs | 2 - Assets/Scripts/RoundController.cs | 7 ++- Assets/Scripts/StatsManager.cs | 19 +++--- Assets/Scripts/Store/Opponent.cs | 2 +- Assets/Scripts/Store/SpawnEnemy.cs | 29 --------- Assets/Scripts/Store/SpawnEnemy.cs.meta | 11 ---- Assets/Scripts/Store/StoreStateHandler.cs | 2 +- Assets/Scripts/UI/CurrentManaText.cs | 8 +-- Assets/Scripts/UI/DamageIndicatorCanvas.cs | 5 +- Assets/Scripts/UI/DamageIndicatorText.cs | 7 ++- Assets/Scripts/UI/DragDestroyController.cs | 19 ++++-- Assets/Scripts/UI/HealthBarController.cs | 3 +- Assets/Scripts/UI/OpponentDragSpawner.cs | 14 ++++- Assets/Scripts/UI/RoundControllerButton.cs | 3 +- Assets/Scripts/Upgrades/Upgrade.cs | 4 +- Assets/Scripts/Upgrades/UpgradeController.cs | 65 +++++++++++--------- Assets/Scripts/utils/Box.cs | 4 +- Assets/Scripts/utils/Interpolator.cs | 5 +- Assets/Scripts/utils/InterpolatorQueue.cs | 5 +- 25 files changed, 142 insertions(+), 149 deletions(-) delete mode 100644 Assets/Scripts/Store/SpawnEnemy.cs delete mode 100644 Assets/Scripts/Store/SpawnEnemy.cs.meta diff --git a/Assets/Scripts/BaseCameraController.cs b/Assets/Scripts/BaseCameraController.cs index 3959709..a2eb4db 100644 --- a/Assets/Scripts/BaseCameraController.cs +++ b/Assets/Scripts/BaseCameraController.cs @@ -4,6 +4,9 @@ using System; using System.Collections.Generic; using UnityEngine; +// Controls Camera movement. The user may control the Camera using the Keyboard or by +// moving the mouse close to the edge of the screen. Scripts may disable user movement +// and instead smoothly animate the camera to a specific position and a specific zoom. public class BaseCameraController : MonoBehaviour { @@ -248,7 +251,7 @@ public class BaseCameraController : MonoBehaviour Debug.DrawLine(worldEdges.topLeft, worldEdges.bottomLeft, color); } - // Update the size of the bounds + // Update the size of the edge bounds public void RecalculateBounds(float newInset) { RecalculateBounds(new Vector2(newInset, newInset)); diff --git a/Assets/Scripts/Fighters/AntiPlayer.cs b/Assets/Scripts/Fighters/AntiPlayer.cs index 7744a8e..afe1795 100644 --- a/Assets/Scripts/Fighters/AntiPlayer.cs +++ b/Assets/Scripts/Fighters/AntiPlayer.cs @@ -1,7 +1,7 @@ -using System.Collections; using System.Collections.Generic; using UnityEngine; +// The main opponent of yours. Defeat him and you win. public class AntiPlayer : Fighter, IFighterCallback { @@ -33,17 +33,19 @@ public class AntiPlayer : Fighter, IFighterCallback var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position; var scale = transform.localScale; - // Always face the target Enemy + // Always face the target Enemy. Flip the scale to also flip the position of the attack hitbox. scale.x = vectorToNextEnemy.x < 0 ? -initalScale.x : initalScale.x; transform.localScale = scale; // Run towards target enemy if too far away if (Mathf.Abs(vectorToNextEnemy.x) > maxDistanceToEnemy) { - animator.SetInteger("AnimState", 1); // Run + animator.SetInteger("AnimState", 1); // Run Animation rigidbody.velocity = new Vector2(Mathf.Sign(vectorToNextEnemy.x) * movementSpeed, rigidbody.velocity.y); - } else + } + else { + // No horizontal movement animator.SetInteger("AnimState", 0); rigidbody.velocity = new Vector2(0, rigidbody.velocity.y); } @@ -54,7 +56,7 @@ public class AntiPlayer : Fighter, IFighterCallback { return false; } - // Can only attack when near an Enemy + // Can only attack when close enough to the target Enemy var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position; return Mathf.Abs(vectorToNextEnemy.x) <= maxDistanceToEnemy; } @@ -66,6 +68,7 @@ public class AntiPlayer : Fighter, IFighterCallback void CalculateClosestEnemy() { + // Sort by closest distance enemies.Sort((a, b) => (int)Mathf.Sign(Vector3.Distance(transform.position, a.transform.position) - Vector3.Distance(transform.position, b.transform.position))); currentTargetEnemy = enemies.Count > 0 ? enemies[0] : null; } @@ -90,6 +93,7 @@ public class AntiPlayer : Fighter, IFighterCallback { base.OnRoundStart(); + // Listen for Enemy Death events, used for targeting foreach (var enemy in GameObject.FindGameObjectsWithTag("Enemy")) { var fighter = enemy.GetComponent<Fighter>(); @@ -101,7 +105,7 @@ public class AntiPlayer : Fighter, IFighterCallback public override void OnRoundEnd(bool won) { - if (!alive) + if (!alive) // When the player successfully killed us { damageIndicator.FlashText("Upgrade!", true); StatsManager.instance.UpgradeAntiPlayer(); diff --git a/Assets/Scripts/Fighters/Archer.cs b/Assets/Scripts/Fighters/Archer.cs index 6b962ec..665f919 100644 --- a/Assets/Scripts/Fighters/Archer.cs +++ b/Assets/Scripts/Fighters/Archer.cs @@ -1,21 +1,6 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - public class Archer : Enemy { - //[SerializeField, Tooltip("When the AntiPlayer is closer than this value, change to a combat idle anim")] - //float playerNearDistance = 50f; - - protected override void Awake() - { - base.Awake(); - } - - protected override void Update() - { - base.Update(); - } + // Archers don't have any special abilities } diff --git a/Assets/Scripts/Fighters/Bandit.cs b/Assets/Scripts/Fighters/Bandit.cs index c5a7979..0896ff3 100644 --- a/Assets/Scripts/Fighters/Bandit.cs +++ b/Assets/Scripts/Fighters/Bandit.cs @@ -1,5 +1,3 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; public class Bandit : Enemy diff --git a/Assets/Scripts/Fighters/Enemy.cs b/Assets/Scripts/Fighters/Enemy.cs index 7d76013..c72b4fa 100644 --- a/Assets/Scripts/Fighters/Enemy.cs +++ b/Assets/Scripts/Fighters/Enemy.cs @@ -1,7 +1,7 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; +// Base Enemy class, includes some functionality common to all Enemies, such as a reference +// to the AntiPlayer and that they always face towards it. public abstract class Enemy : Fighter { @@ -55,7 +55,9 @@ public abstract class Enemy : Fighter public override void OnRoundEnd(bool won) { - // Destroy all dead Enemies after a successful round + // Destroy all dead Enemies after a successful round. Otherwise, if either + // the round was lost of the Enemy was still alive at the end of the round, + // it will be resurrected. if (won && !alive) { Destroy(gameObject); diff --git a/Assets/Scripts/Fighters/Fighter.cs b/Assets/Scripts/Fighters/Fighter.cs index 81c4eae..bdff094 100644 --- a/Assets/Scripts/Fighters/Fighter.cs +++ b/Assets/Scripts/Fighters/Fighter.cs @@ -1,4 +1,3 @@ -using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -7,8 +6,9 @@ public interface IFighterCallback void OnFighterDeath(Fighter fighter); } -// Generic subclass for any Fighter on the field, whether it's an Enemy or the AntiPlayer. +// Generic class for any Fighter on the field, whether it's an Enemy or the AntiPlayer. // Contains stats management such as health, attacks, damage, death, etc. +// Listens to round start/end events and updates the internal state accordingly. public abstract class Fighter : MonoBehaviour, IRoundCallback { @@ -16,9 +16,9 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback [SerializeField, Tooltip("Attack every x seconds")] float baseAttackSpeed = 1f; [SerializeField] int baseAttackDamage = 10; [SerializeField] int baseArmor = 1; - [SerializeField, Tooltip("Being hurt may cancel the current Attack animation, aborting the current attack. If this Fighter is hurt within x seconds of the last attack, attack again after attackRetryDelayAfterBeingHurt seconds")] + [SerializeField, Tooltip("Being hurt may cancel the current Attack animation, aborting the current attack. If this Fighter is hurt within x seconds of the last attack, attack again after attackRetryDelayAfterBeingHurt seconds.")] float attackRetryGracePeriod = 0.8f; - [SerializeField, Tooltip("If an attack is being retried, how long to wait until to actually attack again. Gives the Hrt animation time to play out.")] + [SerializeField, Tooltip("If an attack is being retried, how long to wait until to actually attack again. Gives the Hurt animation time to play out.")] float attackRetryDelayAfterBeingHurt = 0.25f; [SerializeField] List<AudioClip> attackBarks; [SerializeField] List<AudioClip> hurtBarks; @@ -26,7 +26,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback public List<IFighterCallback> callbacks = new List<IFighterCallback>(); - protected int maxHealth = 100; // Dynamically valculated based on upgrades + protected int maxHealth = 100; // Dynamically calculated on round start based on upgrades protected int currentHealth = 100; protected float currentHealthPercentage { get => (float) currentHealth / maxHealth; } protected Animator animator; @@ -37,9 +37,10 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback protected BaseCameraController cameraController; protected bool alive { get => currentHealth > 0; } protected bool roundRunning = false; - protected FighterTypes fighterType; - protected string opponentTag; + protected FighterTypes fighterType; // Subclasses should set this accordingly. Used for stats retrieval. + protected string opponentTag; // Subclasses should set this accordingly. Used for hit detection. + // Used to reset values on round end protected Vector3 initalScale; protected Vector3 initalPosition; protected int initialLayer; @@ -74,12 +75,18 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback RoundController.instance.roundCallbacks.Add(this); } + protected virtual void OnDestroy() + { + RoundController.instance.roundCallbacks.Remove(this); + } + protected virtual void Update() { if (alive && roundRunning) { if (CanAttack()) { + // Attack Timer timeSinceLastAttack += Time.deltaTime; var timeUntilNextAttack = baseAttackSpeed - timeSinceLastAttack; if (timeUntilNextAttack <= 0) @@ -96,6 +103,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback } } + // Returns the actual amount of damage dealt, calculated based on armor upgrades. public virtual int DealDamage(int dmg) { if (!alive || !roundRunning) @@ -142,6 +150,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback #if false Debug.Log(string.Format("'{0}' (tag '{1}') collided with '{2}' (tag '{3}') in parent '{4}' (tag '{5}')", name, tag, other.name, other.tag, other.transform.parent ? other.transform.parent.name : null, other.transform.parent ? other.transform.parent.tag : null)); #endif + // If we hit an opponent, deal them damage if (roundRunning && other.CompareTag(opponentTag)) { var damageToDeal = Mathf.RoundToInt(baseAttackDamage * GetStats().damageMultiplier); @@ -162,6 +171,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback public virtual void OnRoundEnd(bool won) { + // Reset everything back to its initial state roundRunning = false; animator.enabled = false; timeSinceLastAttack = float.PositiveInfinity; @@ -174,9 +184,4 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback callbacks.Clear(); healthBarController.SetHealthBarEnabled(false); } - - protected virtual void OnDestroy() - { - RoundController.instance.roundCallbacks.Remove(this); - } } diff --git a/Assets/Scripts/Fighters/Tank.cs b/Assets/Scripts/Fighters/Tank.cs index 0b7da3d..1b833fe 100644 --- a/Assets/Scripts/Fighters/Tank.cs +++ b/Assets/Scripts/Fighters/Tank.cs @@ -1,5 +1,3 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; public class Tank : Enemy diff --git a/Assets/Scripts/RoundController.cs b/Assets/Scripts/RoundController.cs index e62b921..e2375d8 100644 --- a/Assets/Scripts/RoundController.cs +++ b/Assets/Scripts/RoundController.cs @@ -9,6 +9,10 @@ public interface IRoundCallback void OnRoundEnd(bool won); } +// Controls the state of the current round (whether one is currently running or not) +// and provides update callbacks. Listens to Fighter events. If a round is won or lost, +// meaning if the last Fighter of the AntiPlayer died, play the according animation +// and SFX and end the current round. public class RoundController : MonoBehaviour, IFighterCallback { @@ -140,11 +144,12 @@ public class RoundController : MonoBehaviour, IFighterCallback var targetGameSpeed = 0.2f; SetCurrentGameSpeed(targetGameSpeed); cameraController.SetUserControlEnabled(false); - cameraController.AnimateToPosition(fighter.transform.position + new Vector3(0f, 0.75f), 1.5f, 0.125f * targetGameSpeed); + cameraController.AnimateToPosition(fighter.transform.position + new Vector3(0f, 0.75f), 1.5f, 0.25f * targetGameSpeed); Invoke(nameof(StopRoundAfterDeath), targetGameSpeed * restartDelayAfterLastFighterDeath); } } + // Invoked delayed after the last Fighter died to allow death animations to play out void StopRoundAfterDeath() { cameraController.PlayRandomGlobalAudioClip(hasWonLastRound ? roundWinSfx : roundLooseSfx); diff --git a/Assets/Scripts/StatsManager.cs b/Assets/Scripts/StatsManager.cs index 2b78652..c08d3cb 100644 --- a/Assets/Scripts/StatsManager.cs +++ b/Assets/Scripts/StatsManager.cs @@ -50,6 +50,8 @@ public interface IManaChangeCallback void OnManaChanged(int oldValue, int newValue); } +// Provides the current Statistics (buffs) for supported Fighter types as well as +// Mana storage and management. Allows scripts to buy Upgrade or otherwise spend Mana. public class StatsManager : MonoBehaviour, IRoundCallback { @@ -66,7 +68,7 @@ public class StatsManager : MonoBehaviour, IRoundCallback // The currently active statistics for each fighter type public Dictionary<FighterTypes, FighterStats> fighterStats = new Dictionary<FighterTypes, FighterStats>(); - // Information about currently available and purchased upgrades. Should only be read, not modified. + // Information about currently available and purchased Enemy upgrades. Should only be read, not modified. public Dictionary<UpgradeTypes, UpgradeData> upgrades = new Dictionary<UpgradeTypes, UpgradeData>(); // Want to be notified whenever the current Mana amount changes? @@ -96,7 +98,7 @@ public class StatsManager : MonoBehaviour, IRoundCallback return false; } upgrades[type].count++; - RecalculateStatMultipliers(); + RecalculateEnemyStats(); return true; } @@ -135,6 +137,12 @@ public class StatsManager : MonoBehaviour, IRoundCallback } } + // How much a specific Enemy stat is buffed based on how many Upgrades have already been purchased + public float GetTotalEffectMultiplier(UpgradeTypes type) + { + return upgrades[type].GetTotalEffectMultiplier(); + } + public void UpgradeAntiPlayer() { var playerStats = fighterStats[FighterTypes.ANTI_PLAYER]; @@ -144,7 +152,7 @@ public class StatsManager : MonoBehaviour, IRoundCallback fighterStats[FighterTypes.ANTI_PLAYER] = playerStats; } - void RecalculateStatMultipliers() + void RecalculateEnemyStats() { var enemyStats = fighterStats[FighterTypes.ENEMY]; enemyStats.healthMultiplier = upgrades[UpgradeTypes.ENEMY_HEALTH].GetTotalEffectMultiplier(); @@ -153,11 +161,6 @@ public class StatsManager : MonoBehaviour, IRoundCallback fighterStats[FighterTypes.ENEMY] = enemyStats; } - public float GetTotalEffectMultiplier(UpgradeTypes type) - { - return upgrades[type].GetTotalEffectMultiplier(); - } - void Awake() { if (instance == null) diff --git a/Assets/Scripts/Store/Opponent.cs b/Assets/Scripts/Store/Opponent.cs index ea8d1c9..aba7f88 100644 --- a/Assets/Scripts/Store/Opponent.cs +++ b/Assets/Scripts/Store/Opponent.cs @@ -9,6 +9,6 @@ public class Opponent : ScriptableObject public GameObject enemyPrefab; public int enemyCost; public float costMultiplier; - public Vector2 dragPivot; + public Vector2 dragPivot; // Texture offset used for mouse dragging } diff --git a/Assets/Scripts/Store/SpawnEnemy.cs b/Assets/Scripts/Store/SpawnEnemy.cs deleted file mode 100644 index d18d81e..0000000 --- a/Assets/Scripts/Store/SpawnEnemy.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.EventSystems; - -public class SpawnEnemy : MonoBehaviour, IPointerDownHandler, IBeginDragHandler -{ - public void OnBeginDrag(PointerEventData eventData) - { - Debug.Log("Something has happend"); - } - - public void OnPointerDown(PointerEventData eventData) - { - Debug.Log("Something has happend"); - } - - // Start is called before the first frame update - void Start() - { - - } - - // Update is called once per frame - void Update() - { - - } -} diff --git a/Assets/Scripts/Store/SpawnEnemy.cs.meta b/Assets/Scripts/Store/SpawnEnemy.cs.meta deleted file mode 100644 index 984dcf7..0000000 --- a/Assets/Scripts/Store/SpawnEnemy.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e1e4776ca1e2ca04b99c32d12ca966bb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/Store/StoreStateHandler.cs b/Assets/Scripts/Store/StoreStateHandler.cs index 5b8b133..c29f48c 100644 --- a/Assets/Scripts/Store/StoreStateHandler.cs +++ b/Assets/Scripts/Store/StoreStateHandler.cs @@ -1,7 +1,7 @@ -using System.Collections; using System.Collections.Generic; using UnityEngine; +// Responsible for opening/closing the upgradfe store as well as hiding other UI elements. public class StoreStateHandler : MonoBehaviour, IRoundCallback { diff --git a/Assets/Scripts/UI/CurrentManaText.cs b/Assets/Scripts/UI/CurrentManaText.cs index 63b277d..8b8520e 100644 --- a/Assets/Scripts/UI/CurrentManaText.cs +++ b/Assets/Scripts/UI/CurrentManaText.cs @@ -1,11 +1,9 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // Controls the text displaying the current Mana amount. When the player's amount of -// Mana changes, this visually interpolates smoothly between old and new value. -// Additionally, does a color flash effect. +// Mana changes, this visually interpolates smoothly between old and new value and +// does a color flash effect. public class CurrentManaText : MonoBehaviour, IManaChangeCallback { @@ -40,11 +38,11 @@ public class CurrentManaText : MonoBehaviour, IManaChangeCallback currentlyDisplayedValue = (int)Mathf.Lerp(previousMana, StatsManager.instance.GetMana(), animationProgress / manaUpdateTime); manaText.text = currentlyDisplayedValue.ToString(); } - var flashColor = currentlyDisplayedValue > previousMana ? manaGainColor : manaLossColor; if (colorFlashProgress < colorFlashTime) { // Fade flashed color back to default color colorFlashProgress += Time.deltaTime; + var flashColor = currentlyDisplayedValue > previousMana ? manaGainColor : manaLossColor; manaText.color = Color.Lerp(flashColor, defaultColor, colorFlashProgress / colorFlashTime); } } diff --git a/Assets/Scripts/UI/DamageIndicatorCanvas.cs b/Assets/Scripts/UI/DamageIndicatorCanvas.cs index e7cfa2a..88ea1bd 100644 --- a/Assets/Scripts/UI/DamageIndicatorCanvas.cs +++ b/Assets/Scripts/UI/DamageIndicatorCanvas.cs @@ -1,7 +1,7 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; +// A Canvas for displaying how much damage was dealt to an enemy. +// Can also show any kind of other text. public class DamageIndicatorCanvas : MonoBehaviour { @@ -28,6 +28,7 @@ public class DamageIndicatorCanvas : MonoBehaviour transform.localScale = scale; } + // Creates a new, short-lived text element displaying the given text. public void FlashText(string text, bool center = false) { var rect = rectTransform.rect; diff --git a/Assets/Scripts/UI/DamageIndicatorText.cs b/Assets/Scripts/UI/DamageIndicatorText.cs index 22177ca..e3d98a1 100644 --- a/Assets/Scripts/UI/DamageIndicatorText.cs +++ b/Assets/Scripts/UI/DamageIndicatorText.cs @@ -1,8 +1,9 @@ using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; +// The text element used in DamageIndicatorCanvas. Moves upwards and fades out, +// destroying itself once the opacity hits 0. public class DamageIndicatorText : MonoBehaviour { @@ -17,10 +18,10 @@ public class DamageIndicatorText : MonoBehaviour textComponent = GetComponent<Text>(); textComponent.text = text; - StartCoroutine(DoFade()); + StartCoroutine(RiseAndFade()); } - IEnumerator DoFade() + IEnumerator RiseAndFade() { while (textComponent.color.a > 0) { diff --git a/Assets/Scripts/UI/DragDestroyController.cs b/Assets/Scripts/UI/DragDestroyController.cs index 8b4c5d9..343bcca 100644 --- a/Assets/Scripts/UI/DragDestroyController.cs +++ b/Assets/Scripts/UI/DragDestroyController.cs @@ -1,4 +1,3 @@ -using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -8,6 +7,10 @@ public interface IDragDropListener void OnEnemyDeleted(GameObject enemy, Opponent opponent); } +// Allows you to drag and drop existing Enemies around the field. Checks for valid +// drop positions; resets the dragged Enemy to its previous position of the target +// position was invalid (occluded by another Fighter). Also allows for deletion of +// active Enemies. public class DragDestroyController : MonoBehaviour { @@ -32,6 +35,7 @@ public class DragDestroyController : MonoBehaviour int noCollisionLayer; BaseCameraController cameraController; + // Sets the given Enemy to be the active Enemy that can be dragged around and places on the field. public void HandoffEnemy(GameObject enemy, bool skipSound = true) { if (selectedEnemy != null) @@ -51,6 +55,7 @@ public class DragDestroyController : MonoBehaviour } } + // Sets whether Enemies can be dragged around public void SetDraggingEnabled(bool enabled) { draggingEnabled = enabled; @@ -76,12 +81,13 @@ public class DragDestroyController : MonoBehaviour } } - GameObject RayCastForFighter(bool includeAntiHero) + // Returns the Fighter at the current mouse position, optionally including the AntiPlayer + GameObject RayCastForFighter(bool includeAntiPlayer) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit2D hit = Physics2D.GetRayIntersection(ray, fighterRaycastLength, fighterRaycastLayer); - if (hit.collider == null || (!includeAntiHero && hit.collider.gameObject.CompareTag("AntiPlayer"))) + if (hit.collider == null || (!includeAntiPlayer && hit.collider.gameObject.CompareTag("AntiPlayer"))) { return null; } @@ -89,6 +95,7 @@ public class DragDestroyController : MonoBehaviour return hit.collider.transform.gameObject; } + // Deletes the Enemy under the mouse cursor void DeleteHoveredEnemy() { GameObject enemy = RayCastForFighter(false); @@ -101,7 +108,8 @@ public class DragDestroyController : MonoBehaviour cameraController.PlayRandomGlobalAudioClip(removeEnemySfx); } } - + + // Selects the Enemy currently under the mouse cursor to be the one being dragged around void SelectHoveredEnemy() { GameObject enemy = RayCastForFighter(false); @@ -111,6 +119,8 @@ public class DragDestroyController : MonoBehaviour } } + // Set the current Enemie's position to the mouse position, accounting for configured texture offsets. + // Indicates if the current position is occluded by another Fighter. void MoveSelectedEnemy() { if (selectedEnemy != null) @@ -123,6 +133,7 @@ public class DragDestroyController : MonoBehaviour } } + // Drops the active Enemy at the mouse position. void PlaceSelectedEnemy() { if (selectedEnemy != null) diff --git a/Assets/Scripts/UI/HealthBarController.cs b/Assets/Scripts/UI/HealthBarController.cs index c77020c..cbe9066 100644 --- a/Assets/Scripts/UI/HealthBarController.cs +++ b/Assets/Scripts/UI/HealthBarController.cs @@ -1,7 +1,6 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; +// It's a health bar. You know what it does. public class HealthBarController : MonoBehaviour { diff --git a/Assets/Scripts/UI/OpponentDragSpawner.cs b/Assets/Scripts/UI/OpponentDragSpawner.cs index 66c5f72..d8883a3 100644 --- a/Assets/Scripts/UI/OpponentDragSpawner.cs +++ b/Assets/Scripts/UI/OpponentDragSpawner.cs @@ -1,9 +1,12 @@ -using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; +// Allows Enemies to be spawned by dragging them out of the Box. Handles and +// indicates whether the current Enemy can actually be bought, based on price +// and the current round state. Keeps track of the amount of currently placed +// Enemies of this type to calculate costs. public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCallback, IDragDropListener { @@ -30,6 +33,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal var eventTrigger = GetComponent<EventTrigger>(); + // Listen for BeginDrag events var beginDragEvent = new EventTrigger.Entry(); beginDragEvent.eventID = EventTriggerType.BeginDrag; beginDragEvent.callback.AddListener((data) => OnBeginDrag((PointerEventData)data)); @@ -42,6 +46,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal UpdateDisplayStates(); } + // If all conditions are met, buy a new Enemy void OnBeginDrag(PointerEventData eventData) { if (RoundController.instance.roundRunning || !StatsManager.instance.ModifyMana(GetNextOpponentCost())) @@ -56,6 +61,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal UpdateDisplayStates(); } + // Visually indicate whether this Opponent can be purchased void UpdateDisplayStates() { // Enemies call `OnEnemyDeleted()` when they are destroyed. This also happens @@ -110,6 +116,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal if (opponent == this.opponent) { placedOpponentCount--; + // Refund StatsManager.instance.ModifyMana(-GetNextOpponentCost()); UpdateDisplayStates(); } @@ -122,7 +129,10 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal public void OnRoundEnd(bool won) { - // To make sure this is called _after_ enemies might have destroyed itself in this callback + // To make sure this is called _after_ enemies might have destroyed itself + // with this same callback. Their OnRoundEnd may be called after this one. + // Hey look another hack, it's almost as if we didn't have enough time to + // think about a proper code architecture first! Invoke(nameof(RecalculatePlacedOpponentsCount), 0.01f); UpdateDisplayStates(); } diff --git a/Assets/Scripts/UI/RoundControllerButton.cs b/Assets/Scripts/UI/RoundControllerButton.cs index 431709c..b69294c 100644 --- a/Assets/Scripts/UI/RoundControllerButton.cs +++ b/Assets/Scripts/UI/RoundControllerButton.cs @@ -1,8 +1,7 @@ -using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; +// The button used to start and stop a round, which also indicates whether a round is currently running. public class RoundControllerButton : MonoBehaviour, IRoundCallback { diff --git a/Assets/Scripts/Upgrades/Upgrade.cs b/Assets/Scripts/Upgrades/Upgrade.cs index 162ed72..b2cef55 100644 --- a/Assets/Scripts/Upgrades/Upgrade.cs +++ b/Assets/Scripts/Upgrades/Upgrade.cs @@ -7,8 +7,8 @@ public class Upgrade : ScriptableObject public UpgradeTypes type; public string upgradeName; public int baseCost; - public float costMultiplier; + [Tooltip("How much each additional Upgrade costs")] public float costMultiplier; public Sprite shopSprite; - [Tooltip("Multiplier of the stat that this Upgrade controls")] public float effectMultiplier; + [Tooltip("How much each instance of this Upgrade improves the stat type")] public float effectMultiplier; } diff --git a/Assets/Scripts/Upgrades/UpgradeController.cs b/Assets/Scripts/Upgrades/UpgradeController.cs index 2b668c8..9455397 100644 --- a/Assets/Scripts/Upgrades/UpgradeController.cs +++ b/Assets/Scripts/Upgrades/UpgradeController.cs @@ -1,92 +1,97 @@ -using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; - - +// Powers the Shop. Allows you to purchase Upgrades. Displays how many of each +// Upgrade you already own and how much additional Upgrades cost. public class UpgradeController : MonoBehaviour { [SerializeField] Button manaButton; [Header("Price Texts")] - [SerializeField] Text healthText, damageText, armorText, manaText; + [SerializeField] Text healthText; + [SerializeField] Text damageText; + [SerializeField] Text armorText; + [SerializeField] Text manaText; [Header("Multiplier Texts")] - [SerializeField] Text healthMultiplierText, damageMultiplierText, armorMultiplierText, manaMultiplierText; + [SerializeField] Text healthMultiplierText; + [SerializeField] Text damageMultiplierText; + [SerializeField] Text armorMultiplierText; + [SerializeField] Text manaMultiplierText; - Dictionary<UpgradeTypes,Text> upgradeTexts = new Dictionary<UpgradeTypes,Text>(); + Dictionary<UpgradeTypes, Text> upgradeTexts = new Dictionary<UpgradeTypes, Text>(); Dictionary<UpgradeTypes, Text> multiplierTexts = new Dictionary<UpgradeTypes, Text>(); - StatsManager statsManager; - + private void Awake() { - statsManager = FindObjectOfType<StatsManager>(); - - //initalise upgrade Texts + // Display initial values upgradeTexts.Add(UpgradeTypes.ENEMY_HEALTH, healthText); upgradeTexts.Add(UpgradeTypes.ENEMY_DAMAGE, damageText); upgradeTexts.Add(UpgradeTypes.ENEMY_ARMOR, armorText); upgradeTexts.Add(UpgradeTypes.MANA_COST, manaText); - UpdateAllCosts(); + UpdateCostTexts(); - //initalize Multiplier - multiplierTexts.Add(UpgradeTypes.ENEMY_HEALTH,healthMultiplierText); + multiplierTexts.Add(UpgradeTypes.ENEMY_HEALTH, healthMultiplierText); multiplierTexts.Add(UpgradeTypes.ENEMY_DAMAGE, damageMultiplierText); multiplierTexts.Add(UpgradeTypes.ENEMY_ARMOR, armorMultiplierText); multiplierTexts.Add(UpgradeTypes.MANA_COST, manaMultiplierText); - foreach (KeyValuePair<UpgradeTypes,Text> multiplierText in multiplierTexts) + + foreach (KeyValuePair<UpgradeTypes, Text> multiplierText in multiplierTexts) { - multiplierText.Value.text = statsManager.GetTotalEffectMultiplier(multiplierText.Key).ToString("F2"); + multiplierText.Value.text = StatsManager.instance.GetTotalEffectMultiplier(multiplierText.Key).ToString("F2"); } } + + // Called whenever a button to buy an Upgrade is called. public void Buy(string upgradeType) { switch (upgradeType) { case "Health": - UpdateCostText(UpgradeTypes.ENEMY_HEALTH); + BuyUpgrade(UpgradeTypes.ENEMY_HEALTH); break; case "Damage": - UpdateCostText(UpgradeTypes.ENEMY_DAMAGE); + BuyUpgrade(UpgradeTypes.ENEMY_DAMAGE); break; case "Armor": - UpdateCostText(UpgradeTypes.ENEMY_ARMOR); + BuyUpgrade(UpgradeTypes.ENEMY_ARMOR); break; case "Mana": - UpdateCostText(UpgradeTypes.MANA_COST); + BuyUpgrade(UpgradeTypes.MANA_COST); break; } } - private void UpdateCostText(UpgradeTypes upgradeType) + void BuyUpgrade(UpgradeTypes upgradeType) { - if (statsManager.BuyUpgrade(upgradeType)) + if (StatsManager.instance.BuyUpgrade(upgradeType)) { - upgradeTexts[upgradeType].text = statsManager.GetNextUpgradeCost(upgradeType).ToString(); - multiplierTexts[upgradeType].text = statsManager.GetTotalEffectMultiplier(upgradeType).ToString("F2"); + upgradeTexts[upgradeType].text = StatsManager.instance.GetNextUpgradeCost(upgradeType).ToString(); + multiplierTexts[upgradeType].text = StatsManager.instance.GetTotalEffectMultiplier(upgradeType).ToString("F2"); if (upgradeType == UpgradeTypes.MANA_COST) { - UpdateAllCosts(); - DeactivateMana(); + UpdateCostTexts(); + MaybeDeactivateBuyManaButton(); } } } - private void UpdateAllCosts() + void UpdateCostTexts() { foreach (KeyValuePair<UpgradeTypes, Text> upgradeText in upgradeTexts) { - upgradeText.Value.text = statsManager.GetNextUpgradeCost(upgradeText.Key).ToString(); + upgradeText.Value.text = StatsManager.instance.GetNextUpgradeCost(upgradeText.Key).ToString(); } } - private void DeactivateMana() + // Don't allow you to buy enough Mana Cost Decrease Upgrades to be able to spend negative Mana, aka gain Mana with purchases + void MaybeDeactivateBuyManaButton() { - if (statsManager.GetTotalEffectMultiplier(UpgradeTypes.MANA_COST) <= 0.1) + if (StatsManager.instance.GetTotalEffectMultiplier(UpgradeTypes.MANA_COST) <= 0.1) { manaButton.interactable = false; multiplierTexts[UpgradeTypes.MANA_COST].text = "0.1"; diff --git a/Assets/Scripts/utils/Box.cs b/Assets/Scripts/utils/Box.cs index 6d6d593..e5433e3 100644 --- a/Assets/Scripts/utils/Box.cs +++ b/Assets/Scripts/utils/Box.cs @@ -1,7 +1,9 @@ using System; using UnityEngine; -// A simple struct representing a rectangular box consisting of four edges +// A simple struct representing a rectangular box consisting of four edges. +// I could've probably used a Rect or Bounds but when I write this I didn't +// have much experience with them so, meh. [Serializable] public struct Box { diff --git a/Assets/Scripts/utils/Interpolator.cs b/Assets/Scripts/utils/Interpolator.cs index 23b2423..f21883e 100644 --- a/Assets/Scripts/utils/Interpolator.cs +++ b/Assets/Scripts/utils/Interpolator.cs @@ -1,8 +1,9 @@ using System; using UnityEngine; -// Fancy wrapper class for `Mathf.SmoothDamp()`. Interpolates between `currentValue` and `targetValue`, -// which may change rapidly without disturbing the interpolation. +// Fancy wrapper class for `Mathf.SmoothDamp()`. Interpolates between `currentValue` +// and `targetValue`, which may change rapidly without disturbing the interpolation. +// This entire system is completely over-engineered. [Serializable] public class Interpolator { diff --git a/Assets/Scripts/utils/InterpolatorQueue.cs b/Assets/Scripts/utils/InterpolatorQueue.cs index ad1aaa8..1afb6a7 100644 --- a/Assets/Scripts/utils/InterpolatorQueue.cs +++ b/Assets/Scripts/utils/InterpolatorQueue.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; // A LayeredInterpolator consists of one base interpolator as well as an arbitrary // amount of interpolators which are stacked on top. Only the interpolator at the // top of the queue will be used. Once that interpolator has finished, it will be -// removed from the queue and the seond-last interpolator takes over. +// removed from the queue and the new top interpolator takes over. [Serializable] public class InterpolatorQueue { @@ -43,6 +43,7 @@ public class InterpolatorQueue interpolators.Add(baseInterpolator); } + // Adds a new Interpolator to the top of the queue, meaning that it will be the new active one. public void PushInterpolator(Interpolator newInterpolator) { // Only push interpolators that would actually do something @@ -52,6 +53,7 @@ public class InterpolatorQueue } } + // Removes the currently active interpolator, if there is one public void PopInterpolator() { // Always keep the base interpolator @@ -61,6 +63,7 @@ public class InterpolatorQueue } } + // See `Interpolator#Tick()` public float Tick() { Interpolator current = GetCurrentInterpolator(); -- GitLab