Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: in-game configuration settings #102

Merged
merged 13 commits into from
Jun 23, 2024
8,664 changes: 7,263 additions & 1,401 deletions aplib.net-demo/Assets/Prefabs/UI/MainMenuCanvas.prefab

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions aplib.net-demo/Assets/Scenes/Settings.unity
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,6 @@ PrefabInstance:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 4110221563777805256, guid: 1f89b5875b8d87943a589e68bd51cc9f,
type: 3}
propertyPath: _gameSceneName
value: Main
objectReference: {fileID: 0}
- target: {fileID: 5555664739242282512, guid: 1f89b5875b8d87943a589e68bd51cc9f,
type: 3}
propertyPath: m_AnchorMax.y
Expand Down
279 changes: 279 additions & 0 deletions aplib.net-demo/Assets/Scripts/Configuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
using LevelGeneration;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using Unity.Plastic.Newtonsoft.Json.Linq;
using Unity.VisualScripting.YamlDotNet.Core.Tokens;
using UnityEngine;
using UnityEngine.UI;

public class Configuration : MonoBehaviour
{
[SerializeField] private const float _maxPercentage = 0.7f;
[SerializeField] private const float _minPercentage = 0.2f;

[SerializeField] private SpawnableEnemies _spawnableEnemies;
[SerializeField] private SpawnableItems _spawnableItems;
[SerializeField] private GridConfig _gridConfig;

// Grid component variables.
public int MinGridSize => 3;
public int MaxGridSize => 100;

public int GridVolume { get; private set; }

[SerializeField]
public int GridSizeX { get; private set; } = 3;
[SerializeField]
public int GridSizeZ { get; private set; } = 3;

// Room component.
[SerializeField]
public int RoomAmount { get; private set; } = 0;

// Item ammo.
JensSteenmetz marked this conversation as resolved.
Show resolved Hide resolved
[SerializeField]
public int AmmoItemAmount { get; private set; } = 0;

// Item health.
[SerializeField]
public int HealthItemAmount { get; private set; } = 0;

// Item rage.
[SerializeField]
public int RageItemAmount { get; private set; } = 0;

// Enemy melee.
[SerializeField]
public int MeleeEnemyAmount { get; private set; } = 0;

// Enemy ranged.
[SerializeField]
public int RangedEnemyAmount { get; private set; } = 0;

/// <summary>
/// Max total items that can excist in 1 maze.
/// </summary>
public int TotalItemCount { get; private set; }
/// <summary>
/// Max total enemies that can excist in 1 maze.
/// </summary>
public int TotalEnemyCount { get; private set; }

// Disables TMP fields so unity can run the unit tests.
public bool TestingSwitch { get; set; }

// Input fields.
public TMP_InputField inputFieldXGrid;
public TMP_InputField inputFieldZGrid;
public TMP_InputField inputFieldRoom;
public TMP_InputField inputFieldAmmoItem;
public TMP_InputField inputFieldHealthItem;
public TMP_InputField inputFieldRageItem;
public TMP_InputField inputFieldMeleeEnemy;
public TMP_InputField inputFieldRangedEnemy;

private void Start()
{
// Initialize values.
GridVolume = GridSizeZ * GridSizeX;

TotalItemCount = AmmoItemAmount + HealthItemAmount + RageItemAmount;
TotalEnemyCount = RangedEnemyAmount + MeleeEnemyAmount;
}

/// <summary>
/// Check if input does not exceed the max or min boundry.
/// Set valid input.
/// </summary>
/// <param name="value">Input given from the player through the input field</param>
public void SetGridX(string value)
{
GridSizeX = value == string.Empty ? MinGridSize : int.Parse(value);
CheckAllValuesToBeValid();
}

/// <summary>
/// Check if input does not exceed the max or min boundry.
/// Set valid input.
/// </summary>
/// <param name="value">Input given from the player through the input field</param>
public void SetGridZ(string value)
{
GridSizeZ = value == string.Empty ? MinGridSize : int.Parse(value);
CheckAllValuesToBeValid();
}

/// <summary>
/// Set inputfield amount to variable.
/// Then call check to validate value.
/// </summary>
/// <param name="amount">Amount of rooms.</param>
public void SetValueRoom(string amount)
{
RoomAmount = amount == string.Empty ? 0 : int.Parse(amount);
CheckAllValuesToBeValid();
}

/// <summary>
/// Set inputfield amount to variable.
/// Then call check to validate value.
/// </summary>
/// <param name="amount">Amount of ammo.</param>
public void SetValueItemAmmo(string amount)
{
AmmoItemAmount = amount == string.Empty ? 0 : int.Parse(amount);
CheckAllValuesToBeValid();
}

/// <summary>
/// Set inputfield amount to variable.
/// Then call check to validate value.
/// </summary>
/// <param name="amount">Amount of health potions.</param>
public void SetValueItemHealth(string amount)
{
HealthItemAmount = amount == string.Empty ? 0 : int.Parse(amount);
CheckAllValuesToBeValid();
}

/// <summary>
/// Set inputfield amount to variable.
/// Then call check to validate value.
/// </summary>
/// <param name="amount">Amount of rage potions.</param>
public void SetValueItemRage(string amount)
{
RageItemAmount = amount == string.Empty ? 0 : int.Parse(amount);
CheckAllValuesToBeValid();
}

/// <summary>
/// Set inputfield amount to variable.
/// Then call check to validate value.
/// </summary>
/// <param name="amount">Amount of melee enemies.</param>
public void SetValueEnemyMelee(string amount)
{
MeleeEnemyAmount = amount == string.Empty ? 0 : int.Parse(amount);
CheckAllValuesToBeValid();
}

/// <summary>
/// Set inputfield amount to variable.
/// Then call check to validate value.
/// </summary>
/// <param name="amount">Amount of ranged enemies.</param>
public void SetValueEnemyRanged(string amount)
{
RangedEnemyAmount = amount == string.Empty ? 0 : int.Parse(amount);
CheckAllValuesToBeValid();
}

/// <summary>
/// This is called when the grid values are changed.
/// This is also called when an individual component has changed.
/// It updates all other conponents.
/// </summary>
private void CheckAllValuesToBeValid()
{
// Check gridW and gridH
if (GridSizeX > MaxGridSize) GridSizeX = MaxGridSize;
else if (GridSizeX < MinGridSize) GridSizeX = MinGridSize;

if (GridSizeZ > MaxGridSize) GridSizeZ = MaxGridSize;
else if (GridSizeZ < MinGridSize) GridSizeZ = MinGridSize;

// Update value.
GridVolume = GridSizeX * GridSizeZ;

int minValue = Mathf.CeilToInt(GridVolume * _minPercentage);
int maxValue = Mathf.CeilToInt(GridVolume * _maxPercentage);

// Check room value.
RoomAmount = Mathf.Max(minValue, Mathf.Min(maxValue, RoomAmount));

// Check ItemAmmoAmount value.
AmmoItemAmount = Mathf.Max(minValue, Mathf.Min(maxValue, AmmoItemAmount));

// Check ItemHealthAmount value.
HealthItemAmount = Mathf.Max(minValue, Mathf.Min(maxValue, HealthItemAmount));

// Check ItemRageAmount value.
RageItemAmount = Mathf.Max(minValue, Mathf.Min(maxValue, RageItemAmount));

// Check EnemyMeleeAmount value.
MeleeEnemyAmount = Mathf.Max(minValue, Mathf.Min(maxValue, MeleeEnemyAmount));

// Check EnemyRangedAmount value.
RangedEnemyAmount = Mathf.Max(minValue, Mathf.Min(maxValue, RangedEnemyAmount));

// Check if items and enemies don't go over grid vol * _maxPrecentage(0.7f)
CheckItemOverflow();
CheckEnemyOverflow();

// Print correct number in text field. Skip this when testing.
if (!TestingSwitch)
{
inputFieldXGrid.text = GridSizeX.ToString();
inputFieldZGrid.text = GridSizeZ.ToString();
inputFieldRoom.text = RoomAmount.ToString();
inputFieldAmmoItem.text = AmmoItemAmount.ToString();
inputFieldHealthItem.text = HealthItemAmount.ToString();
inputFieldRageItem.text = RageItemAmount.ToString();
inputFieldMeleeEnemy.text = MeleeEnemyAmount.ToString();
inputFieldRangedEnemy.text = RangedEnemyAmount.ToString();

UpdateConfigValuesInScriptableScript();
}
}

public void CheckItemOverflow()
{
TotalItemCount = AmmoItemAmount + HealthItemAmount + RageItemAmount;
if (TotalItemCount > GridVolume * _maxPercentage)
{
int maxCount = Mathf.CeilToInt(GridVolume * _maxPercentage / 3);
JensSteenmetz marked this conversation as resolved.
Show resolved Hide resolved

TotalItemCount = Mathf.CeilToInt(GridVolume * _maxPercentage);
AmmoItemAmount = maxCount;
HealthItemAmount = maxCount;
RageItemAmount = maxCount;
}
}

public void CheckEnemyOverflow()
{
TotalEnemyCount = RangedEnemyAmount + MeleeEnemyAmount;
if (TotalEnemyCount > GridVolume * _maxPercentage)
{
int maxCount = Mathf.CeilToInt(GridVolume * _maxPercentage / 3);
JensSteenmetz marked this conversation as resolved.
Show resolved Hide resolved

TotalItemCount = Mathf.CeilToInt(GridVolume * _maxPercentage);
MeleeEnemyAmount = maxCount;
RangedEnemyAmount = maxCount;
}
}

/// <summary>
/// This method updates all 3 scriptable scripts for the grid, items and enemies values.
/// Doing this the level generation can use these value to generate.
/// </summary>
private void UpdateConfigValuesInScriptableScript()
{
// Set size and rooms.
_gridConfig.GridWidthX = GridSizeX;
_gridConfig.GridWidthZ = GridSizeZ;
_gridConfig.AmountOfRooms = RoomAmount;

// Set enemies.
_spawnableEnemies.Enemies[0].Count = MeleeEnemyAmount;
_spawnableEnemies.Enemies[1].Count = RangedEnemyAmount;

// Set items.
_spawnableItems.Items[0].Count = AmmoItemAmount;
_spawnableItems.Items[1].Count = HealthItemAmount;
_spawnableItems.Items[2].Count = RageItemAmount;
}
}
11 changes: 11 additions & 0 deletions aplib.net-demo/Assets/Scripts/Configuration.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions aplib.net-demo/Assets/Scripts/MainMenu/MainMenuCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ public class MainMenuCanvas : Singleton<MainMenuCanvas>
[field: SerializeField]
public GameObject SettingCanvas { get; set; }

