Files
Shopkeeper/Assets/Scripts/Items/Shelf.cs
Caleb Sandford deQuincey e9c9bc4409 initial game submission
2025-06-11 13:04:35 +01:00

179 lines
5.7 KiB
C#

using UnityEngine;
using System.Collections.Generic;
public class Shelf : MonoBehaviour
{
public ShelfData shelfData;
public ShelfData.ShelfType shelfType => shelfData.shelfType;
[HideInInspector] public Transform[] stackPoints;
public List<string> stockedItems = new List<string>();
public bool useManualLevelHeights = false; // Toggle in Inspector
void Awake()
{
GenerateStaticStackPoints();
}
// Generates a static grid of stack points based on rows and columns
public void GenerateStaticStackPoints()
{
if (shelfData == null)
{
Debug.LogError("ShelfData not assigned!");
return;
}
// --- Preserve stacked items ---
List<Transform> itemsToPreserve = new List<Transform>();
foreach (Transform child in transform)
{
if (child.name.StartsWith("StackPoint_"))
{
// Save and unparent any items parented to this stack point
List<Transform> toUnparent = new List<Transform>();
foreach (Transform item in child)
{
itemsToPreserve.Add(item);
toUnparent.Add(item);
}
foreach (var item in toUnparent)
item.parent = this.transform; // Temporarily unparent to shelf root
}
}
// Remove old stack points
var toRemove = new List<Transform>();
foreach (Transform child in transform)
if (child.name.StartsWith("StackPoint_"))
toRemove.Add(child);
foreach (var child in toRemove)
DestroyImmediate(child.gameObject);
// ...rest of your code...
int totalPoints = shelfData.rows * shelfData.columns * shelfData.levels;
stackPoints = new Transform[totalPoints];
int idx = 0;
for (int l = 0; l < shelfData.levels; l++)
{
float y = useManualLevelHeights && shelfData.manualLevelHeights != null && l < shelfData.manualLevelHeights.Length
? shelfData.manualLevelHeights[l]
: (shelfData.shelfSize.y / shelfData.levels) * (l + 0.5f);
for (int r = 0; r < shelfData.rows; r++)
{
for (int c = 0; c < shelfData.columns; c++)
{
float x = (-shelfData.shelfSize.x / 2) + (shelfData.shelfSize.x / shelfData.columns) * (c + 0.5f);
float z = (shelfData.shelfSize.z / 2) - (shelfData.shelfSize.z / shelfData.rows) * (r + 0.5f);
Vector3 localOffset = new Vector3(x, y, z) + shelfData.stackOriginOffset;
GameObject point = new GameObject($"StackPoint_{l}_{r}_{c}");
point.transform.parent = this.transform;
point.transform.localPosition = localOffset;
stackPoints[idx++] = point.transform;
}
}
}
// --- Re-parent preserved items to the closest new stack point ---
foreach (var item in itemsToPreserve)
{
// Find the nearest stack point to the item's position
Transform nearest = null;
float minDist = float.MaxValue;
foreach (var sp in stackPoints)
{
float dist = Vector3.Distance(sp.position, item.position);
if (dist < minDist)
{
minDist = dist;
nearest = sp;
}
}
if (nearest != null)
item.parent = nearest;
else
item.parent = this.transform; // fallback
}
}
public void AddStockedItem(string itemName)
{
if (!stockedItems.Contains(itemName))
stockedItems.Add(itemName);
}
public void RemoveStockedItem(string itemName)
{
stockedItems.Remove(itemName);
}
public Transform GetNextAvailableStackPoint()
{
foreach (var point in stackPoints)
{
if (point.childCount == 0)
return point;
}
return null;
}
public Transform GetNearestStackPoint(Vector3 hitPosition, out bool isOccupied)
{
Transform nearest = null;
float minDist = float.MaxValue;
isOccupied = false;
foreach (var point in stackPoints)
{
float dist = Vector3.Distance(point.position, hitPosition);
if (dist < minDist)
{
minDist = dist;
nearest = point;
}
}
if (nearest != null)
isOccupied = nearest.childCount > 0;
return nearest;
}
// Draws the grid in the editor for configuration
void OnDrawGizmos()
{
if (shelfData == null)
return;
Gizmos.color = Color.cyan;
Gizmos.DrawWireCube(transform.position + Vector3.up * shelfData.shelfSize.y * 0.5f, shelfData.shelfSize);
for (int l = 0; l < shelfData.levels; l++)
{
float y = useManualLevelHeights && shelfData.manualLevelHeights != null && l < shelfData.manualLevelHeights.Length
? shelfData.manualLevelHeights[l]
: (shelfData.shelfSize.y / shelfData.levels) * (l + 0.5f);
for (int r = 0; r < shelfData.rows; r++)
{
for (int c = 0; c < shelfData.columns; c++)
{
float x = (-shelfData.shelfSize.x / 2) + (shelfData.shelfSize.x / shelfData.columns) * (c + 0.5f);
// Z: match runtime!
float z = (shelfData.shelfSize.z / 2) - (shelfData.shelfSize.z / shelfData.rows) * (r + 0.5f);
Vector3 localOffset = new Vector3(x, y, z) + shelfData.stackOriginOffset;
Vector3 worldPos = transform.TransformPoint(localOffset);
Gizmos.color = Color.yellow;
Gizmos.DrawWireCube(worldPos, Vector3.one * 0.04f);
Gizmos.color = Color.red;
Gizmos.DrawSphere(worldPos, 0.02f);
}
}
}
}
}