《骑马与砍杀》背包系统实现

本文详细介绍了Unity中ItemManager脚本的功能,包括背包格子生成、物品加载、拖拽交互逻辑,以及BaseItem脚本对物品拖动行为的处理,确保装备正确放置和交换。
摘要由CSDN通过智能技术生成

一、 效果展示

二、 源代码

1,ItemManager.cs

​​//逻辑简介:该脚本作用是生成背包格子和加载背包物品,获得被拖拽物品和目标物品
//配置:1,需要Scroll View来存放背包物品。
//2,将要作为模板的物品名字更改为EquipSlotTemplate。

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ItemManager : MonoBehaviour
{
    [SerializeField] private GameObject currentObject;
    GameObject EquipSlotTemplate;
    public static ItemManager instance;
    Transform content;
    public GameObject nowItem;
    public GameObject toItem;
   
    public List<Item> itemsList = new List<Item>();
    //public Dictionary<string, Item> itemsDic = new Dictionary<string, Item>();
    public Dictionary<int,GameObject> grid=new Dictionary<int,GameObject>();
    AmourTable amourTable;
    WeaponTable weaponTable;
    private void Awake()
    {
        amourTable = Resources.Load<AmourTable>("TableData/AmourTable");
        weaponTable = Resources.Load<WeaponTable>("TableData/WeaponTable");

        AddItem(amourTable.DataList[0]);//添加装备
        AddItem(amourTable.DataList[1]);
        AddItem(amourTable.DataList[2]);
        AddItem(amourTable.DataList[3]);
        AddItem(amourTable.DataList[0]);
        AddItem(amourTable.DataList[0]);
        AddItem(amourTable.DataList[0]);

        AddItem(weaponTable.DataList[0]);

        content = GameObject.Find("Item_Content").transform;
        EquipSlotTemplate = GameObject.Find("EquipSlotTemplate");
         
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }
    private void Start()
    {
        int rowCount = 0;
        int columnCount = 0;
        float xOffset = 173f;
        float yOffset = -127f;
        //生成格子
        for (int i = 0; i < 20; i++)
        {
            GameObject equipSlot = Instantiate(EquipSlotTemplate);
            equipSlot.transform.SetParent(content, false);

            RectTransform rectTransform = equipSlot.GetComponent<RectTransform>();
            rectTransform.anchoredPosition = new Vector2(columnCount * xOffset-180f, rowCount * yOffset+82f);

            columnCount++;
            if (columnCount >= 3)
            {
                columnCount = 0;
                rowCount++;
            }
            if (equipSlot.GetComponent<BaseItem>() == null)
            {
                equipSlot.AddComponent<BaseItem>();

            }
            grid.Add(i, equipSlot);
        }

        UpdateItem();

    }
      private void AddItem(Item item)
    {
        itemsList.Add(item);
    }
    int index = 0;
    public void UpdateItem()
    { 
        //遍历背包物品字典,将背包物品以此赋给格子。
        foreach (var item in itemsList)
        {
            grid[index].GetComponent<Image>().sprite = item.sprite;
            grid[index].GetComponent<BaseItem>().item = item;

            index++;
            if (index >= grid.Count)
            {
                break;
            }
        }
    }
 
}

2,BaseItem.cs

