doc: Added and improved comments + project readme
This commit is contained in:
parent
64162cb4a1
commit
cbfd16941c
@ -20,7 +20,9 @@ public class CameraOperator : MonoBehaviour
|
|||||||
players.Remove(id);
|
players.Remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update is called once per frame
|
/// <summary>
|
||||||
|
/// Rotates the camera to point at the center between the players.
|
||||||
|
/// </summary>
|
||||||
void LateUpdate()
|
void LateUpdate()
|
||||||
{
|
{
|
||||||
if (players.Count < 1)
|
if (players.Count < 1)
|
||||||
|
|||||||
@ -30,8 +30,12 @@ namespace Managers
|
|||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
centralAudioSource = audioLibrary.audios.First(a => a.tag == "music").audioSource;
|
if(audioLibrary == null){
|
||||||
centralAudioSource.Play();
|
return;
|
||||||
|
}
|
||||||
|
centralAudioSource = audioLibrary.audios.First(a => a.tag == "music")?.audioSource;
|
||||||
|
if(centralAudioSource != null)
|
||||||
|
centralAudioSource.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,8 +23,6 @@ public enum Scenes
|
|||||||
namespace Managers
|
namespace Managers
|
||||||
{
|
{
|
||||||
|
|
||||||
// public enum GameState { Starting, Match, End, Paused }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts up the game and it's managers.
|
/// Starts up the game and it's managers.
|
||||||
/// Provides methods for loading additional scenes and triggering custom events when loaded.
|
/// Provides methods for loading additional scenes and triggering custom events when loaded.
|
||||||
@ -88,7 +86,7 @@ namespace Managers
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates the managers needed to use the main menu.
|
/// Instantiates the managers needed to play the game.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void InstantiateBaseManagers()
|
void InstantiateBaseManagers()
|
||||||
{
|
{
|
||||||
@ -148,6 +146,9 @@ namespace Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the camera, for showing an image before the main menu is loaded.
|
||||||
|
/// </summary>
|
||||||
void ShowStartScreen()
|
void ShowStartScreen()
|
||||||
{
|
{
|
||||||
startCamera.SetActive(true);
|
startCamera.SetActive(true);
|
||||||
@ -169,8 +170,8 @@ namespace Managers
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initiates a local battle by giving relavant information to the match manager
|
/// Initiates a local battle by giving relavant information to the responsible managers
|
||||||
/// and starting the match managers appropriate process.
|
/// and starting their appropriate processes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sceneId">Scene id of the chosen arena.</param>
|
/// <param name="sceneId">Scene id of the chosen arena.</param>
|
||||||
public IEnumerator SetupLocalMatchFromMainMenu()
|
public IEnumerator SetupLocalMatchFromMainMenu()
|
||||||
@ -246,6 +247,10 @@ namespace Managers
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Custom delegate which can be executed after scene load.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">Data of the loaded scene</param>
|
||||||
public delegate void CustomOnSceneLoaded(SceneLoadEventArgs args);
|
public delegate void CustomOnSceneLoaded(SceneLoadEventArgs args);
|
||||||
|
|
||||||
public class SceneLoadEventArgs : EventArgs
|
public class SceneLoadEventArgs : EventArgs
|
||||||
|
|||||||
@ -7,9 +7,6 @@ using PrimeTween;
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using GameLogic;
|
using GameLogic;
|
||||||
using Unity.VisualScripting;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Managers
|
namespace Managers
|
||||||
@ -24,7 +21,6 @@ namespace Managers
|
|||||||
private static string arenaAssetsPath = "Assets/ScriptedAssets/Arenas";
|
private static string arenaAssetsPath = "Assets/ScriptedAssets/Arenas";
|
||||||
private static string ruleAssetsPath = "Assets/ScriptedAssets/Rules";
|
private static string ruleAssetsPath = "Assets/ScriptedAssets/Rules";
|
||||||
|
|
||||||
private bool needsStartConfirmation = false;
|
|
||||||
public event Action OnStartPressed;
|
public event Action OnStartPressed;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Globally accessible member to use manager with.
|
/// Globally accessible member to use manager with.
|
||||||
@ -132,6 +128,9 @@ namespace Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates statistics for the players participating in the match.
|
||||||
|
/// </summary>
|
||||||
public void SetupMatchPlayerStatistics()
|
public void SetupMatchPlayerStatistics()
|
||||||
{
|
{
|
||||||
matchPlayerStatistics.Clear();
|
matchPlayerStatistics.Clear();
|
||||||
@ -190,6 +189,11 @@ namespace Managers
|
|||||||
matchState = MatchState.CharacterSelect;
|
matchState = MatchState.CharacterSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Announcement of who won.
|
||||||
|
/// TODO: Also restarts the match right now, no matter what.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mr">Result data of the completed match.</param>
|
||||||
async public void AnnounceWinner(MatchResult mr)
|
async public void AnnounceWinner(MatchResult mr)
|
||||||
{
|
{
|
||||||
UIManager.G.announcments.QueueAnnounceText($"{mr.Winner.playerName}" +
|
UIManager.G.announcments.QueueAnnounceText($"{mr.Winner.playerName}" +
|
||||||
@ -205,6 +209,10 @@ namespace Managers
|
|||||||
RestartMatch();
|
RestartMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the match anew.
|
||||||
|
/// Resetting player positions and statistics.
|
||||||
|
/// </summary>
|
||||||
public void RestartMatch()
|
public void RestartMatch()
|
||||||
{
|
{
|
||||||
ResetMatchCharacters();
|
ResetMatchCharacters();
|
||||||
@ -212,6 +220,10 @@ namespace Managers
|
|||||||
matchState = MatchState.Match;
|
matchState = MatchState.Match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the match, waits for match begin
|
||||||
|
/// confirmation by the players and counts down to start.
|
||||||
|
/// </summary>
|
||||||
async public void StartMatch()
|
async public void StartMatch()
|
||||||
{
|
{
|
||||||
foreach (Player p in matchPlayers)
|
foreach (Player p in matchPlayers)
|
||||||
|
|||||||
@ -1,16 +1,24 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Managers;
|
|
||||||
using TMPro;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine.InputSystem;
|
|
||||||
|
|
||||||
namespace GameLogic
|
namespace GameLogic
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Updates and checks a matches rules according to the state of the match.
|
||||||
|
/// </summary>
|
||||||
public static class MatchLogic
|
public static class MatchLogic
|
||||||
{
|
{
|
||||||
public static MatchRule currentRule;
|
public static MatchRule currentRule;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update match conditions and check for match conclusion.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">Affected player</param>
|
||||||
|
/// <param name="args">Update to the matches conditions</param>
|
||||||
|
/// <param name="mps">Dictionary of the players in the match and their current stats</param>
|
||||||
|
/// <returns></returns>
|
||||||
public static MatchResult UpdateMatchResult(Player p, MatchConditionUpdate args, Dictionary<Player, MatchPlayerStatistic> mps)
|
public static MatchResult UpdateMatchResult(Player p, MatchConditionUpdate args, Dictionary<Player, MatchPlayerStatistic> mps)
|
||||||
{
|
{
|
||||||
switch (args.Condition)
|
switch (args.Condition)
|
||||||
|
|||||||
@ -27,6 +27,7 @@ public class NimbleZoneDetection : MonoBehaviour
|
|||||||
private Zone zone = Zone.NimbleZone;
|
private Zone zone = Zone.NimbleZone;
|
||||||
|
|
||||||
// Ripple properties
|
// Ripple properties
|
||||||
|
// These influence the shader on the nimble zone
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private float rippleFrequency = 3f;
|
private float rippleFrequency = 3f;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
@ -39,10 +40,10 @@ public class NimbleZoneDetection : MonoBehaviour
|
|||||||
private float rippleDuration = 1f;
|
private float rippleDuration = 1f;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private float impactVelocityModifier = 1f;
|
private float impactVelocityModifier = 1f;
|
||||||
[SerializeField]
|
[SerializeField, Tooltip("Minimum ripple effect intensity.")]
|
||||||
[Range(0, 1)]
|
[Range(0, 1)]
|
||||||
private float minImpact = 0.2f;
|
private float minImpact = 0.2f;
|
||||||
[SerializeField]
|
[SerializeField, Tooltip("Velocity which makes the highest/most intense ripples.")]
|
||||||
private float maxVelocity = 45f;
|
private float maxVelocity = 45f;
|
||||||
private int maxRippleAmount = 5;
|
private int maxRippleAmount = 5;
|
||||||
private MeshRenderer meshRenderer;
|
private MeshRenderer meshRenderer;
|
||||||
@ -55,19 +56,37 @@ public class NimbleZoneDetection : MonoBehaviour
|
|||||||
ResetRippleShaderProperties();
|
ResetRippleShaderProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Array of the available gravities.
|
||||||
|
/// </summary>
|
||||||
private Func<Transform, Vector3>[] gravityFunctions =
|
private Func<Transform, Vector3>[] gravityFunctions =
|
||||||
{ DownGravity, NoGravity, InwardsGravity, OutwardsGravity };
|
{ DownGravity, NoGravity, InwardsGravity, OutwardsGravity };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Function which returns a gravity zero vector.
|
||||||
|
/// </summary>
|
||||||
private static Func<Transform, Vector3> NoGravity =
|
private static Func<Transform, Vector3> NoGravity =
|
||||||
new(transform => new Vector3());
|
new(transform => new Vector3());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
private static Func<Transform, Vector3> DownGravity =
|
private static Func<Transform, Vector3> DownGravity =
|
||||||
new(transform => transform.parent.rotation * Vector3.down * gravityFactor);
|
new(transform => transform.parent.rotation * Vector3.down * gravityFactor);
|
||||||
|
|
||||||
// TODO: This is too specific maybe?
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
private static Func<Transform, Vector3> InwardsGravity =
|
private static Func<Transform, Vector3> InwardsGravity =
|
||||||
new(transform => (transform.position - transform.parent.position).normalized * -gravityFactor);
|
new(transform => (transform.position - transform.parent.position).normalized * -gravityFactor);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
private static Func<Transform, Vector3> OutwardsGravity =
|
private static Func<Transform, Vector3> OutwardsGravity =
|
||||||
new Func<Transform, Vector3>(transform =>
|
new Func<Transform, Vector3>(transform =>
|
||||||
(transform.position - transform.parent.position).normalized * gravityFactor);
|
(transform.position - transform.parent.position).normalized * gravityFactor);
|
||||||
@ -113,12 +132,24 @@ public class NimbleZoneDetection : MonoBehaviour
|
|||||||
material.SetFloat("_ShaderTime", Time.timeSinceLevelLoad);
|
material.SetFloat("_ShaderTime", Time.timeSinceLevelLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float ImpactVelocityEffect(float duration, float velocity)
|
/// <summary>
|
||||||
|
/// Calculates the effect which a given velocity has on a ripple property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="duration">Initial value of the ripple property</param>
|
||||||
|
/// <param name="velocity">Velocity of the impact</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private float ImpactVelocityEffect(float initial, float velocity)
|
||||||
{
|
{
|
||||||
return math.max(math.smoothstep(0, maxVelocity, velocity), minImpact)
|
return math.max(math.smoothstep(0, maxVelocity, velocity), minImpact)
|
||||||
* impactVelocityModifier * duration;
|
* impactVelocityModifier * initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spawns ripples on the shader of the nimble zone.
|
||||||
|
/// Up to 5 parallel ripples.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collider"></param>
|
||||||
|
/// <param name="isOutwardsRipple"></param>
|
||||||
private void SpawnRipple(Collider collider, bool isOutwardsRipple)
|
private void SpawnRipple(Collider collider, bool isOutwardsRipple)
|
||||||
{
|
{
|
||||||
Rigidbody body = collider.attachedRigidbody;
|
Rigidbody body = collider.attachedRigidbody;
|
||||||
@ -174,6 +205,9 @@ public class NimbleZoneDetection : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the ripple shaders exposed properties to 0
|
||||||
|
/// </summary>
|
||||||
private void ResetRippleShaderProperties()
|
private void ResetRippleShaderProperties()
|
||||||
{
|
{
|
||||||
Vector4[] rippleOrigins = new Vector4[maxRippleAmount];
|
Vector4[] rippleOrigins = new Vector4[maxRippleAmount];
|
||||||
|
|||||||
@ -6,6 +6,11 @@ using UnityEngine;
|
|||||||
public class PlayingFieldDetection : MonoBehaviour
|
public class PlayingFieldDetection : MonoBehaviour
|
||||||
{
|
{
|
||||||
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the match conditions, when a ship leaves the playing field.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collider"></param>
|
||||||
private void OnTriggerExit(Collider collider)
|
private void OnTriggerExit(Collider collider)
|
||||||
{
|
{
|
||||||
if (collider.tag == "Ship")
|
if (collider.tag == "Ship")
|
||||||
|
|||||||
@ -87,6 +87,9 @@ public class Ship : MonoBehaviour
|
|||||||
UpdateTackleResponse(isCriticalTackle);
|
UpdateTackleResponse(isCriticalTackle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Movement logic and simulation of the ship.
|
||||||
|
/// </summary>
|
||||||
void UpdateMovement()
|
void UpdateMovement()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -144,9 +147,14 @@ public class Ship : MonoBehaviour
|
|||||||
Color.black);
|
Color.black);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates a vector to mitigate the ship drifting when it's changing direction.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentVelocity">Current velocity of the ship</param>
|
||||||
|
/// <param name="zone">Zone which the ship is in</param>
|
||||||
|
/// <returns></returns>
|
||||||
Vector3 DriftDampeningAcceleration(Vector3 currentVelocity, Zone zone)
|
Vector3 DriftDampeningAcceleration(Vector3 currentVelocity, Zone zone)
|
||||||
{
|
{
|
||||||
// TODO: add in ifs for ignoring small deviations
|
|
||||||
Vector3 antiDriftVelocity;
|
Vector3 antiDriftVelocity;
|
||||||
float antiDriftFactor;
|
float antiDriftFactor;
|
||||||
// Cancel out inertia/drifting
|
// Cancel out inertia/drifting
|
||||||
@ -170,6 +178,12 @@ public class Ship : MonoBehaviour
|
|||||||
return antiDriftVelocity * props.antiDriftAmount * antiDriftFactor;
|
return antiDriftVelocity * props.antiDriftAmount * antiDriftFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates drag on the ship depending on it's velocity and inhabited zone.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentVelocity">Velocity of the ship</param>
|
||||||
|
/// <param name="zone">Zone which the ship is in</param>
|
||||||
|
/// <returns></returns>
|
||||||
Vector3 DragDecceleration(Vector3 currentVelocity, Zone zone)
|
Vector3 DragDecceleration(Vector3 currentVelocity, Zone zone)
|
||||||
{
|
{
|
||||||
Vector3 drag = new Vector3();
|
Vector3 drag = new Vector3();
|
||||||
@ -190,11 +204,23 @@ public class Ship : MonoBehaviour
|
|||||||
return drag;
|
return drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the boost input pressed and boosting possible?
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Boosting state</returns>
|
||||||
bool IsBoosting()
|
bool IsBoosting()
|
||||||
{
|
{
|
||||||
return state.boostInput > 0 && canBoost;
|
return state.boostInput > 0 && canBoost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies boost to an acceleration vector.
|
||||||
|
/// This includes increasing acceleration and mitigating
|
||||||
|
/// the gravity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="acceleration">Current acceleration vector</param>
|
||||||
|
/// <param name="currentGravity">Gravity vector which is in force</param>
|
||||||
|
/// <returns></returns>
|
||||||
Vector3 BoostAcceleration(Vector3 acceleration, Vector3 currentGravity)
|
Vector3 BoostAcceleration(Vector3 acceleration, Vector3 currentGravity)
|
||||||
{
|
{
|
||||||
if (IsBoosting())
|
if (IsBoosting())
|
||||||
@ -205,39 +231,44 @@ public class Ship : MonoBehaviour
|
|||||||
return acceleration;
|
return acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logic which depletes boost capacity when boost conditions are met.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">Time delta of the current frame</param>
|
||||||
void BoostStateUpdate(float deltaTime)
|
void BoostStateUpdate(float deltaTime)
|
||||||
{
|
{
|
||||||
boostUI.UpdateFill(Math.Min(state.boostCapacity / props.maxBoostCapacity, 1));
|
boostUI.UpdateFill(Math.Min(state.boostCapacity / props.maxBoostCapacity, 1));
|
||||||
if (IsBoosting() && state.thrustInput != 0)
|
if (IsBoosting() && state.thrustInput != 0)
|
||||||
{
|
{
|
||||||
// Debug.Log("Boost Kapazität wird verbraucht: " + boostCapacity);
|
|
||||||
state.boostCapacity -= deltaTime;
|
state.boostCapacity -= deltaTime;
|
||||||
}
|
}
|
||||||
if (canBoost && zone == Zone.OutsideZone)
|
if (canBoost && zone == Zone.OutsideZone)
|
||||||
{
|
{
|
||||||
// Debug.Log("Boost Kapazität wird passiv verbraucht: " + boostCapacity);
|
|
||||||
state.boostCapacity -= deltaTime * props.outsideBoostRate;
|
state.boostCapacity -= deltaTime * props.outsideBoostRate;
|
||||||
}
|
}
|
||||||
if (state.boostCapacity <= 0)
|
if (state.boostCapacity <= 0)
|
||||||
{
|
{
|
||||||
canBoost = false;
|
canBoost = false;
|
||||||
// Debug.Log("Boost aufgebraucht");
|
|
||||||
}
|
}
|
||||||
// TODO this will be spam abused
|
|
||||||
if ((state.boostInput <= 0 || state.thrustInput == 0 || !canBoost)
|
if ((state.boostInput <= 0 || state.thrustInput == 0 || !canBoost)
|
||||||
&& zone == Zone.NimbleZone
|
&& zone == Zone.NimbleZone
|
||||||
&& state.boostCapacity <= props.maxBoostCapacity)
|
&& state.boostCapacity <= props.maxBoostCapacity)
|
||||||
{
|
{
|
||||||
// Debug.Log("Boost wird aufgeladen: " + boostCapacity);
|
|
||||||
state.boostCapacity += deltaTime;
|
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)
|
if (canBoost == false && state.boostCapacity >= props.minBoostCapacity)
|
||||||
{
|
{
|
||||||
canBoost = true;
|
canBoost = true;
|
||||||
// Debug.Log("Boost verfügbar");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logic which sets the isTackled state.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gotTackled">Use true to process a tackle hit</param>
|
||||||
void UpdateTackleResponse(bool gotTackled = false)
|
void UpdateTackleResponse(bool gotTackled = false)
|
||||||
{
|
{
|
||||||
if (gotTackled && !isTackled)
|
if (gotTackled && !isTackled)
|
||||||
@ -256,6 +287,13 @@ public class Ship : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called by the collision regions which detect tackling.
|
||||||
|
/// Adds resulting forces to the ship and intiates the tackle
|
||||||
|
/// response.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tackleKind">Kind of the tackle. Depends on collision region.</param>
|
||||||
|
/// <param name="collider">Object which has collided with the collision region.</param>
|
||||||
void StartTackleResponse(TackleKind tackleKind, Collider collider)
|
void StartTackleResponse(TackleKind tackleKind, Collider collider)
|
||||||
{
|
{
|
||||||
float tacklePowerFactor = props.criticalTacklePowerFactor;
|
float tacklePowerFactor = props.criticalTacklePowerFactor;
|
||||||
|
|||||||
@ -2,6 +2,9 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace ShipHandling
|
namespace ShipHandling
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Variables for the ship which can also be under the players control.
|
||||||
|
/// </summary>
|
||||||
public class ShipState
|
public class ShipState
|
||||||
{
|
{
|
||||||
public float thrustInput = 0;
|
public float thrustInput = 0;
|
||||||
|
|||||||
@ -1,10 +1,18 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used on vulnerable trigger zones for ships.
|
||||||
|
/// </summary>
|
||||||
public class TackleDetection : MonoBehaviour
|
public class TackleDetection : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private TackleKind tackleKind;
|
[SerializeField] private TackleKind tackleKind;
|
||||||
public UnityEvent<TackleKind, Collider> TackleResponse;
|
public UnityEvent<TackleKind, Collider> TackleResponse;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the fitting tackle response on trigger entered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collider"></param>
|
||||||
void OnTriggerEnter(Collider collider)
|
void OnTriggerEnter(Collider collider)
|
||||||
{
|
{
|
||||||
if (collider.tag != "Spike" && collider.tag != "Bumper")
|
if (collider.tag != "Spike" && collider.tag != "Bumper")
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using Unity.VisualScripting;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides methods for displaying text on a text mesh pro.
|
||||||
|
/// Features a queue for messages which dissapear after a set time.
|
||||||
|
/// </summary>
|
||||||
public class Announcments : MonoBehaviour
|
public class Announcments : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] TextMeshProUGUI announcementText;
|
[SerializeField] TextMeshProUGUI announcementText;
|
||||||
@ -13,6 +15,9 @@ public class Announcments : MonoBehaviour
|
|||||||
private bool workingOnQueue = false;
|
private bool workingOnQueue = false;
|
||||||
private float remainingTime;
|
private float remainingTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the message queue.
|
||||||
|
/// </summary>
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
if (!workingOnQueue && announcementQueue.Count != 0)
|
if (!workingOnQueue && announcementQueue.Count != 0)
|
||||||
@ -38,20 +43,10 @@ public class Announcments : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AnnounceText(string text, float time)
|
/// <summary>
|
||||||
{
|
/// Shows the text without time limit.
|
||||||
announcementText.text = text;
|
/// </summary>
|
||||||
announcementText.enabled = true;
|
/// <param name="text">Text to be shown.</param>
|
||||||
remainingTime = time;
|
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueAnnounceText(string text, float time)
|
|
||||||
{
|
|
||||||
announcementQueue.Enqueue(new Tuple<string, float>(text, time));
|
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AnnounceText(string text)
|
public void AnnounceText(string text)
|
||||||
{
|
{
|
||||||
announcementText.text = text;
|
announcementText.text = text;
|
||||||
@ -60,6 +55,33 @@ public class Announcments : MonoBehaviour
|
|||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the announcement text for a certain time.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="time">Time in seconds</param>
|
||||||
|
private void AnnounceText(string text, float time)
|
||||||
|
{
|
||||||
|
announcementText.text = text;
|
||||||
|
announcementText.enabled = true;
|
||||||
|
remainingTime = time;
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an announcement to the queue.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">Text to be shown.</param>
|
||||||
|
/// <param name="time">Time of the announcement in seconds.</param>
|
||||||
|
public void QueueAnnounceText(string text, float time)
|
||||||
|
{
|
||||||
|
announcementQueue.Enqueue(new Tuple<string, float>(text, time));
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stop the announcement and clear the queue.
|
||||||
|
/// </summary>
|
||||||
public void StopAnnouncement()
|
public void StopAnnouncement()
|
||||||
{
|
{
|
||||||
announcementQueue.Clear();
|
announcementQueue.Clear();
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
using TMPro;
|
using TMPro;
|
||||||
using Unity.VisualScripting;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HUD element which displays a ships remaining boost capacity.
|
||||||
|
/// </summary>
|
||||||
public class BoostCapacityUI : MonoBehaviour
|
public class BoostCapacityUI : MonoBehaviour
|
||||||
{
|
{
|
||||||
public Color goodColor = Color.green;
|
public Color goodColor = Color.green;
|
||||||
@ -12,6 +14,11 @@ public class BoostCapacityUI : MonoBehaviour
|
|||||||
[SerializeField] private TextMeshProUGUI hint;
|
[SerializeField] private TextMeshProUGUI hint;
|
||||||
private float minBoostRatio = 0.3f;
|
private float minBoostRatio = 0.3f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ratio of capacity to max capacity under which the
|
||||||
|
/// boost capacity is considered critically low.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minBoostRatio"></param>
|
||||||
public void SetMinBoostRatio(float minBoostRatio)
|
public void SetMinBoostRatio(float minBoostRatio)
|
||||||
{
|
{
|
||||||
this.minBoostRatio = minBoostRatio;
|
this.minBoostRatio = minBoostRatio;
|
||||||
@ -22,6 +29,10 @@ public class BoostCapacityUI : MonoBehaviour
|
|||||||
hint.SetText($"Boost Capacity \n {p.playerName} \n {p.character.shipName}");
|
hint.SetText($"Boost Capacity \n {p.playerName} \n {p.character.shipName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the color and fill of the capacity meter.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fill">Fill percentage</param>
|
||||||
public void UpdateFill(float fill)
|
public void UpdateFill(float fill)
|
||||||
{
|
{
|
||||||
fillImage.fillAmount = fill;
|
fillImage.fillAmount = fill;
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Unity.VisualScripting;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Colleciton class for referencing and controlling HUD elements.
|
||||||
|
/// </summary>
|
||||||
public class HUD : MonoBehaviour
|
public class HUD : MonoBehaviour
|
||||||
{
|
{
|
||||||
public BoostCapacityUI[] boostCapacities;
|
public BoostCapacityUI[] boostCapacities;
|
||||||
public JoinPrompt[] joinPrompts;
|
public JoinPrompt[] joinPrompts;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start a join prompt.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player">Player to which the prompt belongs</param>
|
||||||
public void StartJoinPrompt(Player player)
|
public void StartJoinPrompt(Player player)
|
||||||
{
|
{
|
||||||
foreach (JoinPrompt jp in joinPrompts)
|
foreach (JoinPrompt jp in joinPrompts)
|
||||||
|
|||||||
@ -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")]
|
[Tooltip("The GameObject holding the Audio Source component for the SWOOSH SOUND when switching to the Settings Screen")]
|
||||||
public AudioSource swooshSound;
|
public AudioSource swooshSound;
|
||||||
|
|
||||||
// [Header("Options")]
|
|
||||||
// public bool flyCameraLoadTransition = true;
|
|
||||||
|
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
GM = GameManager.G;
|
GM = GameManager.G;
|
||||||
@ -212,11 +208,11 @@ namespace SlimUI.ModernMenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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
|
/// Also Initiates the setup of the local match once the Gameplay UI is
|
||||||
/// loaded.
|
/// loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns>IEnumerator for async statemachine</returns>
|
||||||
private IEnumerator SwitchToIngameUI()
|
private IEnumerator SwitchToIngameUI()
|
||||||
{
|
{
|
||||||
AsyncOperation o = SceneManager.LoadSceneAsync((int)Scenes.GameplayUserInterface,
|
AsyncOperation o = SceneManager.LoadSceneAsync((int)Scenes.GameplayUserInterface,
|
||||||
|
|||||||
26
README.md
Normal file
26
README.md
Normal file
@ -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.
|
||||||
Loading…
Reference in New Issue
Block a user