项目上传至Github,下面是链接
https://github.com/Kinzca/3D_Base_System
视频部分:b站链接
unity 背包系统
源码部分:
1、PickupItem:
using System;
using System.Collections.Generic;
using C_.Package;
using UnityEngine;
using UnityEngine.UI;
namespace C_.PlayerController
{
public class PickupItem : MonoBehaviour
{
public GameObject packageCanvas;
private readonly Dictionary<string, (int id, string name,string path, int num)> _itemData =
new Dictionary<string, (int id, string name, string path, int num)>
{
{ "Cube", (1, "Cube","Icons/Cube", 1) },
{ "Sphere", (2, "Sphere","Icons/Sphere", 1) }
};
//玩家碰撞管理
private void OnCollisionEnter(Collision other)
{
if (_itemData.ContainsKey(other.gameObject.tag))
{
var data = _itemData[other.gameObject.tag];
AddItem(data.id, data.name, data.path, data.num, SelectFirstEmptySlot());
other.gameObject.SetActive(false);
}
}
private void AddItem(int id, string nam,string path, int num ,int sid)
{
Sprite icon = Resources.Load<Sprite>(path);
InventoryItem item = new InventoryItem(icon, nam,id, num, sid);
C_.EventManager.EventManager.OnPackageEvent(item);
}
//获取第一个空槽位的索引值
private int SelectFirstEmptySlot()
{
for (int i = 0; i < packageCanvas.transform.childCount; i++)
{
Transform child = packageCanvas.transform.GetChild(i);
Image image = child.GetComponent<Image>();
if (image != null && image.sprite == null)
{
return i;
}
}
return -1;
}
}
}
2、InventorySlot
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace C_.Package
{
public class InventorySlot :MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IDragHandler,IEndDragHandler,IPointerClickHandler
{
public Sprite sprite;
public Text mark;
public int index;
public event Action<InventorySlot,PointerEventData> PointerEnterEvent;
public event Action PointerExitEvent;
public event Action<InventorySlot,PointerEventData> OnDragEvent;
public event Action<InventorySlot> EndDragEvent;
public event Action<InventorySlot,PointerEventData> SingleDragEvent;
private void Awake()
{
//初始化组件的一些元素
var image = GetComponent<Image>();
if (image != null)
{
sprite = image.sprite;
}
index = transform.GetSiblingIndex();
}
public void OnPointerEnter(PointerEventData eventData)
{
var image = eventData.pointerEnter.GetComponent<Image>();
if (image.sprite != null)
{
PointerEnterEvent?.Invoke(this,eventData); //触发进入时的事件
}
}
public void OnPointerExit(PointerEventData eventData)
{
var image = eventData.pointerEnter.GetComponent<Image>();
if (image.sprite != null)
{
PointerExitEvent?.Invoke(); //鼠标离开时触发的事件
}
}
public void OnDrag(PointerEventData eventData)
{
var image = eventData.pointerDrag.GetComponent<Image>();
//格子内存在物品才处理拖动逻辑
if (image.sprite != null && eventData.button==PointerEventData.InputButton.Left)
{
OnDragEvent?.Invoke(this, eventData);
}
}
public void OnEndDrag(PointerEventData eventData)
{
//获取结束时鼠标停留的位置
var endSlot = eventData.pointerEnter;
InventorySlot slot = endSlot.GetComponent<InventorySlot>();
EndDragEvent?.Invoke(slot); //结束拖拽时触发,将结束时停留在的slot位置传递给订阅的方法
}
//鼠标右键响应更新
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
SingleDragEvent?.Invoke(this,eventData);
}
}
}
}
3、InventoryItem
using UnityEngine;
namespace C_.Package
{
public class InventoryItem
{
public Sprite ItemIcon;
public int ItemID;
public string ItemName;
public int Number;
public int SlotID;
//构造函数,初始化物品属性
public InventoryItem(Sprite icon, string name,int id, int number, int sid)
{
ItemIcon = icon;
ItemID = id;
ItemName = name;
Number = number;
SlotID = sid;
}
public void AddQuantity(int amount)
{
Number += amount;
}
}
}
4、InventoryManager
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;