решено
спасибо, что нашли время посмотреть мой вопрос.
В настоящее время я работаю над проектом, использующим Unity3D, и столкнулся с некоторыми трудностями при создании системы инвентаризации.Проведя некоторые исследования, я решил, что в моих интересах использовать List of ScriptableObjects (Item) для создания этой системы инвентаризации из-за простоты управления и расширяемости списков.
JustВ качестве примера у меня есть пункт под названием «Череп».Когда игрок указывает на череп, мой код предлагает пользователю нажать F, чтобы взять предмет, который, в свою очередь, должен удалить экземпляр предмета из игрового мира и добавить экземпляр этого предмета в инвентарь.
Больше всего проблем вызывает мой скрипт InventoryEditor, который управляет функцией RayCast, о которой я упоминал ранее.
Вот код в моем скрипте InventoryEditor, за исключением методов Update и Start, так как они работают так, как задумано.
using UnityEngine;
public class InventoryEditor : MonoBehaviour
{
private bool isOpen = false;
public TMPro.TMP_Text itemIDTM;
public GameObject currentObject;
public GameObject inventoryUI;
new Inventory playerInventory;
public void CurrentObject()
{
RaycastHit itemHit;
Ray itemFinder = new Ray(this.transform.position, transform.TransformDirection(Vector3.forward));
if (Physics.Raycast(itemFinder, out itemHit))
{
if (itemHit.collider.tag == "Item")
{
// Rather than itemHit.collider.name I would prefer if it uses the Identifier of the
//Item ScriptableObject V
itemIDTM.text = "F - Pick up: " + itemHit.collider.name;
if (Input.GetKeyDown(KeyCode.F))
{
/*
I need to Add an Item When F is pressed
Something along the lines of:
playerInventory.AddItem(Item that is hit by RayCast);
*/
}
}
else
{
itemIDTM.text = "";
}
}
}
}
Вот мой объект ScriptableObject, который не вызывает у меня никаких проблем
using UnityEngine;
[CreateAssetMenu]
public class Item : ScriptableObject
{
public string identifier;
public GameObject model;
public int value;
public double weight;
Item(string identifierStr)
{
this.identifier = identifierStr;
}
}
Вот мой класс инвентаризации
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Inventory : List<Item>
{
public List<Item> itemList = new List<Item>();
// Default Constructor
Inventory()
{
}
public override string ToString()
{
string itemListString = " ";
for(int i = 0; i < itemList.Count; i++)
{
itemListString = itemListString += itemList[i].name;
}
return itemListString;
}
public void AddItem(Item itemToAdd)
{
for (int i = 0; i < itemList.Count + 1; i++)
{
if (itemList[i] == null)
{
itemList[i] = itemToAdd;
}
}
}
// Remove Item Not Finished
public void RemoveItem(Item itemToRemove)
{
for (int i = 0; i < itemList.Count; i++)
{
if (itemList[i] == itemToRemove)
{
itemList.Remove(itemToRemove);
}
}
}
}
Единственное решение, которое я могудумать о том, чтобы использовать ScriptableObject.CreateInstance, чтобы заполнить мой игровой мир предметами, которые я хочу добавить в инвентарь, но даже тогда я не уверен, как сделать и то, и другое: ссылаться на эти экземпляры предметов в коде и использовать RayCast, чтобы определить, чтоЭкземпляр предмета поражен.Можно ли создавать экземпляры ScriptableObject в единстве без кода или мне придется заполнять свой мир с помощью кода?
Любая помощь будет принята с благодарностью. Я уже давно борюсь с этим.