diff --git a/Assets/Scripts/CameraOperator.cs b/Assets/Scripts/CameraOperator.cs
index 55b600e..58bd32a 100644
--- a/Assets/Scripts/CameraOperator.cs
+++ b/Assets/Scripts/CameraOperator.cs
@@ -20,7 +20,9 @@ public class CameraOperator : MonoBehaviour
players.Remove(id);
}
- // Update is called once per frame
+ ///
+ /// Rotates the camera to point at the center between the players.
+ ///
void LateUpdate()
{
if (players.Count < 1)
diff --git a/Assets/Scripts/Managers/AVEffectsManager.cs b/Assets/Scripts/Managers/AVEffectsManager.cs
index 45b2ad9..f671aa7 100644
--- a/Assets/Scripts/Managers/AVEffectsManager.cs
+++ b/Assets/Scripts/Managers/AVEffectsManager.cs
@@ -30,8 +30,12 @@ namespace Managers
void Start()
{
- centralAudioSource = audioLibrary.audios.First(a => a.tag == "music").audioSource;
- centralAudioSource.Play();
+ if(audioLibrary == null){
+ return;
+ }
+ centralAudioSource = audioLibrary.audios.First(a => a.tag == "music")?.audioSource;
+ if(centralAudioSource != null)
+ centralAudioSource.Play();
}
}
diff --git a/Assets/Scripts/Managers/GameManager.cs b/Assets/Scripts/Managers/GameManager.cs
index 8a45237..7d1c0d6 100644
--- a/Assets/Scripts/Managers/GameManager.cs
+++ b/Assets/Scripts/Managers/GameManager.cs
@@ -23,8 +23,6 @@ public enum Scenes
namespace Managers
{
- // public enum GameState { Starting, Match, End, Paused }
-
///
/// Starts up the game and it's managers.
/// Provides methods for loading additional scenes and triggering custom events when loaded.
@@ -88,7 +86,7 @@ namespace Managers
}
///
- /// Instantiates the managers needed to use the main menu.
+ /// Instantiates the managers needed to play the game.
///
void InstantiateBaseManagers()
{
@@ -148,6 +146,9 @@ namespace Managers
}
}
+ ///
+ /// Starts the camera, for showing an image before the main menu is loaded.
+ ///
void ShowStartScreen()
{
startCamera.SetActive(true);
@@ -169,8 +170,8 @@ namespace Managers
}
///
- /// Initiates a local battle by giving relavant information to the match manager
- /// and starting the match managers appropriate process.
+ /// Initiates a local battle by giving relavant information to the responsible managers
+ /// and starting their appropriate processes.
///
/// Scene id of the chosen arena.
public IEnumerator SetupLocalMatchFromMainMenu()
@@ -246,6 +247,10 @@ namespace Managers
}
+ ///
+ /// Custom delegate which can be executed after scene load.
+ ///
+ /// Data of the loaded scene
public delegate void CustomOnSceneLoaded(SceneLoadEventArgs args);
public class SceneLoadEventArgs : EventArgs
diff --git a/Assets/Scripts/Managers/MatchManager.cs b/Assets/Scripts/Managers/MatchManager.cs
index 341cb36..3441a86 100644
--- a/Assets/Scripts/Managers/MatchManager.cs
+++ b/Assets/Scripts/Managers/MatchManager.cs
@@ -7,9 +7,6 @@ using PrimeTween;
using UnityEditor;
using UnityEngine;
using GameLogic;
-using Unity.VisualScripting;
-using System.Xml;
-using System.Collections;
using System.Threading.Tasks;
namespace Managers
@@ -24,7 +21,6 @@ namespace Managers
private static string arenaAssetsPath = "Assets/ScriptedAssets/Arenas";
private static string ruleAssetsPath = "Assets/ScriptedAssets/Rules";
- private bool needsStartConfirmation = false;
public event Action OnStartPressed;
///
/// Globally accessible member to use manager with.
@@ -132,6 +128,9 @@ namespace Managers
}
}
+ ///
+ /// Creates statistics for the players participating in the match.
+ ///
public void SetupMatchPlayerStatistics()
{
matchPlayerStatistics.Clear();
@@ -190,6 +189,11 @@ namespace Managers
matchState = MatchState.CharacterSelect;
}
+ ///
+ /// Announcement of who won.
+ /// TODO: Also restarts the match right now, no matter what.
+ ///
+ /// Result data of the completed match.
async public void AnnounceWinner(MatchResult mr)
{
UIManager.G.announcments.QueueAnnounceText($"{mr.Winner.playerName}" +
@@ -205,6 +209,10 @@ namespace Managers
RestartMatch();
}
+ ///
+ /// Starts the match anew.
+ /// Resetting player positions and statistics.
+ ///
public void RestartMatch()
{
ResetMatchCharacters();
@@ -212,6 +220,10 @@ namespace Managers
matchState = MatchState.Match;
}
+ ///
+ /// Initializes the match, waits for match begin
+ /// confirmation by the players and counts down to start.
+ ///
async public void StartMatch()
{
foreach (Player p in matchPlayers)
diff --git a/Assets/Scripts/MatchLogic.cs b/Assets/Scripts/MatchLogic.cs
index d64010b..b7bdeff 100644
--- a/Assets/Scripts/MatchLogic.cs
+++ b/Assets/Scripts/MatchLogic.cs
@@ -1,16 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Managers;
-using TMPro;
using UnityEditor;
-using UnityEngine.InputSystem;
namespace GameLogic
{
+ ///
+ /// Updates and checks a matches rules according to the state of the match.
+ ///
public static class MatchLogic
{
public static MatchRule currentRule;
+
+ ///
+ /// Update match conditions and check for match conclusion.
+ ///
+ /// Affected player
+ /// Update to the matches conditions
+ /// Dictionary of the players in the match and their current stats
+ ///
public static MatchResult UpdateMatchResult(Player p, MatchConditionUpdate args, Dictionary mps)
{
switch (args.Condition)
diff --git a/Assets/Scripts/NimbleZoneDetection.cs b/Assets/Scripts/NimbleZoneDetection.cs
index 372f207..6544df5 100644
--- a/Assets/Scripts/NimbleZoneDetection.cs
+++ b/Assets/Scripts/NimbleZoneDetection.cs
@@ -27,6 +27,7 @@ public class NimbleZoneDetection : MonoBehaviour
private Zone zone = Zone.NimbleZone;
// Ripple properties
+ // These influence the shader on the nimble zone
[SerializeField]
private float rippleFrequency = 3f;
[SerializeField]
@@ -39,10 +40,10 @@ public class NimbleZoneDetection : MonoBehaviour
private float rippleDuration = 1f;
[SerializeField]
private float impactVelocityModifier = 1f;
- [SerializeField]
+ [SerializeField, Tooltip("Minimum ripple effect intensity.")]
[Range(0, 1)]
private float minImpact = 0.2f;
- [SerializeField]
+ [SerializeField, Tooltip("Velocity which makes the highest/most intense ripples.")]
private float maxVelocity = 45f;
private int maxRippleAmount = 5;
private MeshRenderer meshRenderer;
@@ -55,19 +56,37 @@ public class NimbleZoneDetection : MonoBehaviour
ResetRippleShaderProperties();
}
+ ///
+ /// Array of the available gravities.
+ ///
private Func[] gravityFunctions =
{ DownGravity, NoGravity, InwardsGravity, OutwardsGravity };
+ ///
+ /// Function which returns a gravity zero vector.
+ ///
private static Func NoGravity =
new(transform => new Vector3());
+ ///
+ /// Function which returns a gravity vector downwards, depending
+ /// on the parent transforms rotation.
+ /// The parenting transform for a ship is the arena it's in.
+ ///
private static Func DownGravity =
new(transform => transform.parent.rotation * Vector3.down * gravityFactor);
- // TODO: This is too specific maybe?
+ ///
+ /// Function which returns a gravity vector towards the center of the parenting transform.
+ /// The parenting transform for a ship is the arena it's in.
+ ///
private static Func InwardsGravity =
new(transform => (transform.position - transform.parent.position).normalized * -gravityFactor);
+ ///
+ /// Function which returns a gravity vector outwards from the center of the parenting transform.
+ /// The parenting transform for a ship is the arena it's in.
+ ///
private static Func OutwardsGravity =
new Func(transform =>
(transform.position - transform.parent.position).normalized * gravityFactor);
@@ -113,12 +132,24 @@ public class NimbleZoneDetection : MonoBehaviour
material.SetFloat("_ShaderTime", Time.timeSinceLevelLoad);
}
- private float ImpactVelocityEffect(float duration, float velocity)
+ ///
+ /// Calculates the effect which a given velocity has on a ripple property.
+ ///
+ /// Initial value of the ripple property
+ /// Velocity of the impact
+ ///
+ private float ImpactVelocityEffect(float initial, float velocity)
{
return math.max(math.smoothstep(0, maxVelocity, velocity), minImpact)
- * impactVelocityModifier * duration;
+ * impactVelocityModifier * initial;
}
+ ///
+ /// Spawns ripples on the shader of the nimble zone.
+ /// Up to 5 parallel ripples.
+ ///
+ ///
+ ///
private void SpawnRipple(Collider collider, bool isOutwardsRipple)
{
Rigidbody body = collider.attachedRigidbody;
@@ -174,6 +205,9 @@ public class NimbleZoneDetection : MonoBehaviour
}
}
+ ///
+ /// Resets the ripple shaders exposed properties to 0
+ ///
private void ResetRippleShaderProperties()
{
Vector4[] rippleOrigins = new Vector4[maxRippleAmount];
diff --git a/Assets/Scripts/PlayingFieldDetection.cs b/Assets/Scripts/PlayingFieldDetection.cs
index e7a8aba..b88e32b 100644
--- a/Assets/Scripts/PlayingFieldDetection.cs
+++ b/Assets/Scripts/PlayingFieldDetection.cs
@@ -6,6 +6,11 @@ using UnityEngine;
public class PlayingFieldDetection : MonoBehaviour
{
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Updates the match conditions, when a ship leaves the playing field.
+ ///
+ ///
private void OnTriggerExit(Collider collider)
{
if (collider.tag == "Ship")
diff --git a/Assets/Scripts/Ship.cs b/Assets/Scripts/Ship.cs
index 5fffa5f..113583c 100644
--- a/Assets/Scripts/Ship.cs
+++ b/Assets/Scripts/Ship.cs
@@ -87,6 +87,9 @@ public class Ship : MonoBehaviour
UpdateTackleResponse(isCriticalTackle);
}
+ ///
+ /// Movement logic and simulation of the ship.
+ ///
void UpdateMovement()
{
@@ -144,9 +147,14 @@ public class Ship : MonoBehaviour
Color.black);
}
+ ///
+ /// Calculates a vector to mitigate the ship drifting when it's changing direction.
+ ///
+ /// Current velocity of the ship
+ /// Zone which the ship is in
+ ///
Vector3 DriftDampeningAcceleration(Vector3 currentVelocity, Zone zone)
{
- // TODO: add in ifs for ignoring small deviations
Vector3 antiDriftVelocity;
float antiDriftFactor;
// Cancel out inertia/drifting
@@ -170,6 +178,12 @@ public class Ship : MonoBehaviour
return antiDriftVelocity * props.antiDriftAmount * antiDriftFactor;
}
+ ///
+ /// Calculates drag on the ship depending on it's velocity and inhabited zone.
+ ///
+ /// Velocity of the ship
+ /// Zone which the ship is in
+ ///
Vector3 DragDecceleration(Vector3 currentVelocity, Zone zone)
{
Vector3 drag = new Vector3();
@@ -190,11 +204,23 @@ public class Ship : MonoBehaviour
return drag;
}
+ ///
+ /// Is the boost input pressed and boosting possible?
+ ///
+ /// Boosting state
bool IsBoosting()
{
return state.boostInput > 0 && canBoost;
}
+ ///
+ /// Applies boost to an acceleration vector.
+ /// This includes increasing acceleration and mitigating
+ /// the gravity.
+ ///
+ /// Current acceleration vector
+ /// Gravity vector which is in force
+ ///
Vector3 BoostAcceleration(Vector3 acceleration, Vector3 currentGravity)
{
if (IsBoosting())
@@ -205,39 +231,44 @@ public class Ship : MonoBehaviour
return acceleration;
}
+ ///
+ /// Logic which depletes boost capacity when boost conditions are met.
+ ///
+ /// Time delta of the current frame
void BoostStateUpdate(float deltaTime)
{
boostUI.UpdateFill(Math.Min(state.boostCapacity / props.maxBoostCapacity, 1));
if (IsBoosting() && state.thrustInput != 0)
{
- // Debug.Log("Boost Kapazität wird verbraucht: " + boostCapacity);
state.boostCapacity -= deltaTime;
}
if (canBoost && zone == Zone.OutsideZone)
{
- // Debug.Log("Boost Kapazität wird passiv verbraucht: " + boostCapacity);
state.boostCapacity -= deltaTime * props.outsideBoostRate;
}
if (state.boostCapacity <= 0)
{
canBoost = false;
- // Debug.Log("Boost aufgebraucht");
}
- // TODO this will be spam abused
+
if ((state.boostInput <= 0 || state.thrustInput == 0 || !canBoost)
&& zone == Zone.NimbleZone
&& state.boostCapacity <= props.maxBoostCapacity)
{
- // Debug.Log("Boost wird aufgeladen: " + boostCapacity);
state.boostCapacity += deltaTime;
}
+ // When your boost capacity is still critical, you can't start boosting immediately again.
+ // TODO: This is not tested well enough with players.
if (canBoost == false && state.boostCapacity >= props.minBoostCapacity)
{
canBoost = true;
- // Debug.Log("Boost verfügbar");
}
}
+ ///
+ /// Logic which sets the isTackled state.
+ ///
+ /// Use true to process a tackle hit
void UpdateTackleResponse(bool gotTackled = false)
{
if (gotTackled && !isTackled)
@@ -256,6 +287,13 @@ public class Ship : MonoBehaviour
}
}
+ ///
+ /// Called by the collision regions which detect tackling.
+ /// Adds resulting forces to the ship and intiates the tackle
+ /// response.
+ ///
+ /// Kind of the tackle. Depends on collision region.
+ /// Object which has collided with the collision region.
void StartTackleResponse(TackleKind tackleKind, Collider collider)
{
float tacklePowerFactor = props.criticalTacklePowerFactor;
diff --git a/Assets/Scripts/ShipState.cs b/Assets/Scripts/ShipState.cs
index 2045263..781746c 100644
--- a/Assets/Scripts/ShipState.cs
+++ b/Assets/Scripts/ShipState.cs
@@ -2,6 +2,9 @@ using UnityEngine;
namespace ShipHandling
{
+ ///
+ /// Variables for the ship which can also be under the players control.
+ ///
public class ShipState
{
public float thrustInput = 0;
diff --git a/Assets/Scripts/TackleDetection.cs b/Assets/Scripts/TackleDetection.cs
index 79eb9cf..880c94d 100644
--- a/Assets/Scripts/TackleDetection.cs
+++ b/Assets/Scripts/TackleDetection.cs
@@ -1,10 +1,18 @@
using UnityEngine;
using UnityEngine.Events;
+///
+/// Used on vulnerable trigger zones for ships.
+///
public class TackleDetection : MonoBehaviour
{
[SerializeField] private TackleKind tackleKind;
public UnityEvent TackleResponse;
+
+ ///
+ /// Invokes the fitting tackle response on trigger entered.
+ ///
+ ///
void OnTriggerEnter(Collider collider)
{
if (collider.tag != "Spike" && collider.tag != "Bumper")
diff --git a/Assets/Scripts/UI/Announcments.cs b/Assets/Scripts/UI/Announcments.cs
index eefdc97..cfcceab 100644
--- a/Assets/Scripts/UI/Announcments.cs
+++ b/Assets/Scripts/UI/Announcments.cs
@@ -1,10 +1,12 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using TMPro;
-using Unity.VisualScripting;
using UnityEngine;
+///
+/// Provides methods for displaying text on a text mesh pro.
+/// Features a queue for messages which dissapear after a set time.
+///
public class Announcments : MonoBehaviour
{
[SerializeField] TextMeshProUGUI announcementText;
@@ -12,7 +14,10 @@ public class Announcments : MonoBehaviour
public Queue> announcementQueue = new Queue>();
private bool workingOnQueue = false;
private float remainingTime;
-
+
+ ///
+ /// Update the message queue.
+ ///
void Update()
{
if (!workingOnQueue && announcementQueue.Count != 0)
@@ -38,20 +43,10 @@ public class Announcments : MonoBehaviour
}
}
- public void AnnounceText(string text, float time)
- {
- announcementText.text = text;
- announcementText.enabled = true;
- remainingTime = time;
- enabled = true;
- }
-
- public void QueueAnnounceText(string text, float time)
- {
- announcementQueue.Enqueue(new Tuple(text, time));
- enabled = true;
- }
-
+ ///
+ /// Shows the text without time limit.
+ ///
+ /// Text to be shown.
public void AnnounceText(string text)
{
announcementText.text = text;
@@ -60,6 +55,33 @@ public class Announcments : MonoBehaviour
enabled = false;
}
+ ///
+ /// Set the announcement text for a certain time.
+ ///
+ ///
+ /// Time in seconds
+ private void AnnounceText(string text, float time)
+ {
+ announcementText.text = text;
+ announcementText.enabled = true;
+ remainingTime = time;
+ enabled = true;
+ }
+
+ ///
+ /// Add an announcement to the queue.
+ ///
+ /// Text to be shown.
+ /// Time of the announcement in seconds.
+ public void QueueAnnounceText(string text, float time)
+ {
+ announcementQueue.Enqueue(new Tuple(text, time));
+ enabled = true;
+ }
+
+ ///
+ /// Stop the announcement and clear the queue.
+ ///
public void StopAnnouncement()
{
announcementQueue.Clear();
diff --git a/Assets/Scripts/UI/BoostCapacityUI.cs b/Assets/Scripts/UI/BoostCapacityUI.cs
index 3b0cb21..04ddeca 100644
--- a/Assets/Scripts/UI/BoostCapacityUI.cs
+++ b/Assets/Scripts/UI/BoostCapacityUI.cs
@@ -1,8 +1,10 @@
using TMPro;
-using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
+///
+/// HUD element which displays a ships remaining boost capacity.
+///
public class BoostCapacityUI : MonoBehaviour
{
public Color goodColor = Color.green;
@@ -12,6 +14,11 @@ public class BoostCapacityUI : MonoBehaviour
[SerializeField] private TextMeshProUGUI hint;
private float minBoostRatio = 0.3f;
+ ///
+ /// Ratio of capacity to max capacity under which the
+ /// boost capacity is considered critically low.
+ ///
+ ///
public void SetMinBoostRatio(float minBoostRatio)
{
this.minBoostRatio = minBoostRatio;
@@ -22,6 +29,10 @@ public class BoostCapacityUI : MonoBehaviour
hint.SetText($"Boost Capacity \n {p.playerName} \n {p.character.shipName}");
}
+ ///
+ /// Updates the color and fill of the capacity meter.
+ ///
+ /// Fill percentage
public void UpdateFill(float fill)
{
fillImage.fillAmount = fill;
diff --git a/Assets/Scripts/UI/HUD.cs b/Assets/Scripts/UI/HUD.cs
index 93eaec8..ca1133e 100644
--- a/Assets/Scripts/UI/HUD.cs
+++ b/Assets/Scripts/UI/HUD.cs
@@ -1,13 +1,17 @@
-using System.Collections;
-using System.Collections.Generic;
-using Unity.VisualScripting;
using UnityEngine;
+///
+/// Colleciton class for referencing and controlling HUD elements.
+///
public class HUD : MonoBehaviour
{
public BoostCapacityUI[] boostCapacities;
public JoinPrompt[] joinPrompts;
+ ///
+ /// Start a join prompt.
+ ///
+ /// Player to which the prompt belongs
public void StartJoinPrompt(Player player)
{
foreach (JoinPrompt jp in joinPrompts)
diff --git a/Assets/SlimUI/Modern Menu 1/Scripts/Managers/SlimUIMainMenu.cs b/Assets/SlimUI/Modern Menu 1/Scripts/Managers/SlimUIMainMenu.cs
index cf93277..43894e9 100644
--- a/Assets/SlimUI/Modern Menu 1/Scripts/Managers/SlimUIMainMenu.cs
+++ b/Assets/SlimUI/Modern Menu 1/Scripts/Managers/SlimUIMainMenu.cs
@@ -89,10 +89,6 @@ namespace SlimUI.ModernMenu
[Tooltip("The GameObject holding the Audio Source component for the SWOOSH SOUND when switching to the Settings Screen")]
public AudioSource swooshSound;
- // [Header("Options")]
- // public bool flyCameraLoadTransition = true;
-
-
void Start()
{
GM = GameManager.G;
@@ -212,11 +208,11 @@ namespace SlimUI.ModernMenu
}
///
- /// Loads the Gameplay UI and unloads the Main Menu once thats loaded.
+ /// Loads the Gameplay UI and after that unloads the Main Menu.
/// Also Initiates the setup of the local match once the Gameplay UI is
/// loaded.
///
- ///
+ /// IEnumerator for async statemachine
private IEnumerator SwitchToIngameUI()
{
AsyncOperation o = SceneManager.LoadSceneAsync((int)Scenes.GameplayUserInterface,
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..61b45ac
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+When using this repo a game can be started from the Unity Editor,
+by starting the GameManagement scene from the Assets/Scenes folder.
+The GameManager is a sort of bootloader, which sets up all the
+other managers and orchestrates the match start process.
+
+Once the main menu is loaded, the only real option is to start a
+local 2v2 match.
+I use SlimUI, as the main menu for now, it is a store asset.
+Starting this match (using the button in SlimUI) sets off the async scene loading,
+transition to the arena camera and match setup in the GameManager.
+
+The GameManager provides a method which invokes an event once a
+specific scene has been loaded.
+Here I'm using that to trigger the camera transition once the arena scene was loaded.
+
+After the camera transition the InGameUI scene is loaded and when the UI is there,
+the match setup process in the GameManager is started.
+
+To look into this process see:
+Assets\SlimUI\Modern Menu 1\Scripts\Managers\SlimUIMainMenu Line 162 onwards
+Assets\Scripts\Managers\GameManager Line 176 onwards
+
+Also noteworthy is the Ship Movement logic in which I change the flying behavior and gravity
+for the ship depending which zone it is in
+and the shader for the ripple effect of the inner/green/nimble zone, which is an older simple
+ripple shader converted to URP (in code not shader graph), featuring up to 5 simulateously animated ripples.
\ No newline at end of file