Skip to content

Utilities

Summary

This page outlines the utilitiy scripts used by the 2.5D Beat 'Em Up Template. These classes don't belong to any one game system and act as general-purpose tools that can be used anywhere, in any game, when needed.

Scripting

The code files in this section are at BeatEmUpTemplate/Assets/Scripting/Utilities.

utilities_scripting.png

CSharp

These scripts are not meant to be attached to GameObjects in the scene. Many of them represent static event classes that are meant to be invoked or are abstract classes representing concepts.

ActionWrapper

classDiagram
    class ActionWrapper{
    }

ActionWrapper.cs is used by PersistentGameManager to define the EventLinks in its StateMachine. It essentially connects two nodes in the StateMachine through subscriptions to GameEvents.

StateMachine

classDiagram
    class StateMachine{
    }

StateMachine.cs represents a basic, general-purpose state machine. It is used by PersistentGameManager to represent the game's state.

classDiagram
    class ILink{
    <<Interface>>
    }

ILink.cs is used by IStates to add a link to another IState.

IState
classDiagram
    class IState{
    <<Interface>>
    }

IState.cs is used by PersistentGameManager to create custom states for a StateMachine.

classDiagram
    class EventLink{
    }

EventLinks are used to connect nodes in a StateMachine.

EventLink.cs is used by PersistentGameManager to link the paused and running game states.

States
classDiagram
    AbstractState <|-- GameState
    GameState <|-- TemplateGameState
    class AbstractState{
    <<Abstract>>
    }

AbstractStates represent the conceptual nodes of a StateMachine while GameStates represent actual game state nodes.

AbstractState.cs defines what is common across all AbstractStates, regardless of game.

GameState.cs defines what is common across all GameStates, regardless of game.

TemplateGameState.cs represents the GameStates in the template.

Interfaces

These scripts contain collections of method signatures and properties that can be implemented by other scripts. All classes in these folder use the interface keyword in their declaration.

Interfaces act like a contract; when a class implements an interface, an instance of that class can also be treated as an instance of that interface. This functionality means that two unrelated classes can be treated in the same way through an interface that they both implement.

ICanFace

classDiagram
    class ICanFace{
    <<Interface>>
    }

ICanFace.cs is implemented by classes that can face a specific Direction. It is implemented by VillainController so that BasicEnemyAI can control the direction the unit faces.

ICanMove

classDiagram
    class ICanMove{
    <<Interface>>
    }

ICanMove.cs is implemented by classes that can move conditionally. It is implemented by UnitController so that BeltScrollMove can know if the unit can currently move.

ICanStop

classDiagram
    class ICanStop{
    <<Interface>>
    }

ICanStop.cs is implemented by classes that can stop. It is implemented by BeltScrollMove so that UnitController can stop the unit from moving when needed.

IDamageable

classDiagram
    class IDamageable{
    <<Interface>>
    }

IDamageable.cs is implemented by classes that are damageable. It is implemented by UnitController to notify StateMachineBehaviours that the unit was damaged so that the animation state machine can update accordingly.

IDefeatable

classDiagram
    class IDefeatable{
    <<Interface>>
    }

IDefeatable.cs is implemented by classes that are defeatable. It is implemented by UnitController to notify StateMachineBehaviours that the unit was defeated so that the animation state machine can update accordingly.

IHaveDamage

classDiagram
    class IHaveDamage{
    <<Interface>>
    }

IHaveDamage.cs is implemented by classes that have damage. It is implemented by JabAbilityData and CrossAbilityData so that a target's HurtResponder knows that it has to process damage as part of its hurt response.

IHaveDirection

classDiagram
    class IHaveDirection{
    <<Interface>>
    }

IHaveDirection.cs is implemented by classes that have Direction. It is implemented by UnitController so that JabHitbox and CrossHitbox know what direction to perform their boxcasts when getting hit info from a collision.

IHaveFloatingHealthBar

classDiagram
    class IHaveFloatingHealthBar{
    <<Interface>>
    }

IHaveFloatingHealthBar.cs is implemented by classes that have a floating health bar transform. It is implemented by VillainController so that FloatingHealthBarController knows where to position the unit's floating health bar.

IHaveHitStun

classDiagram
    class IHaveHitStun{
    <<Interface>>
    }

IHaveHitStun.cs is implemented by classes that have hitstun. It is implemented by JabAbilityData and CrossAbilityData so that a target's HurtResponder knows that it has to process hitstun as part of its hurt response.

IHaveHurtboxes

classDiagram
    class IHaveHurtboxes{
    <<Interface>>
    }

IHaveHurtboxes.cs is implemented by classes that have hurtboxes. It is implemented by HeroController so that BasicEnemyAI can calculate the closest possible target hurtbox.

IHaveHurtboxMask

classDiagram
    class IHaveHurtboxMask{
    <<Interface>>
    }

IHaveHurtboxMask.cs is implemented by classes that have a hurtbox mask. It is implemented by UnitController so that JabHitbox and CrossHitbox know what type of hurtbox they collide with when active.

IHaveKnockback

classDiagram
    class IHaveKnockback{
    <<Interface>>
    }

IHaveKnockback.cs is implemented by classes that have knockback. It is implemented by JabAbilityData and CrossAbilityData for two reasons:

  1. So that JabHitbox and CrossHitbox can assign knockback direction after a collision based on hit info.
  2. So that a target's HurtResponder knows that it has to process knockback as part of its hurt response.

IHaveMaximumHealth

