Files
2026-04-16 01:51:46 +05:00

107 lines
4.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
/// <summary>
/// Показывает модель активного предмета хотбара в руке персонажа.
/// Принцип — как в Minecraft: выбранный слот хотбара = предмет в правой руке.
/// Добавьте на Player, назначьте handBone в Inspector.
/// </summary>
public class HandEquipSystem : MonoBehaviour
{
[Header("Hand Setup")]
[Tooltip("Кость правой руки из скелета персонажа")]
public Transform handBone;
[Tooltip("Смещение предмета относительно кости руки")]
public Vector3 itemOffset = Vector3.zero;
[Tooltip("Поворот предмета в руке (euler)")]
public Vector3 itemRotation = Vector3.zero;
[Tooltip("Масштаб предмета в руке")]
public Vector3 itemScale = Vector3.one;
// ── Приватные поля ────────────────────────────────────────────────────────
private GameObject _currentHandItem;
// ── Lifecycle ─────────────────────────────────────────────────────────────
void Start()
{
// Подписываемся на смену слота хотбара
if (PlayerInput.Instance != null)
PlayerInput.Instance.OnHotbarSelect += OnHotbarSlotSelected;
// Подписываемся на изменение слотов (drag-drop, добавление/удаление)
if (InventoryEvents.Instance != null)
InventoryEvents.Instance.OnSlotChanged.AddListener(OnSlotChanged);
UpdateHandItem();
}
void OnDestroy()
{
if (PlayerInput.Instance != null)
PlayerInput.Instance.OnHotbarSelect -= OnHotbarSlotSelected;
if (InventoryEvents.Instance != null)
InventoryEvents.Instance.OnSlotChanged.RemoveListener(OnSlotChanged);
}
// ── Обработчики событий ───────────────────────────────────────────────────
private void OnHotbarSlotSelected(int index) => UpdateHandItem();
private void OnSlotChanged(int slotIndex, string itemId) => UpdateHandItem();
// ── Логика обновления предмета в руке ────────────────────────────────────
/// <summary>
/// Обновить объект в руке под текущий выбранный слот хотбара.
/// Можно вызвать вручную если нужно принудительное обновление.
/// </summary>
public void UpdateHandItem()
{
// Уничтожить старый объект в руке
if (_currentHandItem != null)
{
Destroy(_currentHandItem);
_currentHandItem = null;
}
if (handBone == null)
{
Debug.LogWarning("[HandEquipSystem] handBone не назначен!");
return;
}
if (InventoryManager.Instance == null) return;
var item = InventoryManager.Instance.GetSelectedHotbarItem();
if (item == null || item.modelPrefab == null) return;
// Создать модель как дочерний объект кости руки
_currentHandItem = Instantiate(item.modelPrefab, handBone);
_currentHandItem.name = $"HandItem_{item.itemName}";
_currentHandItem.transform.localPosition = itemOffset;
_currentHandItem.transform.localEulerAngles = itemRotation;
_currentHandItem.transform.localScale = itemScale;
// Отключить физику и коллайдеры — предмет в руке не должен взаимодействовать с миром
foreach (var col in _currentHandItem.GetComponentsInChildren<Collider>())
col.enabled = false;
foreach (var rb in _currentHandItem.GetComponentsInChildren<Rigidbody>())
rb.isKinematic = true;
}
/// <summary>
/// Убрать предмет из руки (например когда открыт инвентарь).
/// </summary>
public void ClearHandItem()
{
if (_currentHandItem != null)
{
Destroy(_currentHandItem);
_currentHandItem = null;
}
}
}