//逻辑简介:拖拽物品时,记录被拖拽物品的初始父物体,被拖拽物品先作为canvas的子物体,拖拽成功后,让被拖拽物品的父物体为目标物体的父物体,目标物体的父物体成为被拖拽物品的的父物体。然后再交换位置。
//配置:1,把Canvas的名称改为StaticCanvas,若不更改的话,需要修改代码canvas = GameObject.Find("StaticCanvas").GetComponent<Canvas>();
//2,所有装备槽有一个父物体。名字为“EquipSlots”。每个装备槽根据类型也要改名为“Head_Slot”等等。背包槽的父物体也要改名为“Item_Content”。
//3,该脚本通过ItemManager挂载到每个物品上。

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class BaseItem :MonoBehaviour,IPointerEnterHandler, IPointerExitHandler, IDragHandler, IBeginDragHandler, IEndDragHandler
{
    [SerializeField] private GameObject currentObject;
     RectTransform rectTransform;
     Canvas canvas;
     Transform canvasTranform; // 作为临时父级容器,用于装载和移除拖动的图像
    Transform currentParentTrans;
    [SerializeField]  Transform itemParentTrans; // 作为临时父级容器,用于装载和移除拖动的图像
     Image image;
    public bool hasEquipSlot;
    Vector2 currentRectTrans;
    
   [SerializeField] public Item item;
    private void Awake() {
        canvas = GameObject.Find("StaticCanvas").GetComponent<Canvas>();
        canvasTranform = GameObject.Find("StaticCanvas").transform;
        rectTransform = GetComponent<RectTransform>();
        image = GetComponent<Image>();

        if (item == null)
        {
            item = new Item();
        }
        
    }
   
    private void Start() {
        if (transform.name == "Head_Slot")//给装备槽 加type
        {
            item.type = "头盔";
        }
        else if (transform.name == "Clothe_Slot")
        {
            item.type = "衣服";
        }
        else if (transform.name == "Wrist_Slot")
        {
            item.type = "手腕";
        }
        else if (transform.name == "Shoes_Slot")
        {
            item.type = "鞋子";
        }
        else if (transform.name == "Horse_Slot")
        {
            item.type = "马匹";
        }
        else if (transform.name == "Wepon_Slot")
        { 
            item.type = "武器";
        }
        currentParentTrans = transform.parent;
    }
    public void OnPointerEnter(PointerEventData eventData)
    {
        currentObject = eventData.pointerEnter;
        ItemManager.instance.toItem = gameObject;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        ItemManager.instance.toItem = null;
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
         if (item.name == null)
        {
            return;
        }
        currentRectTrans = rectTransform.anchoredPosition;
        currentParentTrans = transform.parent;

        ItemManager.instance.nowItem = gameObject;
        ItemManager.instance.toItem = null;
        
        itemParentTrans = currentObject.transform.parent; //记录当前物体的父物体位置
        currentObject.transform.SetParent(canvasTranform); //将当前物体移动到临时父级容器
    }


    public void OnDrag(PointerEventData eventData)
    {
        if (item.name == null)
        {
            return;
        }
        transform.GetComponent<Button>().interactable = false;
        image.raycastTarget = false;
        // 根据鼠标的移动来调整物体的位置
        rectTransform.anchoredPosition += eventData.delta / canvas.scaleFactor;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
       if (item.name == null)
        {
            return;
        }
        Debug.Log(item.sprite);
        if (ItemManager.instance.toItem == null) //物品栏装备没有拖动到 装备栏和物品栏 即toItem为null 
        {
            currentObject.transform.SetParent(itemParentTrans);
            // 将当前物体的位置重置为原始位置
            rectTransform.anchoredPosition = currentRectTrans;
        }
        else if (ItemManager.instance.toItem.transform.parent.name == "EquipSlots"&&currentParentTrans.name=="Item_Content") //物品栏装备拖动到到了装备槽上
        {
            //type判断
            if (ItemManager.instance.nowItem.GetComponent<BaseItem>().item.type == ItemManager.instance.toItem.GetComponent<BaseItem>().item.type)
            {
                //父类交换
                ItemManager.instance.nowItem.transform.SetParent(ItemManager.instance.toItem.transform.parent, false);//把这个物体作为装备槽父物体的子物体。
                ItemManager.instance.toItem.transform.SetParent(currentParentTrans, false);

                //位置交换
                Vector2 temp = ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition;//获得装备槽本地坐标
                ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition = currentRectTrans;
                ItemManager.instance.nowItem.GetComponent<RectTransform>().anchoredPosition = temp;//把装备槽本地坐标赋值给该物体。
            }
            else 
            {
                currentObject.transform.SetParent(itemParentTrans);
                rectTransform.anchoredPosition = currentRectTrans;
             }
        }
        else if (currentParentTrans.name=="EquipSlots"&&ItemManager.instance.toItem.transform.parent.name=="Item_Content")//装备栏移动到物品栏 
        {
            //判断type是否相同 相同交换位置 或者 不同(装备和格子)也交换位置。
            if ((ItemManager.instance.nowItem.GetComponent<BaseItem>().item.type == ItemManager.instance.toItem.GetComponent<BaseItem>().item.type) || ItemManager.instance.toItem.GetComponent<BaseItem>().item.name == null)
            {
                //父类交换
                ItemManager.instance.nowItem.transform.SetParent(ItemManager.instance.toItem.transform.parent, false);
                ItemManager.instance.toItem.transform.SetParent(currentParentTrans, false);

                //位置交换
                Vector2 temp = currentRectTrans;
                ItemManager.instance.nowItem.GetComponent<RectTransform>().anchoredPosition = ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition;
                ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition = temp;
                ItemManager.instance.nowItem.GetComponent<BaseItem>().item.type = ItemManager.instance.toItem.GetComponent<BaseItem>().item.type;
            }
            else
            { 
                currentObject.transform.SetParent(itemParentTrans);
                rectTransform.anchoredPosition = currentRectTrans;
            }
               
                 
        }
        //物品栏物品相互更换位置
        else if (ItemManager.instance.toItem.transform.parent.name == "Item_Content" && currentParentTrans.name == "Item_Content")//
        {
            //父类交换
            ItemManager.instance.toItem.transform.SetParent(currentParentTrans);
            ItemManager.instance.nowItem.transform.SetParent(currentParentTrans);

            //位置交换
            Vector2 temp = currentRectTrans;
            ItemManager.instance.nowItem.GetComponent<RectTransform>().anchoredPosition = ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition;
            ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition = temp;
        }
        //装备栏之间交换位置
        else if (ItemManager.instance.toItem.transform.parent.name == "EquipSlots" && currentParentTrans.name == "EquipSlots")
        {
            if (ItemManager.instance.nowItem.GetComponent<BaseItem>().item.type == ItemManager.instance.toItem.GetComponent<BaseItem>().item.type)
            {
                //父类交换
                ItemManager.instance.toItem.transform.SetParent(currentParentTrans);
                ItemManager.instance.nowItem.transform.SetParent(currentParentTrans);
                
                //位置交换
                Vector2 temp = currentRectTrans;//获得nowItem本地坐标
                ItemManager.instance.nowItem.GetComponent<RectTransform>().anchoredPosition = ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition;
                ItemManager.instance.toItem.GetComponent<RectTransform>().anchoredPosition = temp;
                
                
            }
               else 
            {
                currentObject.transform.SetParent(itemParentTrans);
                rectTransform.anchoredPosition = currentRectTrans;
            }
        }
        // 恢复鼠标点击
        transform.GetComponent<Button>().interactable = true;
        image.raycastTarget = true;
        

        ItemManager.instance.nowItem = null;
        ItemManager.instance.toItem = null;
    }
    
}
public class Item
{
    public int id;
    public string name;
    public Sprite sprite;
    public int price;
    public string type;
}

3,加载资源

using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Data/AmourTable", fileName = "AmourTable")]

public class AmourTable : ScriptableObject
{
  public List<AmourTableItem> DataList = new List<AmourTableItem>();
  public Dictionary<string, AmourTableItem> WeaponDataList = new Dictionary<string, AmourTableItem>();
}
[System.Serializable]
  public class AmourTableItem:Item
{
    public int weight;

    public int defense;

}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[CreateAssetMenu(menuName = "Data/ItemTable", fileName = "ItemTable")]

public class ItemTable : ScriptableObject
{
  public List<ItemTableItem> DataList = new List<ItemTableItem>();
  public Dictionary<string, ItemTableItem> ItemDataList = new Dictionary<string, ItemTableItem>();
}
[System.Serializable]
  public class ItemTableItem:Item
{
    public int Price;
    public int weight;
   
}

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值