Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Rust Dropped items

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
20 Ноя 2025
Сообщения
3
Реакции
0
Привет в dropped items prefab ид тот же не зависимо от самого drop item
как получить itemid из dropped item-a
или прочитать строку названия dropitem-a для сортировки и тд
 
Проблема в том, что 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> =&gt; _itemId;<br> <span><span>public</span> <span>string</span> <span>GetName</span>(<span></span>)</span> =&gt; _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&lt;WorldItem&gt;();<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 лучше?​

  1. Скорость: GetComponent и чтение переменной работают быстрее, чем операции со строками (Split, Replace).
  2. Типизация: Вы точно знаете, что ID — это число, а не строка.
  3. Гибкость: В скрипте WorldItem можно хранить не только ID, но и количество (StackSize), прочность предмета и т.д.
Могу подсказать, как реализовать это, если вы используете ScriptableObjects (SO) вместо int ID?
 
Проблема в том, что 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> =&gt; _itemId;<br> <span><span>public</span> <span>string</span> <span>GetName</span>(<span></span>)</span> =&gt; _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&lt;WorldItem&gt;();<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 лучше?​

  1. Скорость: GetComponent и чтение переменной работают быстрее, чем операции со строками (Split, Replace).
  2. Типизация: Вы точно знаете, что ID — это число, а не строка.
  3. Гибкость: В скрипте WorldItem можно хранить не только ID, но и количество (StackSize), прочность предмета и т.д.
Могу подсказать, как реализовать это, если вы используете ScriptableObjects (SO) вместо int ID?
это чё за пиздец? такое неиронке даже трудно будет выдать
 
Привет в dropped items prefab ид тот же не зависимо от самого drop item
как получить itemid из dropped item-a
или прочитать строку названия dropitem-a для сортировки и тд
потому что префабид это айди объекта типо игрок, крейт, шкаф и т.д, чтобы получить айди предмета тебе надо

auto base_networkable = ...;
if ( !base_networkable->is_class( _( "DroppedItem ) ) )
return;

// DroppedItem -> WorldItem -> Item
auto item = mem::read< sdk::c_item* >( base_networkable + offsets::world_item::item );
auto uid = mem::read< unsigned long >( item + offsets::item::uid );

вот ты и получил уид
 
Назад
Сверху Снизу