/// <summary>
/// Reference to the configuration settings.
/// </summary>
[field: SerializeField]
public GameObject ConfigCanvas { get; set; }

/// <summary>
/// Reference to the help/keybinds canvas.
/// </summary>
Expand Down Expand Up @@ -70,6 +76,7 @@ private void HideAllCanvases()
{
HideCanvas(MenuCanvas);
HideCanvas(SettingCanvas);
HideCanvas(ConfigCanvas);
HideCanvas(HelpCanvas);
}

Expand Down Expand Up @@ -103,4 +110,26 @@ private void ToggleCanvas(GameObject canvas)
/// <param name="canvas">The canvas to check.</param>
/// <returns>True if the canvas is active, false otherwise.</returns>
private bool IsActive(GameObject canvas) => canvas && canvas.activeSelf;

/// <summary>
/// When the play button is pressed it will take the player to the configuration scene.
/// If the back button in this canvas is pressed it will go back to main menu.
/// </summary>
public void ProceedToConfig()
{
// Set all canvases to inactive.
HideCanvas(MenuCanvas);

// Set config or menu active and disable the other.
ShowCanvas(ConfigCanvas);
}

/// <summary>
/// Toggle for when the user wants to go back to the main menu.
/// </summary>
public void BackToMenu()
{
HideCanvas(ConfigCanvas);
ShowCanvas(MenuCanvas);
}
}
8 changes: 8 additions & 0 deletions aplib.net-demo/Assets/Testing/UnitTests.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading