feat(shop): configurable package display rotation, pocoregal shelf model

Add _displayRotationEuler to Lieferkarton/ShelfSlot so package prefabs
with a non-upright export orientation can be corrected per-container
without touching PackageDisplay code. Fixes a bug where flying packages
landed with a different rotation than the resting shelf display
(PlayerCarry used the raw shelf transform instead of
ShelfSlot.GetSlotWorldRotation()).

Also adds the pocoregal shelf model (Blender export) and its materials,
places it in the Shop scene, registers ShelfSlot as a network prefab,
and rescales EmptyBox. See docs/PACKAGE_DISPLAY_SETUP.md for the
display-grid setup/troubleshooting reference.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 16:13:32 +02:00
co-authored by Claude Sonnet 5
parent 8ca4858082
commit 9eb588e491
19 changed files with 1126 additions and 285 deletions
+9 -1
View File
@@ -24,6 +24,7 @@ namespace AfterHours.Shop
[SerializeField] private int _displayColumns = 4;
[SerializeField] private int _displayRows = 3;
[SerializeField] private Vector3 _displaySpacing = new(0.1f, 0.1f, 0.1f);
[SerializeField] private Vector3 _displayRotationEuler = Vector3.zero;
private readonly NetworkVariable<int> _productId = new(-1);
private readonly NetworkVariable<int> _quantity = new(0);
@@ -41,7 +42,7 @@ namespace AfterHours.Shop
private PackageDisplay _packageDisplay;
private void Awake() => _packageDisplay = new PackageDisplay(_displayRoot, _displayColumns, _displayRows, _displaySpacing);
private void Awake() => _packageDisplay = new PackageDisplay(_displayRoot, _displayColumns, _displayRows, _displaySpacing, _displayRotationEuler);
/// <summary>Weltposition des Rasterplatzes mit gegebenem Index Ziel fürs Flug-Visual (siehe PlayerCarry).</summary>
public Vector3 GetSlotWorldPosition(int index)
@@ -49,6 +50,13 @@ namespace AfterHours.Shop
return _displayRoot != null ? _displayRoot.TransformPoint(_packageDisplay.SlotLocalPosition(index)) : transform.position;
}
/// <summary>Endrotation eines Pakets im Regal muss zur ruhenden Anzeige passen, siehe PlayerCarry.</summary>
public Quaternion GetSlotWorldRotation()
{
Quaternion baseRotation = _displayRoot != null ? _displayRoot.rotation : transform.rotation;
return baseRotation * Quaternion.Euler(_displayRotationEuler);
}
public override void OnNetworkSpawn()
{
_quantity.OnValueChanged += (_, _) => RefreshVisuals();