diff --git a/Assets/Prefabs/Buildings/Registry.asset b/Assets/Prefabs/Buildings/Registry.asset new file mode 100644 index 0000000..6e1bf8e --- /dev/null +++ b/Assets/Prefabs/Buildings/Registry.asset @@ -0,0 +1,24 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 406e966552b740c1aece5036cefe9bb7, type: 3} + m_Name: Registry + m_EditorClassIdentifier: Fruitomation::Fruitomation.Game.BuildingRegistry + Buildings: + - Name: Fan + Prefab: {fileID: 8624048914473773482, guid: 1b5c88b3f8d08674a9b15155d6ba9a36, + type: 3} + - Name: Stair + Prefab: {fileID: 2132872997366704715, guid: 3cf8228c3f6c43d4cb60319693b11828, + type: 3} + - Name: Wall + Prefab: {fileID: 1970033728917450326, guid: 3492b31295b69c148bb5a0660e598878, + type: 3} diff --git a/Assets/Prefabs/Buildings/Registry.asset.meta b/Assets/Prefabs/Buildings/Registry.asset.meta new file mode 100644 index 0000000..c439bdd --- /dev/null +++ b/Assets/Prefabs/Buildings/Registry.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e6ae3d283005f994da00a3d8835a3cb5 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index fcbb7a9..fe5e391 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -1806,7 +1806,9 @@ MonoBehaviour: BuildingManager: {fileID: 2005593405} CurrentMouseClickStrength: 0 GridPosition: {x: 0, y: 0} - SelectedBuildingToBuild: {fileID: 0} + SelectedBuildingToBuild: + Name: + Prefab: {fileID: 0} FlipCurrentBuilding: 0 --- !u!58 &1330313879 CircleCollider2D: @@ -2810,16 +2812,7 @@ MonoBehaviour: MenuGrid: {fileID: 1484797012} MenuItemPrefab: {fileID: 1541142508120997748, guid: 74aff4063df1fab4c954bebfad022ff5, type: 3} - BuildingPrefabs: - - Name: Fan - Prefab: {fileID: 8624048914473773482, guid: 1b5c88b3f8d08674a9b15155d6ba9a36, - type: 3} - - Name: Wall - Prefab: {fileID: 1970033728917450326, guid: 3492b31295b69c148bb5a0660e598878, - type: 3} - - Name: Stair - Prefab: {fileID: 2132872997366704715, guid: 3cf8228c3f6c43d4cb60319693b11828, - type: 3} + BuildingPrefabs: {fileID: 11400000, guid: e6ae3d283005f994da00a3d8835a3cb5, type: 2} --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Game/Buildings/Building.cs b/Assets/Scripts/Game/Buildings/Building.cs index 790c7c5..23b899b 100644 --- a/Assets/Scripts/Game/Buildings/Building.cs +++ b/Assets/Scripts/Game/Buildings/Building.cs @@ -14,8 +14,18 @@ namespace Fruitomation.Game private BuildingManager Manager; - public void SetManager(BuildingManager manager) => Manager = manager; - + public Vector2Int GridPosition { get; private set; } + public Vector2Int Position { get; private set; } + public bool IsFlipped { get; private set; } + + public void Init(BuildingManager manager, Vector2Int gridPosition, Vector2Int position, bool isFlipped) + { + GridPosition = gridPosition; + IsFlipped = isFlipped; + Position = position; + Manager = manager; + } + [UsedImplicitly, Preserve, InspectorCallable("Click Building")] public void OnBuildingClicked() { Debug.Log($"Building clicked {gameObject.name}"); diff --git a/Assets/Scripts/Game/Buildings/BuildingManager.cs b/Assets/Scripts/Game/Buildings/BuildingManager.cs index 95586c0..b051cbb 100644 --- a/Assets/Scripts/Game/Buildings/BuildingManager.cs +++ b/Assets/Scripts/Game/Buildings/BuildingManager.cs @@ -1,10 +1,17 @@ using System.Collections.Generic; +using JetBrains.Annotations; +using UnityEngine.Scripting; using UnityEngine; +using System; +using System.IO; +using System.Linq; namespace Fruitomation.Game { public class BuildingManager : MonoBehaviour { + [SerializeField] private BuildingRegistry Registry; + private class BuildingInfo { public BuildingInfo(Building b, RectTransform rt) @@ -17,33 +24,108 @@ namespace Fruitomation.Game public RectTransform Rect { get; } } + [Serializable] private class SerializedBuilding + { + [SerializeField, Preserve, UsedImplicitly] public Vector2Int GridPosition; + [SerializeField, Preserve, UsedImplicitly] public Vector2Int Position; + [SerializeField, Preserve, UsedImplicitly] public string PrefabName; + [SerializeField, Preserve, UsedImplicitly] public bool IsFlipped; + + public SerializedBuilding(Vector2Int gridPosition, Vector2Int pos, string name, bool flipped) + { + GridPosition = gridPosition; + IsFlipped = flipped; + PrefabName = name; + Position = pos; + } + } + + [Serializable] private class SerializedBuildings + { + [SerializeField, Preserve, UsedImplicitly] private SerializedBuilding[] Buildings; + public SerializedBuilding[] Get() => Buildings; + + public SerializedBuildings(List buildings) => + Buildings = buildings.ToArray(); + } + + private static string Filepath => Path.Combine(Application.persistentDataPath, "buildings.json"); + private bool[,] InhabitedCells { get; } = new bool[96, 49]; private List Buildings { get; } = new(); - + + private void Start() + { + if (!File.Exists(Filepath)) + { + return; + } + + string json = File.ReadAllText(Filepath); + SerializedBuilding[] buildings = JsonUtility.FromJson(json).Get(); + + foreach (SerializedBuilding building in buildings) + { + GameObject prefab = Registry.GetBuildingOf(building.PrefabName); + GameObject go = Instantiate(prefab, transform); + + BuildingInfo info = new + ( + go.GetComponent(), + go.GetComponent() + ); + + info.Rect.transform.localScale = new Vector3(building.IsFlipped ? -1f : 1f, 1f, 1f); + info.Rect.sizeDelta = info.Building.SizeOnGrid * 40; + info.Rect.anchoredPosition = building.Position; + go.name = $"{building.PrefabName}"; + + info.Building.Init(this, building.GridPosition, building.Position, building.IsFlipped); + Buildings.Add(info.Building); + } + } + + private void OnDestroy() + { + Debug.Log($"Buildings: [{Buildings.Count}]"); + + List serialized = Buildings.Select(building => new SerializedBuilding + ( + building.GridPosition, + building.Position, + building.name, + building.IsFlipped + ) + ).ToList(); + + string json = JsonUtility.ToJson(new SerializedBuildings(serialized), false); + File.WriteAllText(Filepath, json); + } + public void RemoveBuilding(Building building) => Buildings.Remove(building); - public bool AddBuildingAt(Vector2Int position, GameObject prefab, bool isFlipped) + public bool AddBuildingAt(Vector2Int position, BuildingRegistry.BuildingInfo building, bool isFlipped) { // - GameObject go = Instantiate(prefab, transform); + GameObject go = Instantiate(building.Prefab, transform); BuildingInfo info = new ( go.GetComponent(), go.GetComponent() ); - - info.Building.SetManager(this); + go.name = $"{building.Name}"; Vector2Int p0 = position * 40; Vector2Int p1 = p0 + new Vector2Int(20, 100); Vector2Int g0 = position + new Vector2Int(48, 24); - Vector2 off0 = info.Building.SizeOnGrid - Vector2.one; - Vector2 off1 = off0 * 20; + Vector2Int off0 = info.Building.SizeOnGrid - Vector2Int.one; + Vector2Int off1 = off0 * 20; + Vector2Int p2 = p1 + off1; info.Rect.sizeDelta = info.Building.SizeOnGrid * 40; - info.Rect.anchoredPosition = p1 + off1; + info.Rect.anchoredPosition = p2; info.Rect.transform.localScale = new Vector3(isFlipped ? -1f : 1f, 1f, 1f); @@ -65,7 +147,9 @@ namespace Fruitomation.Game InhabitedCells[x, y] = true; } + info.Building.Init(this, g0, p2, isFlipped); Buildings.Add(info.Building); + return true; } } diff --git a/Assets/Scripts/Game/Buildings/BuildingRegistry.cs b/Assets/Scripts/Game/Buildings/BuildingRegistry.cs new file mode 100644 index 0000000..a3199d4 --- /dev/null +++ b/Assets/Scripts/Game/Buildings/BuildingRegistry.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace Fruitomation.Game +{ + [CreateAssetMenu] public class BuildingRegistry : ScriptableObject + { + [System.Serializable] public class BuildingInfo + { + public string Name; + public GameObject Prefab; + } + + [SerializeField] private List Buildings; + public BuildingInfo[] GetBuildings() => Buildings.ToArray(); + + public GameObject GetBuildingOf(string building) + { + return (from info in Buildings where info.Name == building select info.Prefab).FirstOrDefault(); + } + } +} diff --git a/Assets/Scripts/Game/Buildings/BuildingRegistry.cs.meta b/Assets/Scripts/Game/Buildings/BuildingRegistry.cs.meta new file mode 100644 index 0000000..4be06fb --- /dev/null +++ b/Assets/Scripts/Game/Buildings/BuildingRegistry.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 406e966552b740c1aece5036cefe9bb7 +timeCreated: 1776095957 \ No newline at end of file diff --git a/Assets/Scripts/UI/BuildingMenu.cs b/Assets/Scripts/UI/BuildingMenu.cs index 6bd8eec..1437b80 100644 --- a/Assets/Scripts/UI/BuildingMenu.cs +++ b/Assets/Scripts/UI/BuildingMenu.cs @@ -1,26 +1,18 @@ -using System.Collections.Generic; -using Fruitomation.Global; -using UnityEngine; +using Fruitomation.Global; +using Fruitomation.Game; using UnityEngine.UI; +using UnityEngine; namespace Fruitomation.UI { public class BuildingMenu : MonoBehaviour { - [System.Serializable] private class BuildingInfo - { - public string Name; - public GameObject Prefab; - } - [Header("References")] [SerializeField] private GameCursor Cursor; [SerializeField] private GameObject Menu; [SerializeField] private GameObject MenuGrid; [SerializeField] private GameObject MenuItemPrefab; - - [Header("Options")] - [SerializeField] private List BuildingPrefabs; + [SerializeField] private BuildingRegistry BuildingPrefabs; private void Update() { @@ -29,7 +21,7 @@ namespace Fruitomation.UI private void Start() { - foreach (BuildingInfo info in BuildingPrefabs) + foreach (BuildingRegistry.BuildingInfo info in BuildingPrefabs.GetBuildings()) { GameObject go = Instantiate(MenuItemPrefab, MenuGrid.transform); Text text = go.GetComponentInChildren(); @@ -40,7 +32,7 @@ namespace Fruitomation.UI butt.onClick.AddListener(() => { GameStateController.State = GameState.Building; - Cursor.SetSelectedBuildingToBuild(info.Prefab); + Cursor.SetSelectedBuildingToBuild(info); }); } } diff --git a/Assets/Scripts/UI/GameCursor.cs b/Assets/Scripts/UI/GameCursor.cs index 7579ce9..1c6e53c 100644 --- a/Assets/Scripts/UI/GameCursor.cs +++ b/Assets/Scripts/UI/GameCursor.cs @@ -24,7 +24,7 @@ namespace Fruitomation.UI [Header("Read Only")] [SerializeField, InspectorReadOnly] private float CurrentMouseClickStrength; [SerializeField, InspectorReadOnly] private Vector2Int GridPosition; - [SerializeField, InspectorReadOnly] private GameObject SelectedBuildingToBuild; + [SerializeField, InspectorReadOnly] private BuildingRegistry.BuildingInfo SelectedBuildingToBuild; [SerializeField, InspectorReadOnly] private bool FlipCurrentBuilding; private readonly ContactFilter2D ContactFilter = new(); @@ -35,9 +35,9 @@ namespace Fruitomation.UI private float StartOfMouseClick; private bool MouseOnGrid; - public void SetSelectedBuildingToBuild(GameObject prefab) + public void SetSelectedBuildingToBuild(BuildingRegistry.BuildingInfo prefab) { - SelectedBuildingsBuildingBase = prefab.GetComponent(); + SelectedBuildingsBuildingBase = prefab.Prefab.GetComponent(); SelectedBuildingToBuild = prefab; FlipCurrentBuilding = false;