Skip to content

Commit f70c59c

Browse files
committed
feat(core): add tutorial 42 code
1 parent 9cf84f5 commit f70c59c

5 files changed

Lines changed: 244 additions & 1 deletion

File tree

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using UnityEngine;
5+
using UnityEngine.UI;
6+
7+
public class MainMenuManager : MonoBehaviour
8+
{
9+
private static readonly Color[] _playerColors = new Color[]
10+
{
11+
Color.red,
12+
Color.blue,
13+
Color.yellow,
14+
Color.green,
15+
Color.cyan,
16+
Color.magenta,
17+
Color.white,
18+
Color.gray,
19+
};
20+
21+
[Header("Prefabs")]
22+
public GameObject menuScenePickPrefab;
23+
public GameObject playerPickerPrefab;
24+
25+
[Header("UI")]
26+
public Transform newGameScrollview;
27+
public Image newGameDetailMapCapture;
28+
public Text newGameDetailInfoText;
29+
public Transform newGamePlayersList;
30+
public Button startGameButton;
31+
32+
private MapData _selectedMap;
33+
private List<bool> _activePlayers;
34+
private Dictionary<int, PlayerData> _playersData;
35+
private List<Color> _availableColors;
36+
37+
private void Start()
38+
{
39+
_PopulateMapsList();
40+
}
41+
42+
#region New Game
43+
private void _PopulateMapsList()
44+
{
45+
MapData[] maps = Resources.LoadAll<MapData>("ScriptableObjects/Maps");
46+
Transform t; Sprite s;
47+
foreach (MapData map in maps)
48+
{
49+
GameObject g = Instantiate(menuScenePickPrefab, newGameScrollview);
50+
t = g.transform;
51+
s = Resources.Load<Sprite>($"MapCaptures/{map.sceneName}");
52+
t.Find("MapCapture").GetComponent<Image>().sprite = s;
53+
t.Find("Data/Name").GetComponent<Text>().text = map.mapName;
54+
t.Find("Data/Desc").GetComponent<Text>().text =
55+
$"{map.GetMapSizeType()} map, max {map.maxPlayers} players";
56+
_AddScenePickListener(g.GetComponent<Button>(), map, s);
57+
}
58+
}
59+
60+
private void _SelectMap(MapData map, Sprite mapSprite)
61+
{
62+
_selectedMap = map;
63+
startGameButton.interactable = true;
64+
65+
_availableColors = new List<Color>(_playerColors);
66+
67+
foreach (Transform child in newGamePlayersList)
68+
Destroy(child.gameObject);
69+
70+
newGameDetailMapCapture.sprite = mapSprite;
71+
newGameDetailInfoText.text = $"{map.mapName} <size=20>({map.mapSize}x{map.mapSize})</size>";
72+
73+
_activePlayers = new List<bool>(map.maxPlayers);
74+
_playersData = new Dictionary<int, PlayerData>(map.maxPlayers);
75+
string name;
76+
for (int i = 0; i < map.maxPlayers; i++)
77+
{
78+
name = i == 0 ? "Player" : $"Enemy {i}";
79+
_activePlayers.Add(false);
80+
_playersData[i] = new PlayerData(name, _playerColors[i]);
81+
82+
Transform player = Instantiate(playerPickerPrefab, newGamePlayersList).transform;
83+
player.Find("Name/InputField").GetComponent<InputField>().text = name;
84+
Image colorSprite = player.Find("Color/Content").GetComponent<Image>();
85+
colorSprite.color = _playersData[i].color;
86+
87+
Transform colorsPicker = player.Find("Color/ColorsPicker");
88+
Transform picker;
89+
90+
player.Find("Color/Content").GetComponent<Button>().onClick.AddListener(() =>
91+
{
92+
for (int j = 0; j < _playerColors.Length; j++)
93+
{
94+
picker = colorsPicker.Find("Background").GetChild(j);
95+
picker.GetComponent<Button>().interactable =
96+
_availableColors.Contains(_playerColors[j]);
97+
}
98+
colorsPicker.gameObject.SetActive(true);
99+
});
100+
101+
for (int j = 0; j < _playerColors.Length; j++)
102+
{
103+
picker = colorsPicker.Find("Background").GetChild(j);
104+
picker.GetComponent<Image>().color = _playerColors[j];
105+
_AddScenePickPlayerColorListener(
106+
colorsPicker, colorSprite,
107+
picker.GetComponent<Button>(),
108+
i, j);
109+
}
110+
111+
_AddScenePickPlayerInputListener(
112+
player.Find("Name/InputField").GetComponent<InputField>(),
113+
i);
114+
115+
if (i <= 1)
116+
{
117+
player.Find("Toggle").GetComponent<Button>().interactable = false;
118+
_TogglePlayer(player, i);
119+
}
120+
else
121+
{
122+
_AddScenePickPlayerToggleListener(
123+
player.Find("Toggle").GetComponent<Button>(),
124+
player,
125+
i);
126+
}
127+
}
128+
}
129+
130+
private void _SetPlayerColor(
131+
Color color, int i, Image colorSprite, bool autoAdd = true)
132+
{
133+
if (autoAdd && _playersData[i].color != null)
134+
_availableColors.Add(_playersData[i].color);
135+
_availableColors.Remove(color);
136+
_playersData[i].color = color;
137+
colorSprite.color = color;
138+
}
139+
140+
private void _SetPlayerName(string value, int i)
141+
{
142+
_playersData[i].name = value;
143+
}
144+
145+
private void _TogglePlayer(Transform t, int i)
146+
{
147+
bool active = !_activePlayers[i];
148+
_activePlayers[i] = active;
149+
float from = active ? 42 : 0;
150+
float to = active ? 0 : 42;
151+
t.Find("Toggle/Checkmark").gameObject.SetActive(active);
152+
StartCoroutine(_TogglingPlayer(t.Find("Color/Block")
153+
.GetComponent<RectTransform>(), from, to, 42));
154+
StartCoroutine(_TogglingPlayer(t.Find("Name/Block")
155+
.GetComponent<RectTransform>(), from, to, 274));
156+
157+
// check for player colors duplicates
158+
Color c = _playersData[i].color;
159+
if (active)
160+
{
161+
if (_availableColors.Contains(c))
162+
_availableColors.Remove(c);
163+
else
164+
_SetPlayerColor(
165+
_availableColors[0], i,
166+
t.Find("Color/Content").GetComponent<Image>(),
167+
false);
168+
}
169+
else
170+
{
171+
if (!_availableColors.Contains(c))
172+
_availableColors.Add(c);
173+
}
174+
175+
// check there are at least 2 players active
176+
startGameButton.interactable =
177+
_activePlayers.Where(a => a).Count() >= 2;
178+
}
179+
180+
private IEnumerator _TogglingPlayer(RectTransform rt, float from, float to, float width)
181+
{
182+
rt.sizeDelta = new Vector2(to, from);
183+
float t = 0f;
184+
while (t < 0.5f)
185+
{
186+
rt.sizeDelta = new Vector2(Mathf.Lerp(from, to, t * 2f), width);
187+
t += Time.deltaTime;
188+
yield return null;
189+
}
190+
rt.sizeDelta = new Vector2(to, width);
191+
}
192+
193+
private void _AddScenePickListener(Button b, MapData map, Sprite mapSprite)
194+
{
195+
b.onClick.AddListener(() => _SelectMap(map, mapSprite));
196+
}
197+
198+
private void _AddScenePickPlayerColorListener(Transform colorsPicker, Image colorSprite, Button b, int i, int c)
199+
{
200+
b.onClick.AddListener(() => {
201+
_SetPlayerColor(_playerColors[c], i, colorSprite);
202+
colorsPicker.gameObject.SetActive(false);
203+
});
204+
}
205+
206+
private void _AddScenePickPlayerInputListener(InputField f, int i)
207+
{
208+
f.onValueChanged.AddListener((string value) => _SetPlayerName(value, i));
209+
}
210+
211+
private void _AddScenePickPlayerToggleListener(Button b, Transform t, int i)
212+
{
213+
b.onClick.AddListener(() => _TogglePlayer(t, i));
214+
}
215+
216+
#endregion
217+
218+
}