classDiagram
    IHaveMaximumHealth <|-- IHealth
    class IHaveMaximumHealth{
    <<Interface>>
    }
    class IHealth{
    <<Interface>>
    }

IHaveMaximumHealth.cs is implemented by classes that have maximum health. It is implemented by UnitStats so that a UnitController can initialize its HealthBehaviour with the correct maximum health.

IHealth

IHealth.cs is implemented by classes that have health. It is implemented by UnitController for two reasons:

  1. So that GameplayScreenController can initialize the Hero's health bar with the correct current and maximum health.
  2. So that FloatingHealthBarManager can initialize the Villain's floating health bar with the correct current and maximum health.

IHaveName

classDiagram
    class IHaveName{
    <<Interface>>
    }

IHaveName.cs is implemented by classes that have a name. It is implemented by UnitController so that UnitActionManager can out output debug logs when attempting to perform UnitActions.

IHaveRange

classDiagram
    class IHaveRange{
    <<Interface>>
    }

IHaveRange.cs is implemented by classes that have range. It is implemented by JabUnitAction and CrossUnitAction so that BasicEnemyAI knows the maximum range at which to position itself in order to hit with the edge of an ability.

IHaveWalkSpeed

classDiagram
    class IHaveWalkSpeed{
    <<Interface>>
    }

IHaveWalkSpeed.cs is implemented by classes that have walk speed. It is implemented by UnitStats and UnitController for two reasons:

  1. So that TrainingAIPlayerUnitManager can randomize Villain walk speeds within a set range of their base walk speed.
  2. So that each instance of BeltScrollMove can set its internal walk speed via BeltScrollMoveUnitAction.

IPausable

classDiagram
    class IPausable{
    <<Interface>>
    }

IPausable.cs is implemented by classes that are pausable. It is implemented by BeltScrollMove to allow a UnitController to pause and unpause its behavior.

IPauseAnimator

classDiagram
    class IPauseAnimator{
    <<Interface>>
    }

IPauseAnimator.cs is implemented by classes that can pause the animator. It is implemented by UnitController to notify StateMachineBehaviours that the unit was paused so that the animation state machine can update accordingly.

IRaiseMoveExecuted

classDiagram
    class IRaiseMoveExecuted{
    <<Interface>>
    }

IRaiseMoveExecuted.cs is implemented by classes that raise a move executed event. It is implemented by BeltScrollMove for two reasons:

  1. So that HeroController can have the unit face the direction it is moving.
  2. To notify StateMachineBehaviours that the unit is moving so that the animation state machine can update accordingly.

IRaiseSetAnimationBool

classDiagram
    class IRaiseSetAnimationBool{
    <<Interface>>
    }

IRaiseSetAnimationBool.cs is implemented by classes that set an animation bool. It is implemented by Jab and Cross to notify StateMachineBehaviours that the user is executing an ability so that the animation state machine can update accordingly.

IRaiseWon

classDiagram
    class IRaiseWon{
    <<Interface>>
    }

IRaiseWon.cs is implemented by classes that raise a win. It is implemented by UnitController to notify StateMachineBehaviours that the unit has won so that the animation state machine can update accordingly.

MonoBehaviours

These scripts are meant to be attached to GameObjects in the scene as components and inherit from Unity's MonoBehaviour class.

HorizontalDolly

classDiagram
    class HorizontalDolly{
    }

HorizontalDolly.cs is used to have the x-position of a GameObject follow the x-position of a human player unit. This component can be found attached to the MainCamera GameObject in the Training scene.

Lerp

classDiagram
    class Lerp{
    }

Lerp.cs is used to animate a GameObject's movement between two points. This component can be found attached to the Clouds GameObject in the Title scene.

LoadSceneOnStart

classDiagram
    class LoadSceneOnStart{
    }

LoadSceneOnStart.cs is used to immediately load a new scene. This component can be found attached to the Initializer GameObject in the Initialization scene and the SceneLoader GameObject in the Persistent scene.

MatchScaleXSignWithTransform

classDiagram
    class MatchScaleXSignWithTransform{
    }
MatchScaleXSignWithTransform.cs is used to have a GameObject's scale x sign always copy that of another GameObject's scale x sign. This component can be found attached to the UI GameObject of Human prefab and its Hero and Villain prefab variants. These prefabs are instantiated as children of the HumanPlayerUnitManager and AIPlayerUnitManager GameObjects in the Training scene at runtime.

PropertyAttributes

These scripts contain custom attributes for script variables. All classes in this folder derive from Unity's base PropertyAttribute class.

ReadOnlyAttribute

classDiagram
    class ReadOnlyAttribute{
    }

ReadOnlyAttribute.cs is used to denote fields that are read-only in the Unity Editor Inspector window.

RenameAttribute

classDiagram
    class RenameAttribute{
    }

RenameAttribute.cs is used to change a field's name in the Unity Editor Inspector window.

PropertyDrawers

These scripts contain custom drawers to control how script variables with custom PropertyAttributes appear in the Inspector. All classes in this folder derive from Unity's base PropertyDrawer class.

ReadOnlyPropertyDrawer

classDiagram
    class ReadOnlyPropertyDrawer{
    }

ReadOnlyPropertyDrawer.cs controls how the serializable ReadOnlyAttribute class looks in the inspector.

RenamePropertyDrawers

classDiagram
    class RenamePropertyDrawers{
    }cls

RenamePropertyDrawer.cs controls how the serializable RenameAttribute class looks in the inspector.