Использование предметов здоровья и баффы добавлены в мой плеер
Я сделал инвентарь с 2-мя пользовательскими интерфейсами, один из которых является инвентарем, а другой похож на панель оборудования с 5 слотами, и то, что я хотел бы сделать, - это когда я оснащаю предмет идентификатором панели оборудования, например значением здоровья на них, чтобы настроить здоровье моего игрока... я совсем новичок во всем этом и действительно мог бы просто использовать некоторую помощь ... вот мой код...
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public delegate void ModifiedEvent(); [System.Serializable] public class ModifiableInt { [SerializeField] private int baseValue; public int BaseValue { get { return baseValue; } set { baseValue = value; UpdateModifiedValue(); } } [SerializeField] private int modifiedValue; public int ModifiedValue { get { return modifiedValue; } private set { modifiedValue = value; } } public List<IModifier> modifiers = new List<IModifier>(); public event ModifiedEvent ValueModified; public ModifiableInt(ModifiedEvent method = null) { modifiedValue = BaseValue; if (method != null) ValueModified += method; } public void RegsiterModEvent(ModifiedEvent method) { ValueModified += method; } public void UnregsiterModEvent(ModifiedEvent method) { ValueModified -= method; } public void UpdateModifiedValue() { var valueToAdd = 0; for (int i = 0; i < modifiers.Count; i++) { modifiers[i].AddValue(ref valueToAdd); } ModifiedValue = baseValue + valueToAdd; if (ValueModified != null) ValueModified.Invoke(); } public void AddModifier(IModifier _modifier) { modifiers.Add(_modifier); UpdateModifiedValue(); } public void RemoveModifier(IModifier _modifier) { modifiers.Remove(_modifier); UpdateModifiedValue(); } } <pre>using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using UnityEditor; using System.Runtime.Serialization; using UnityEngine.EventSystems; public enum InterfaceType { Inventory, Equipment, Chest } [CreateAssetMenu(fileName = " New Inventory", menuName = "Inventory System/Inventory")] public class InventoryObject : ScriptableObject { public string savePath; public ItemDatabaseObject database; public InterfaceType type;//type of inventory we dealing with public Inventory Container; public InventorySlot[] GetSlots { get { return Container.Slots; } } public bool AddItem(Item _item, int _amount) { if (EmptySlotCount < 0) { return false; } InventorySlot slot = FindItemOnInventory(_item); if (!database.ItemObjects[_item.Id].stackable || slot == null) { SetEmptySlot(_item, _amount); return true; } slot.AddAmount(_amount); return true; } public int EmptySlotCount { get { int counter = 0; for (int i = 0; i < GetSlots.Length; i++) { if (GetSlots[i].item.Id <= -1) { counter++; } } return counter; } } public InventorySlot FindItemOnInventory(Item _item) { for (int i = 0; i < GetSlots.Length; i++) { if (GetSlots[i].item.Id == _item.Id) { return GetSlots[i]; } }return null; } public InventorySlot SetEmptySlot(Item _item, int _amount) { for (int i = 0; i < GetSlots.Length; i++) { if (GetSlots[i].item.Id <= 0) { GetSlots[i].UpdateSlot(_item, _amount); return GetSlots[i]; } } //Set up functionality if inv is full return null; } public void SwapItems(InventorySlot item1, InventorySlot item2) { if (item2.CanPlaceInSlot(item1.itemObject) && item1.CanPlaceInSlot(item2.itemObject)) { InventorySlot temp = new InventorySlot(item2.item, item2.amount); item2.UpdateSlot(item1.item, item1.amount); item1.UpdateSlot(temp.item, temp.amount); } } public void RemoveItem(Item _item) { for (int i = 0; i < GetSlots.Length; i++) { if (GetSlots[i].item == _item) { GetSlots[i].UpdateSlot(null, 0); } } } [ContextMenu("Save")]//SAVES INVENTORY public void Save() { //string saveData = JsonUtility.ToJson(this, true); //BinaryFormatter bf = new BinaryFormatter(); //FileStream file = File.Create(string.Concat(Application.persistentDataPath, savePath)); //bf.Serialize(file, saveData); //file.Close(); IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream(string.Concat(Application.persistentDataPath, savePath), FileMode.Create, FileAccess.Write); formatter.Serialize(stream, Container); stream.Close(); } [ContextMenu("Load")]//LOADS INVENTORY public void Load() { if (File.Exists(string.Concat(Application.persistentDataPath, savePath))) { // BinaryFormatter bf = new BinaryFormatter(); //FileStream file = File.Open(string.Concat(Application.persistentDataPath, savePath), FileMode.Open); //JsonUtility.FromJsonOverwrite(bf.Deserialize(file).ToString(), this); //file.Close(); IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream(string.Concat(Application.persistentDataPath, savePath), FileMode.Open, FileAccess.Read); Inventory newContainer = (Inventory)formatter.Deserialize(stream); for (int i = 0; i < GetSlots.Length; i++) { GetSlots[i].UpdateSlot(newContainer.Slots[i].item, newContainer.Slots[i].amount); } stream.Close(); } } [ContextMenu("Clear")] public void Clear() { Container.Clear(); } } [System.Serializable] public class Inventory { public InventorySlot[] Slots = new InventorySlot[24]; public void Clear() { for (int i = 0; i < Slots.Length; i++) { Slots[i].RemoveItem(); } } } public delegate void SlotUpdated(InventorySlot _slot); [System.Serializable] public class InventorySlot { public ItemType[] AllowedItems = new ItemType[0]; [System.NonSerialized]//hidden public UserInterface parent; [System.NonSerialized]//hideen public GameObject slotDisplay; [System.NonSerialized] public SlotUpdated OnAfterUpdate; [System.NonSerialized] public SlotUpdated OnBeforeUpdate; public Item item; public int amount; public itemObject itemObject { get { if (item.Id >= 0) { return parent.inventory.database.ItemObjects[item.Id]; } return null; } } public InventorySlot() { UpdateSlot(new Item(), 0); } public InventorySlot(Item _item, int _amount) { UpdateSlot(_item, _amount); } public void UpdateSlot(Item _item, int _amount) { if (OnBeforeUpdate != null) OnBeforeUpdate.Invoke(this); item = _item; amount = _amount; if (OnAfterUpdate != null) OnAfterUpdate.Invoke(this); } public void RemoveItem() { UpdateSlot(new Item(), 0); } public void AddAmount(int value) { UpdateSlot(item, amount += value); } public bool CanPlaceInSlot(itemObject _itemObject) { if (AllowedItems.Length <= 0 || _itemObject == null || _itemObject.data.Id < 0) { return true; } for (int i = 0; i < AllowedItems.Length; i++) { if (_itemObject.type == AllowedItems[i]) { return true; } } return false; } } using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.UI; using UnityEngine.EventSystems; using UnityEngine.Events; public abstract class UserInterface : MonoBehaviour { public InventoryObject inventory; public Dictionary<GameObject, InventorySlot> slotsOnInterface = new Dictionary<GameObject, InventorySlot>(); //Start is called before the first frame update void Start() { for (int i = 0; i < inventory.GetSlots.Length; i++) { inventory.GetSlots[i].parent = this; inventory.GetSlots[i].OnAfterUpdate += OnSlotUpdate; } CreateSlots(); AddEvent(gameObject, EventTriggerType.PointerEnter, delegate { OnEnterInterface(gameObject); }); AddEvent(gameObject, EventTriggerType.PointerExit, delegate { OnExitInterface(gameObject); }); } private void OnSlotUpdate(InventorySlot _slot) { if (_slot.item.Id >= 0) { _slot.slotDisplay.transform.GetChild(0).GetComponentInChildren<Image>().sprite = _slot.itemObject.uiDisplay; //inventory.database.GetItem[_slot.Value.item.Id].uiDisplay;//UPDATE SLOT TO DISPLAY ITEM _slot.slotDisplay.transform.GetChild(0).GetComponentInChildren<Image>().color = new Color(1, 1, 1, 1); _slot.slotDisplay.GetComponentInChildren<TextMeshProUGUI>().text = _slot.amount == 1 ? "" : _slot.amount.ToString("n0"); } else { _slot.slotDisplay.transform.GetChild(0).GetComponentInChildren<Image>().sprite = null;//UPDATE SLOT TO DISPLAY ITEM _slot.slotDisplay.transform.GetChild(0).GetComponentInChildren<Image>().color = new Color(1, 1, 1, 0); _slot.slotDisplay.GetComponentInChildren<TextMeshProUGUI>().text = ""; } } //Update is called once per frame //void Update() //{ // slotsOnInterface.UpdateSlotDisplay(); //} protected void AddEvent(GameObject obj, EventTriggerType type, UnityAction<BaseEventData> action) { EventTrigger trigger = obj.GetComponent<EventTrigger>(); var eventTrigger = new EventTrigger.Entry(); eventTrigger.eventID = type; eventTrigger.callback.AddListener(action); trigger.triggers.Add(eventTrigger); } public abstract void CreateSlots(); public void OnEnter(GameObject obj) { MouseData.slotHoveredOver = obj; } public void OnExit(GameObject obj) { MouseData.slotHoveredOver = null; } public void OnEnterInterface(GameObject obj) { MouseData.intefaceMouseIsOver = obj.GetComponent<UserInterface>(); } public void OnExitInterface(GameObject obj) { MouseData.slotHoveredOver = null; } public void OnDragStart(GameObject obj) { MouseData.tempItemBeingDragged = CreateTempItem(obj); } public GameObject CreateTempItem(GameObject obj) { GameObject tempItem = null; if (slotsOnInterface[obj].item.Id >= 0)//if item exists were going to : { tempItem = new GameObject(); var rt = tempItem.AddComponent<RectTransform>(); rt.sizeDelta = new Vector2(75, 75); tempItem.transform.SetParent(transform.parent); var img = tempItem.AddComponent<Image>(); img.sprite = slotsOnInterface[obj].itemObject.uiDisplay; img.raycastTarget = false; } return tempItem; } public void OnDragEnd(GameObject obj) { Destroy(MouseData.tempItemBeingDragged); if (MouseData.intefaceMouseIsOver == null) { slotsOnInterface[obj].RemoveItem(); return; } if (MouseData.slotHoveredOver) { InventorySlot mouseHoverSlotData = MouseData.intefaceMouseIsOver.slotsOnInterface[MouseData.slotHoveredOver]; inventory.SwapItems(slotsOnInterface[obj], mouseHoverSlotData); } } public void OnDrag(GameObject obj) { if (MouseData.tempItemBeingDragged != null) { MouseData.tempItemBeingDragged.GetComponent<RectTransform>().position = Input.mousePosition; } } public void UpdateDisplay() { } } public static class MouseData { public static UserInterface intefaceMouseIsOver; public static GameObject tempItemBeingDragged; public static GameObject slotHoveredOver; } public static class ExtensionMethods { public static void UpdateSlotDisplay(this Dictionary<GameObject, InventorySlot> _slotsOnInterface) { foreach (KeyValuePair<GameObject, InventorySlot> _slot in _slotsOnInterface) { if (_slot.Value.item.Id >= 0) { _slot.Key.transform.GetChild(0).GetComponentInChildren<Image>().sprite = _slot.Value.itemObject.uiDisplay; //inventory.database.GetItem[_slot.Value.item.Id].uiDisplay;//UPDATE SLOT TO DISPLAY ITEM _slot.Key.transform.GetChild(0).GetComponentInChildren<Image>().color = new Color(1, 1, 1, 1); _slot.Key.GetComponentInChildren<TextMeshProUGUI>().text = _slot.Value.amount == 1 ? "" : _slot.Value.amount.ToString("n0"); } else { _slot.Key.transform.GetChild(0).GetComponentInChildren<Image>().sprite = null;//UPDATE SLOT TO DISPLAY ITEM _slot.Key.transform.GetChild(0).GetComponentInChildren<Image>().color = new Color(1, 1, 1, 0); _slot.Key.GetComponentInChildren<TextMeshProUGUI>().text = ""; } } } } using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using UnityEngine.EventSystems; public interface IModifier { void AddValue(ref int baseValue); } using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class DynamicInterface : UserInterface { public int Y_START; public int X_START; public int X_SPACE_BETWEEN_ITEM; public int NUMBER_OF_COLUMN; public int Y_SPACE_BETWEEN_ITEMS; public GameObject inventoryPrefab; public override void CreateSlots() { slotsOnInterface = new Dictionary<GameObject, InventorySlot>(); for (int i = 0; i < inventory.GetSlots.Length; i++) { var obj = Instantiate(inventoryPrefab, Vector3.zero, Quaternion.identity, transform); obj.GetComponent<RectTransform>().localPosition = GetPosition(i); AddEvent(obj, EventTriggerType.PointerEnter, delegate { OnEnter(obj); }); AddEvent(obj, EventTriggerType.PointerExit, delegate { OnExit(obj); }); AddEvent(obj, EventTriggerType.BeginDrag, delegate { OnDragStart(obj); }); AddEvent(obj, EventTriggerType.EndDrag, delegate { OnDragEnd(obj); }); AddEvent(obj, EventTriggerType.Drag, delegate { OnDrag(obj); }); inventory.GetSlots[i].slotDisplay = obj; slotsOnInterface.Add(obj, inventory.GetSlots[i]); } } private Vector3 GetPosition(int i) { return new Vector3(X_START + (X_SPACE_BETWEEN_ITEM * (i % NUMBER_OF_COLUMN)), Y_START + (Y_SPACE_BETWEEN_ITEMS * (i / NUMBER_OF_COLUMN)), 0f); } } using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class StaticInterface : UserInterface { public GameObject[] slots; public override void CreateSlots() { slotsOnInterface = new Dictionary<GameObject, InventorySlot>(); for (int i = 0; i < inventory.GetSlots.Length; i++) { var obj = slots[i]; AddEvent(obj, EventTriggerType.PointerEnter, delegate { OnEnter(obj); }); AddEvent(obj, EventTriggerType.PointerExit, delegate { OnExit(obj); }); AddEvent(obj, EventTriggerType.BeginDrag, delegate { OnDragStart(obj); }); AddEvent(obj, EventTriggerType.EndDrag, delegate { OnDragEnd(obj); }); AddEvent(obj, EventTriggerType.Drag, delegate { OnDrag(obj); }); inventory.GetSlots[i].slotDisplay = obj; slotsOnInterface.Add(obj, inventory.GetSlots[i]); } } } using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { public InventoryObject inventory; public InventoryObject equipment; public Attribute[] attributes; private Transform _potion; private Transform _food; private Transform _sword; private Transform _shield; private void Start() { for (int i = 0; i < attributes.Length; i++) { attributes[i].SetParent(this); } for (int i = 0; i < equipment.GetSlots.Length; i++) { equipment.GetSlots[i].OnBeforeUpdate += OnRemoveItem; equipment.GetSlots[i].OnAfterUpdate += OnAddItem; } } public void OnRemoveItem(InventorySlot _slot)//unequip { if (_slot.itemObject == null) return; switch (_slot.parent.inventory.type) { case InterfaceType.Inventory: break; case InterfaceType.Equipment: print(message: string.Concat("Removed ", _slot.itemObject, " on ", _slot.parent.inventory.type, ", Allowed Items: ", string.Join(", ", _slot.AllowedItems))); for (int i = 0; i < _slot.item.buffs.Length; i++) { for (int j = 0; j < attributes.Length; j++) { if (attributes[j].type == _slot.item.buffs[i].attribute) attributes[j].value.RemoveModifier(_slot.item.buffs[i]);//removes modifier } } break; case InterfaceType.Chest: break; default: break; } } public void OnAddItem(InventorySlot _slot)//equip { if (_slot.itemObject == null) return; switch (_slot.parent.inventory.type) { case InterfaceType.Inventory: break; case InterfaceType.Equipment: print(message: string.Concat("Placed ", _slot.itemObject, " on ", _slot.parent.inventory.type, ", Allowed Items: ", string.Join(", ", _slot.AllowedItems))); for (int i = 0; i < _slot.item.buffs.Length; i++) { for (int j = 0; j < attributes.Length; j++) { if (attributes[j].type == _slot.item.buffs[i].attribute)//if attribute on item is same as on char attributes[j].value.AddModifier(_slot.item.buffs[i]);//take attr on char take value add modifier } } //if (_slot.itemObject.characterDisplay != null) //{ // switch (_slot.AllowedItems[0]) // { // case ItemType.Food: // break; // default: // break; // } //} break; case InterfaceType.Chest: break; default: break; } } public void OnTriggerEnter2D(Collider2D other) { var groundItem = other.GetComponent<GroundItem>(); if (groundItem) { Item _item = new Item(groundItem.item); if (inventory.AddItem(_item, 1)) { Destroy(other.gameObject); } } } private void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { inventory.Save(); equipment.Save(); } if (Input.GetKeyDown(KeyCode.Return)) { inventory.Load(); equipment.Load(); } } public void AttributeModified(Attribute attribute) { Debug.Log(string.Concat(attribute.type, "was updated! value is now ", attribute.value.ModifiedValue)); } private void OnApplicationQuit() { inventory.Clear(); equipment.Clear(); } } [System.Serializable] public class Attribute { [System.NonSerialized] public Player parent; public Attributes type; public ModifiableInt value; public void SetParent(Player _parent)//parent will know everytime attribute is updated { parent = _parent; value = new ModifiableInt(AttributeModified); } public void AttributeModified() { parent.AttributeModified(this); } }
Извините, если это немного длинновато, я просто добавил весь код, который, как мне кажется, мне нужно было опубликовать.
Что я уже пробовал:
я перепробовал почти все, что искал и смотрел учебники.