Assets/Scripts/Managers/MainMenuManager.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Scripts/ScriptableObjects/MapData.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,12 @@ public class MapData : ScriptableObject
99
public int maxPlayers;
1010

1111
public string sceneName;
12+
13+
public string GetMapSizeType()
14+
{
15+
if (mapSize <= 200) return "Small";
16+
if (mapSize <= 500) return "Medium";
17+
if (mapSize <= 1200) return "Large";
18+
return "Immense";
19+
}
1220
}

Assets/Scripts/ScriptableObjects/Parameters/GamePlayersParameters.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ public class PlayerData : BinarySerializable
77
public string name;
88
public Color color;
99

10+
public PlayerData(string name, Color color)
11+
{
12+
this.name = name;
13+
this.color = color;
14+
}
15+
1016
protected PlayerData(SerializationInfo info, StreamingContext context)
1117
: base(info, context) { }
1218
}

Assets/Scripts/Tools/MinimapCapture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public static void TakeScreenshot(string name, Vector2Int size, Camera camera)
2424
Object.DestroyImmediate(output);
2525

2626
// write to a file in the project folder
27-
string folderPath = Application.dataPath + "/MapCaptures";
27+
string folderPath = Application.dataPath + "/Resources/MapCaptures";
2828
if (!Directory.Exists(folderPath))
2929
Directory.CreateDirectory(folderPath);
3030
string filePath = $"{folderPath}/{name}.jpg";

0 commit comments

Comments
 (0)