Added saving of buildings

This commit is contained in:
2026-04-13 19:11:21 +01:00
parent d8253bd275
commit 1faca796ba
9 changed files with 175 additions and 38 deletions

View File

@@ -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}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e6ae3d283005f994da00a3d8835a3cb5
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1806,7 +1806,9 @@ MonoBehaviour:
BuildingManager: {fileID: 2005593405} BuildingManager: {fileID: 2005593405}
CurrentMouseClickStrength: 0 CurrentMouseClickStrength: 0
GridPosition: {x: 0, y: 0} GridPosition: {x: 0, y: 0}
SelectedBuildingToBuild: {fileID: 0} SelectedBuildingToBuild:
Name:
Prefab: {fileID: 0}
FlipCurrentBuilding: 0 FlipCurrentBuilding: 0
--- !u!58 &1330313879 --- !u!58 &1330313879
CircleCollider2D: CircleCollider2D:
@@ -2810,16 +2812,7 @@ MonoBehaviour:
MenuGrid: {fileID: 1484797012} MenuGrid: {fileID: 1484797012}
MenuItemPrefab: {fileID: 1541142508120997748, guid: 74aff4063df1fab4c954bebfad022ff5, MenuItemPrefab: {fileID: 1541142508120997748, guid: 74aff4063df1fab4c954bebfad022ff5,
type: 3} type: 3}
BuildingPrefabs: BuildingPrefabs: {fileID: 11400000, guid: e6ae3d283005f994da00a3d8835a3cb5, type: 2}
- 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}
--- !u!1660057539 &9223372036854775807 --- !u!1660057539 &9223372036854775807
SceneRoots: SceneRoots:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -14,7 +14,17 @@ namespace Fruitomation.Game
private BuildingManager Manager; 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() [UsedImplicitly, Preserve, InspectorCallable("Click Building")] public void OnBuildingClicked()
{ {

View File

@@ -1,10 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEngine.Scripting;
using UnityEngine; using UnityEngine;
using System;
using System.IO;
using System.Linq;
namespace Fruitomation.Game namespace Fruitomation.Game
{ {
public class BuildingManager : MonoBehaviour public class BuildingManager : MonoBehaviour
{ {
[SerializeField] private BuildingRegistry Registry;
private class BuildingInfo private class BuildingInfo
{ {
public BuildingInfo(Building b, RectTransform rt) public BuildingInfo(Building b, RectTransform rt)
@@ -17,33 +24,108 @@ namespace Fruitomation.Game
public RectTransform Rect { get; } 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<SerializedBuilding> buildings) =>
Buildings = buildings.ToArray();
}
private static string Filepath => Path.Combine(Application.persistentDataPath, "buildings.json");
private bool[,] InhabitedCells { get; } = new bool[96, 49]; private bool[,] InhabitedCells { get; } = new bool[96, 49];
private List<Building> Buildings { get; } = new(); private List<Building> Buildings { get; } = new();
private void Start()
{
if (!File.Exists(Filepath))
{
return;
}
string json = File.ReadAllText(Filepath);
SerializedBuilding[] buildings = JsonUtility.FromJson<SerializedBuildings>(json).Get();
foreach (SerializedBuilding building in buildings)
{
GameObject prefab = Registry.GetBuildingOf(building.PrefabName);
GameObject go = Instantiate(prefab, transform);
BuildingInfo info = new
(
go.GetComponent<Building>(),
go.GetComponent<RectTransform>()
);
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<SerializedBuilding> 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 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 BuildingInfo info = new
( (
go.GetComponent<Building>(), go.GetComponent<Building>(),
go.GetComponent<RectTransform>() go.GetComponent<RectTransform>()
); );
go.name = $"{building.Name}";
info.Building.SetManager(this);
Vector2Int p0 = position * 40; Vector2Int p0 = position * 40;
Vector2Int p1 = p0 + new Vector2Int(20, 100); Vector2Int p1 = p0 + new Vector2Int(20, 100);
Vector2Int g0 = position + new Vector2Int(48, 24); Vector2Int g0 = position + new Vector2Int(48, 24);
Vector2 off0 = info.Building.SizeOnGrid - Vector2.one; Vector2Int off0 = info.Building.SizeOnGrid - Vector2Int.one;
Vector2 off1 = off0 * 20; Vector2Int off1 = off0 * 20;
Vector2Int p2 = p1 + off1;
info.Rect.sizeDelta = info.Building.SizeOnGrid * 40; 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); info.Rect.transform.localScale = new Vector3(isFlipped ? -1f : 1f, 1f, 1f);
@@ -65,7 +147,9 @@ namespace Fruitomation.Game
InhabitedCells[x, y] = true; InhabitedCells[x, y] = true;
} }
info.Building.Init(this, g0, p2, isFlipped);
Buildings.Add(info.Building); Buildings.Add(info.Building);
return true; return true;
} }
} }

View File

@@ -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<BuildingInfo> Buildings;
public BuildingInfo[] GetBuildings() => Buildings.ToArray();
public GameObject GetBuildingOf(string building)
{
return (from info in Buildings where info.Name == building select info.Prefab).FirstOrDefault();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 406e966552b740c1aece5036cefe9bb7
timeCreated: 1776095957

View File

@@ -1,26 +1,18 @@
using System.Collections.Generic; using Fruitomation.Global;
using Fruitomation.Global; using Fruitomation.Game;
using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityEngine;
namespace Fruitomation.UI namespace Fruitomation.UI
{ {
public class BuildingMenu : MonoBehaviour public class BuildingMenu : MonoBehaviour
{ {
[System.Serializable] private class BuildingInfo
{
public string Name;
public GameObject Prefab;
}
[Header("References")] [Header("References")]
[SerializeField] private GameCursor Cursor; [SerializeField] private GameCursor Cursor;
[SerializeField] private GameObject Menu; [SerializeField] private GameObject Menu;
[SerializeField] private GameObject MenuGrid; [SerializeField] private GameObject MenuGrid;
[SerializeField] private GameObject MenuItemPrefab; [SerializeField] private GameObject MenuItemPrefab;
[SerializeField] private BuildingRegistry BuildingPrefabs;
[Header("Options")]
[SerializeField] private List<BuildingInfo> BuildingPrefabs;
private void Update() private void Update()
{ {
@@ -29,7 +21,7 @@ namespace Fruitomation.UI
private void Start() private void Start()
{ {
foreach (BuildingInfo info in BuildingPrefabs) foreach (BuildingRegistry.BuildingInfo info in BuildingPrefabs.GetBuildings())
{ {
GameObject go = Instantiate(MenuItemPrefab, MenuGrid.transform); GameObject go = Instantiate(MenuItemPrefab, MenuGrid.transform);
Text text = go.GetComponentInChildren<Text>(); Text text = go.GetComponentInChildren<Text>();
@@ -40,7 +32,7 @@ namespace Fruitomation.UI
butt.onClick.AddListener(() => butt.onClick.AddListener(() =>
{ {
GameStateController.State = GameState.Building; GameStateController.State = GameState.Building;
Cursor.SetSelectedBuildingToBuild(info.Prefab); Cursor.SetSelectedBuildingToBuild(info);
}); });
} }
} }

View File

@@ -24,7 +24,7 @@ namespace Fruitomation.UI
[Header("Read Only")] [Header("Read Only")]
[SerializeField, InspectorReadOnly] private float CurrentMouseClickStrength; [SerializeField, InspectorReadOnly] private float CurrentMouseClickStrength;
[SerializeField, InspectorReadOnly] private Vector2Int GridPosition; [SerializeField, InspectorReadOnly] private Vector2Int GridPosition;
[SerializeField, InspectorReadOnly] private GameObject SelectedBuildingToBuild; [SerializeField, InspectorReadOnly] private BuildingRegistry.BuildingInfo SelectedBuildingToBuild;
[SerializeField, InspectorReadOnly] private bool FlipCurrentBuilding; [SerializeField, InspectorReadOnly] private bool FlipCurrentBuilding;
private readonly ContactFilter2D ContactFilter = new(); private readonly ContactFilter2D ContactFilter = new();
@@ -35,9 +35,9 @@ namespace Fruitomation.UI
private float StartOfMouseClick; private float StartOfMouseClick;
private bool MouseOnGrid; private bool MouseOnGrid;
public void SetSelectedBuildingToBuild(GameObject prefab) public void SetSelectedBuildingToBuild(BuildingRegistry.BuildingInfo prefab)
{ {
SelectedBuildingsBuildingBase = prefab.GetComponent<Building>(); SelectedBuildingsBuildingBase = prefab.Prefab.GetComponent<Building>();
SelectedBuildingToBuild = prefab; SelectedBuildingToBuild = prefab;
FlipCurrentBuilding = false; FlipCurrentBuilding = false;