Проблема в том, что InstanceID игрового объекта (Game Object) или самого префаба ничего не знает о вашей логике инвентаря. Для Unity это просто "клон объекта".
Чтобы «Dropped Item» знал, чем он является (меч, зелье или камень), вы должны
прикрепить к префабу скрипт, который будет хранить эту информацию.
Вот два основных способа решения: правильный (через компонент) и быстрый (через имя).
Способ 1: Использование компонента-обертки (Рекомендуемый)
Это самый надежный способ. Вы создаете скрипт, который висит на префабе и хранит ссылку на данные предмета (ID или ScriptableObject).
1. Создайте скрипт для выброшенного предмета
Назовем его WorldItem или ItemPickup. Повесьте его на ваш префаб.
C#
<span>using</span> UnityEngine;<br><br><span>public</span> <span>class</span> <span>WorldItem</span> : <span>MonoBehaviour</span><br>{<br> <span>// Здесь храним данные. Это может быть int ID или ссылка на ScriptableObject</span><br> [<span>SerializeField</span>] <span>private</span> <span>int</span> _itemId; <br> [<span>SerializeField</span>] <span>private</span> <span>string</span> _itemName;<br> <br> <span>// Публичный метод для инициализации предмета при спавне</span><br> <span><span>public</span> <span>void</span> <span>Initialize</span>(<span><span>int</span> id, <span>string</span> name</span>)</span><br> {<br> _itemId = id;<br> _itemName = name;<br> <br> <span>// Тут можно поменять спрайт или модельку в зависимости от ID</span><br> }<br><br> <span>// Геттеры для получения данных извне</span><br> <span><span>public</span> <span>int</span> <span>GetID</span>(<span></span>)</span> => _itemId;<br> <span><span>public</span> <span>string</span> <span>GetName</span>(<span></span>)</span> => _itemName;<br>}<br>
2. Как передать данные при выбрасывании (Drop)
Когда вы выбрасываете предмет из инвентаря, вы должны записать в него данные:
C#
<span><span>public</span> <span>void</span> <span>DropItem</span>(<span>GameObject itemPrefab, Vector3 position, <span>int</span> id, <span>string</span> name</span>)</span><br>{<br> <span>// Создаем объект в мире</span><br> GameObject droppedObj = Instantiate(itemPrefab, position, Quaternion.identity);<br><br> <span>// Получаем наш компонент и передаем данные</span><br> WorldItem worldItemScript = droppedObj.GetComponent<WorldItem>();<br> <br> <span>if</span> (worldItemScript != <span>null</span>)<br> {<br> worldItemScript.Initialize(id, name);<br> }<br>}<br>
3. Как получить ItemID при подборе
Когда игрок кликает мышкой или наступает в триггер:
C#
<span><span>void</span> <span>OnTriggerEnter</span>(<span>Collider other</span>)</span><br>{<br> <span>// Проверяем, есть ли на объекте наш компонент</span><br> <span>if</span> (other.TryGetComponent(<span>out</span> WorldItem item))<br> {<br> <span>int</span> id = item.GetID(); <span>// Получили ID!</span><br> <span>string</span> name = item.GetName(); <span>// Получили имя!</span><br> <br> Debug.Log(<span>$"Подобран предмет: <span>{name}</span> с ID: <span>{id}</span>"</span>);<br> <br> <span>// Логика добавления в инвентарь...</span><br> Destroy(other.gameObject);<br> }<br>}<br>
Способ 2: Парсинг имени (Не рекомендуется, но работает)
Если вы не хотите создавать отдельный скрипт, можно менять имя игрового объекта (gameObject.name) при спавне, а потом читать его. Но это "грязный" метод.
При выбрасывании:
C#
GameObject droppedObj = Instantiate(prefab, pos, rot);<br>droppedObj.name = <span>"Item_Sword_101"</span>; <span>// Зашиваем данные в имя</span><br>
При получении:
C#
<span>string</span> objName = other.gameObject.name; <span>// Получим "Item_Sword_101" или "Item_Sword_101(Clone)"</span><br><br><span>// Придется очищать от "(Clone)" если Unity его добавила</span><br>objName = objName.Replace(<span>"(Clone)"</span>, <span>""</span>).Trim();<br><br><span>// Разбираем строку, если нужно</span><br><span>string</span>[] parts = objName.Split(<span>'_'</span>); <br><span>// parts[1] будет "Sword", parts[2] будет "101"</span><br>
Почему Способ 1 лучше?
- Скорость: GetComponent и чтение переменной работают быстрее, чем операции со строками (Split, Replace).
- Типизация: Вы точно знаете, что ID — это число, а не строка.
- Гибкость: В скрипте WorldItem можно хранить не только ID, но и количество (StackSize), прочность предмета и т.д.
Могу подсказать, как реализовать это, если вы используете ScriptableObjects (SO) вместо int ID?