【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

2024-06-29 1074阅读

最终效果

【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

文章目录

  • 最终效果
  • 前言
  • 素材下载
  • 图片配置
  • 获取格子坐标
  • 动态控制背包大小
  • 添加物品
  • 移动物品
  • 物品跟随鼠标
  • 创建物品的容器,定义不同物品
  • 修改物品尺寸
  • 修复物品放置位置问题
  • 按物品尺寸占用对应大小的格子
  • 判断物品是否超出边界范围
  • 物品放置重叠,交换物品
  • 放置加入点偏移量
  • 突出显示我们选中的物品
  • 优化
  • 多个背包
  • 自动入库物品
  • 旋转物品
  • 修改旋转高亮背景和占位也跟着旋转
  • 选中拖拽物品排序问题
  • 最终效果
  • 源码
  • 完结

    前言

    在这一集中我将使用Unity制作基于瓦片的网格库存系统。 就像在《逃离塔科夫》、《暗黑破坏神》或《流放之路》等游戏中一样。

    素材下载

    https://assetstore.unity.com/packages/2d/gui/icons/gui-parts-159068

    图片配置

    配置图片为重复

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    不懂UI画布适配查看:【Unity小技巧】最简单的UI设置适配方案

    修改UI画布适配

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    新增UI图片,类型改为平铺,默认图片是256的,太大了,所以我们选择缩小4倍,每单位像素为4,同时注意修改轴心在左上角

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    获取格子坐标

    新增ItemGrid代码

    public class ItemGrid : MonoBehaviour
    {
        // 定义每个格子的宽度和高度
        const float tileSizeWidth = 256 / 4;
        const float tileSizeHeight = 256 / 4;
        // 计算在格子中的位置
        Vector2 positionOnTheGrid = new Vector2();
        Vector2Int tileGridPosition = new Vector2Int();
        RectTransform rectTransform;
        Canvas canvas;
        private void Start()
        {
            rectTransform = GetComponent();
            canvas = FindObjectOfType();
        }
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                // 获取当前鼠标位置在网格中的格子坐标,并打印到控制台
                Debug.Log(GetTileGridPosition(Input.mousePosition));
            }
        }
        
        // 根据鼠标位置计算在格子中的位置
        public Vector2Int GetTileGridPosition(Vector2 mousePosition)
        {
            // 计算鼠标位置相对于 RectTransform 的偏移量
            positionOnTheGrid.x = mousePosition.x - rectTransform.position.x;
            positionOnTheGrid.y = rectTransform.position.y - mousePosition.y;
            // 将偏移量转换为网格位置
            // 这里假设 tileSizeWidth 和 tileSizeHeight 是单个瓦片的宽度和高度
            // canvas.scaleFactor 是 Canvas 的缩放因子(通常用于 UI 适配不同分辨率)
            tileGridPosition.x = (int)(positionOnTheGrid.x / tileSizeWidth / canvas.scaleFactor);
            tileGridPosition.y = (int)(positionOnTheGrid.y / tileSizeHeight / canvas.scaleFactor);
            // 返回计算出的网格位置
            return tileGridPosition;
        }
    }
    

    挂载脚本

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    效果,点击格子打印位置

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    动态控制背包大小

    修改ItemGrid

    [SerializeField] int gridSizeWidth = 10;
    [SerializeField] int gridSizeHeight = 10;
    private void Start()
    {
        rectTransform = GetComponent();
        canvas = FindObjectOfType();
        Init(gridSizeWidth, gridSizeHeight);
    }
    void Init(int width, int height){
        Vector2 size = new Vector2(width * tileSizeWidth, height * tileSizeHeight);
        rectTransform.sizeDelta = size;
    }
    

    配置

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    添加物品

    配置物品预制体。修改尺寸和去掉光线投射目标

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    新增Item脚本,挂载在物品上

    public class Item : MonoBehaviour {
        
    }
    

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    动态添加测试物品,修改ItemGrid

    Item[,] itemSlot;//存储物品位置信息
    private void Start()
    {
    	itemSlot= new Item[gridSizeWidth, gridSizeHeight];
        rectTransform = GetComponent();
        canvas = FindObjectOfType();
        Init(gridSizeWidth, gridSizeHeight);
        //动态添加测试物品
        Item item = Instantiate(itemPrefab).GetComponent();
        PlaceItem(item, 0, 0);
        item = Instantiate(itemPrefab).GetComponent();
        PlaceItem(item, 3, 2);
        item = Instantiate(itemPrefab).GetComponent();
        PlaceItem(item, 2, 4);
    }
        
    //按格子坐标添加物品
    public void PlaceItem(Item item, int posX, int posY){
        itemSlot[posX, posY] = item;
        item.transform.SetParent(transform, false);
        Vector2 positon = new Vector2();
        positon.x = posX * tileSizeWidth + tileSizeWidth / 2;
        positon.y = -(posY * tileSizeHeight + tileSizeHeight / 2);
        item.transform.localPosition = positon;
    }
    

    配置

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    运行效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    移动物品

    修改ItemGrid,按格子坐标获取物品

    //按格子坐标获取物品
    public Item PickUpItem(int x, int y){
        Item toReturn = itemSlot[x, y];
        itemSlot[x, y] = null;
        return toReturn;
    }
    

    新增InventoryController,实现物品交互功能

    public class InventoryController : MonoBehaviour
    {
        public ItemGrid selectedItemGrid;//操作的背包
        Item selectedItem;//选中物品
        private void Update()
        {
            if (selectedItemGrid == null) return;
            if (Input.GetMouseButtonDown(0))
            {
                // 获取当前鼠标位置在网格中的格子坐标,并打印到控制台
                Debug.Log(selectedItemGrid.GetTileGridPosition(Input.mousePosition));
                //获取物品
                Vector2Int tileGridPosition = selectedItemGrid.GetTileGridPosition(Input.mousePosition);
                if(selectedItem == null){
                    selectedItem = selectedItemGrid.PickUpItem(tileGridPosition.x, tileGridPosition.y);
                }else{
                    selectedItemGrid.PlaceItem(selectedItem, tileGridPosition.x, tileGridPosition.y);
                    selectedItem = null;
                }
            }
        }
    }
    

    新增GridInteract,动态赋值背包数据

    [RequireComponent(typeof(ItemGrid))]
    public class GridInteract : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
    {
        private InventoryController inventoryController;
        private ItemGrid itemGrid;
        private void Awake()
        {
            inventoryController = FindObjectOfType();
            itemGrid = GetComponent();
        }
        // 鼠标进入触发
        public void OnPointerEnter(PointerEventData eventData)
        {
            inventoryController.selectedItemGrid = itemGrid;
        }
        // 鼠标退出触发
        public void OnPointerExit(PointerEventData eventData)
        {
            inventoryController.selectedItemGrid = null;
        }
    }
    

    挂载

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    物品跟随鼠标

    修改InventoryController

    private void Update()
    {
        //物品跟随鼠标
        if(selectedItem) selectedItem.transform.position = Input.mousePosition;
    	
    	//...
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    创建物品的容器,定义不同物品

    新增ItemData

    [CreateAssetMenu]
    public class ItemData : ScriptableObject
    {
        public int width = 1;
        public int height = 1;
        public Sprite itemIcon;
    }
    

    配置物品

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    修改Item

    public class Item : MonoBehaviour
    {
        public ItemData itemData;
        
        public void Set(ItemData itemData){
            this.itemData = itemData;
            GetComponent().sprite = itemData.itemIcon;
        }
    }
    

    修改InventoryController

    [SerializeField] List items;
    [SerializeField] GameObject itemPrefab;
    Canvas canvas;
    private void Start() {
        canvas = FindObjectOfType();
    }
    private void Update()
    {
        //TODO: 方便测试,动态随机添加物品
        if (Input.GetKeyDown(KeyCode.Q))
        {
            CreateRandomItem();
        }
        //...
    }
    //随机添加物品
    private void CreateRandomItem()
    {
    	if (selectedItem) return;
        Item item = Instantiate(itemPrefab).GetComponent();
        selectedItem = item;
        selectedItem.transform.SetParent(canvas.transform, false);
        int index = UnityEngine.Random.Range(0, items.Count);
        item.Set(items[index]);
    }
    

    配置

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    效果,按Q生成不同物品

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    修改物品尺寸

    修改Item

    public void Set(ItemData itemData){
        this.itemData = itemData;
        GetComponent().sprite = itemData.itemIcon;
        //修改物品尺寸
        Vector2 size = new Vector2();
        size.x = itemData.width * ItemGrid.tileSizeWidth;
        size.y = itemData.height * ItemGrid.tileSizeHeight;
        GetComponent().sizeDelta = size;
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    修复物品放置位置问题

    修改ItemGrid

    //按格子坐标添加物品
    public void PlaceItem(Item item, int posX, int posY){
        itemSlot[posX, posY] = item;
        item.transform.SetParent(transform, false);
        Vector2 positon = new Vector2();
        positon.x = posX * tileSizeWidth + tileSizeWidth * item.itemData.width / 2;
        positon.y = -(posY * tileSizeHeight + tileSizeHeight * item.itemData.height / 2);
        item.transform.localPosition = positon;
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    按物品尺寸占用对应大小的格子

    修改ItemGrid

    //按格子坐标添加物品
    public void PlaceItem(Item item, int posX, int posY)
    {
        item.transform.SetParent(transform, false);
        // 按物品尺寸占用对应大小的格子
        for (int ix = 0; ix  
    

    运行看是否正常

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    判断物品是否超出边界范围

    修改ItemGrid

    //按格子坐标添加物品
    public bool PlaceItem(Item item, int posX, int posY)
    {
        //判断物品是否超出边界
        if (BoundryCheck(posX, posY, item.itemData.width, item.itemData.height) == false) return false;
        
        //...
    	
    	return true;
    }
    //判断物品是否超出边界
    bool BoundryCheck(int posX, int posY, int width, int height)
    {
        if (PositionCheck(posX, posY) == false) return false;
        posX += width - 1;
        posY += height - 1;
        if (PositionCheck(posX, posY) == false) return false;
        return true;
    }
    //判断格子坐标是否超出
    bool PositionCheck(int posX, int posY)
    {
        if (posX = gridSizeWidth || posY >= gridSizeHeight) return false;
        return true;
    }
    

    修改InventoryController

    private void Update()
    {
       //...
       if (Input.GetMouseButtonDown(0))
       {
           Vector2Int tileGridPosition = selectedItemGrid.GetTileGridPosition(Input.mousePosition);
           if (selectedItem == null)
           {
               //选中物品
               selectedItem = selectedItemGrid.PickUpItem(tileGridPosition.x, tileGridPosition.y);
           }
           else
           {
               // 移动物品
               PlaceItem(tileGridPosition);
           } 
       }
    }
        
    //移动物品
    void PlaceItem(Vector2Int tileGridPosition){
        bool complete = selectedItemGrid.PlaceItem(selectedItem, tileGridPosition.x, tileGridPosition.y);
        if(complete) selectedItem = null;
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    物品放置重叠,交换物品

    修改InventoryController

    Item overlapItem;//重叠物品
    //移动物品
    void PlaceItem(Vector2Int tileGridPosition){
        bool complete = selectedItemGrid.PlaceItem(selectedItem, tileGridPosition.x, tileGridPosition.y, ref overlapItem);
        if(complete) {
            selectedItem = null;
            //如果存在重叠物品
            if(overlapItem != null) {
                selectedItem = overlapItem;
                overlapItem = null;
            }
        }
    }
    

    修改ItemGrid

    //按格子坐标添加物品
    public bool PlaceItem(Item item, int posX, int posY, ref Item overlapItem)
    {
        //判断物品是否超出边界
        if (BoundryCheck(posX, posY, item.itemData.width, item.itemData.height) == false) return false;
        //检查指定位置和范围内是否存在重叠物品,有多个重叠物品退出
        if (OverlapCheck(posX, posY, item.itemData.width, item.itemData.height, ref overlapItem) == false) return false;
        if(overlapItem) CleanGridReference(overlapItem);
    	//...
    }
    //检查指定位置和范围内是否存在重叠物品,并overlapItem返回重叠物品,,有多个重叠物品返回false
    private bool OverlapCheck(int posX, int posY, int width, int height, ref Item overlapItem)
    {
        for (int x = 0; x  
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    放置加入点偏移量

    修改InventoryController放置时加入点偏移量,让放置效果更好

    private void Update()
    {
        //TODO: 方便测试,动态随机添加物品
        if (Input.GetKeyDown(KeyCode.Q))
        {
            CreateRandomItem();
        }
        //物品跟随鼠标
        if (selectedItem) selectedItem.transform.position = Input.mousePosition;
        if (selectedItemGrid == null) return;
        if (Input.GetMouseButtonDown(0))
        {
            LeftMouseButtonPress();
        }
    }
    //点击操作
    private void LeftMouseButtonPress()
    {
        Vector2 position = Input.mousePosition;
        if (selectedItem != null)
        {
            position.x -= (selectedItem.itemData.width - 1) * ItemGrid.tileSizeWidth / 2;
            position.y += (selectedItem.itemData.height - 1) * ItemGrid.tileSizeHeight / 2;
        }
        Vector2Int tileGridPosition = selectedItemGrid.GetTileGridPosition(position);
        if (selectedItem == null)
        {
            //选中物品
            selectedItem = selectedItemGrid.PickUpItem(tileGridPosition.x, tileGridPosition.y);
        }
        else
        {
            // 移动物品
            PlaceItem(tileGridPosition);
        }
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    突出显示我们选中的物品

    修改ItemGrid

    //按格子坐标转化为UI坐标位置
    public Vector2 CalculatePositionOnGrid(Item item, int posX, int posY)
    {
        Vector2 position = new Vector2();
        position.x = posX * tileSizeWidth + tileSizeWidth * item.itemData.width / 2;
        position.y = -(posY * tileSizeHeight + tileSizeHeight * item.itemData.height / 2);
        return position;
    }
    //按格子坐标获取物品
    internal Item GetItem(int x, int y)
    {
        return itemSlot[x, y];
    }
    

    新增InventoryHighlight,控制高亮背景显示

    //控制高亮背景显示
    public class InventoryHighlight : MonoBehaviour
    {
        [SerializeField] RectTransform highlighter;
        // 设置高亮框大小
        public void SetSize(Item targetItem)
        {
            Vector2 size = new Vector2();
            size.x = targetItem.itemData.width * ItemGrid.tileSizeWidth;
            size.y = targetItem.itemData.height * ItemGrid.tileSizeHeight;
            highlighter.sizeDelta = size;
        }
        // 设置高亮框位置
        public void SetPosition(ItemGrid targetGrid, Item targetItem)
        {
            Vector2 pos = targetGrid.CalculatePositionOnGrid(targetItem, targetItem.onGridPositionX, targetItem.onGridPositionY);
            highlighter.localPosition = pos;
        }
        //显示隐藏
        public void Show(bool b){
            highlighter.gameObject.SetActive(b);        
        }
        //设置高亮背景父级
        public void SetParent(ItemGrid targetGrid){
            highlighter.SetParent(targetGrid.GetComponent());
        }
        //设置高亮框位置
        public void SetPosition(ItemGrid targetGrid, Item targetItem, int posX, int posY)
        {
            Vector2 pos = targetGrid.CalculatePositionOnGrid(targetItem, posX, posY);
            highlighter.localPosition = pos;
        }
    }
    

    修改InventoryController

    InventoryHighlight inventoryHighlight;
    Item itemToHighlight;//高亮显示物品
    private void Start()
    {
        canvas = FindObjectOfType();
        inventoryHighlight = GetComponent();
    }
    private void Update()
    {
        //TODO: 方便测试,动态随机添加物品
        if (Input.GetKeyDown(KeyCode.Q))
        {
            CreateRandomItem();
        }
        //物品跟随鼠标
        if (selectedItem) selectedItem.transform.position = Input.mousePosition;
        if (selectedItemGrid == null)
        {
            inventoryHighlight.Show(false);
            return;
        }
        if (Input.GetMouseButtonDown(0))
        {
            // 获取当前鼠标位置在网格中的格子坐标,并打印到控制台
            Debug.Log(selectedItemGrid.GetTileGridPosition(Input.mousePosition));
            LeftMouseButtonPress();
        }
        //高亮显示
        HandleHighlight();
    }
    //点击操作,选中物品
    private void LeftMouseButtonPress()
    {
        Vector2Int tileGridPosition = GetTileGridPosition();
        if (selectedItem == null)
        {
            //选中物品
            selectedItem = selectedItemGrid.PickUpItem(tileGridPosition.x, tileGridPosition.y);
        }
        else
        {
            // 移动物品
            PlaceItem(tileGridPosition);
        }
    }
    //鼠标坐标转化为格子坐标
    private Vector2Int GetTileGridPosition()
    {
        Vector2 position = Input.mousePosition;
        if (selectedItem != null)
        {
            position.x -= (selectedItem.itemData.width - 1) * ItemGrid.tileSizeWidth / 2;
            position.y += (selectedItem.itemData.height - 1) * ItemGrid.tileSizeHeight / 2;
        }
        Vector2Int tileGridPosition = selectedItemGrid.GetTileGridPosition(position);
        return tileGridPosition;
    }
    //高亮显示
    private void HandleHighlight()
    {
        Vector2Int positionOnGrid = GetTileGridPosition();
        if (selectedItem == null)
        {
            itemToHighlight = selectedItemGrid.GetItem(positionOnGrid.x, positionOnGrid.y);
            if (itemToHighlight != null)
            {
                inventoryHighlight.Show(true);
                inventoryHighlight.SetSize(itemToHighlight);
                inventoryHighlight.SetParent(selectedItemGrid);
                inventoryHighlight.SetPosition(selectedItemGrid, itemToHighlight);
            }else{
                inventoryHighlight.Show(false);
            }
        }
        else
        {
            inventoryHighlight.Show(selectedItemGrid.BoundryCheck(
                    positionOnGrid.x,
                    positionOnGrid.y,
                    selectedItem.itemData.width,
                    selectedItem.itemData.height)
            );//防止显示跨界
            inventoryHighlight.SetSize(selectedItem);
            inventoryHighlight.SetParent(selectedItemGrid);
            inventoryHighlight.SetPosition(selectedItemGrid, selectedItem, positionOnGrid.x, positionOnGrid.y);
        }
    }
    

    新增高亮背景

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    挂载配置

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    优化

    修改InventoryController,节约不必要的计算

    Vector2Int oldPosition;
    //高亮显示
    private void HandleHighlight()
    {
        Vector2Int positionOnGrid = GetTileGridPosition();
        //节约没必要的计算
        if(oldPosition == positionOnGrid) return;
        oldPosition = positionOnGrid;
        //...
    }
    

    最好为光线投射添加一些填充,Raycast Padding区域

    参考:Unity 显示Raycast Padding区域

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    多个背包

    只要复制背包,修改尺寸即可

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    自动入库物品

    修改ItemGrid

    //按格子坐标添加物品
    public bool PlaceItem(Item item, int posX, int posY, ref Item overlapItem)
    {
        //判断物品是否超出边界
        if (BoundryCheck(posX, posY, item.itemData.width, item.itemData.height) == false) return false;
        //检查指定位置和范围内是否存在重叠物品,有多个重叠物品退出
        if (OverlapCheck(posX, posY, item.itemData.width, item.itemData.height, ref overlapItem) == false) return false;
        if (overlapItem) CleanGridReference(overlapItem);
        PlaceItem(item, posX, posY);
        return true;
    }
    //按格子坐标添加物品
    public void PlaceItem(Item item, int posX, int posY)
    {
        item.transform.SetParent(transform, false);
        // 按物品尺寸占用对应大小的格子
        for (int ix = 0; ix  
    

    修改InventoryController

    //TODO:方便测试,随机入库物品
    if (Input.GetKeyDown(KeyCode.W))
    {
        InsertRandomItem();
    }
    //随机入库物品
    private void InsertRandomItem()
    {
        if(selectedItemGrid == null) return;
        int index = UnityEngine.Random.Range(0, items.Count);
        // 在网格中找到适合放置物品的位置
        Vector2Int? posOnGrid = selectedItemGrid.FindSpaceForObject(items[index]);
        if (posOnGrid == null) return;
        
        Item item = Instantiate(itemPrefab).GetComponent();
        item.transform.SetParent(canvas.transform, false);
        item.Set(items[index]);
        
        // 将物品放置到网格中的指定位置
        selectedItemGrid.PlaceItem(item, posOnGrid.Value.x, posOnGrid.Value.y);
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    旋转物品

    修改Item

    public bool rotated = false;
    //旋转物品
    public void Rotate()
    {
        rotated = !rotated;
        transform.rotation = Quaternion.Euler(0, 0, rotated == true ? 90f : 0f);
    }
    

    修改InventoryController

    //旋转物品
    if (Input.GetKeyDown(KeyCode.R))
    {
        RotateItem();
    }
    //旋转物品
    void RotateItem(){
        if (selectedItem == null) return;
        selectedItem.Rotate();
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    修改旋转高亮背景和占位也跟着旋转

    修改Item

    public int WIDTH{
        get{
            if(rotated == false){
                return itemData.width;
            }
            return itemData.height;
        }
    }
    public int HEIGHT{
        get{
            if(rotated == false){
                return itemData.height;
            }
            return itemData.width;
        }
    }
    

    然后修改InventoryController、ItemGrid和InventoryHighlight把

    item.itemData.width改为 item.WIDTH

    item.itemData.height改为item.HEIGHT

    给大家提供一个技巧,可以先修改ItemData宽高注释,这时代码会报错,对应修改位置即可,然后再还原回去

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    选中拖拽物品排序问题

    修改InventoryController,大概就是添加selectedItem.transform.SetAsLastSibling();保证选中对象排最后,及排序最靠前

    //点击操作,选中物品
    private void LeftMouseButtonPress()
    {
        Vector2Int tileGridPosition = GetTileGridPosition();
        if (selectedItem == null)
        {
            //选中物品
            selectedItem = selectedItemGrid.PickUpItem(tileGridPosition.x, tileGridPosition.y);
            selectedItem.transform.SetAsLastSibling();
        }
        else
        {
            // 移动物品
            PlaceItem(tileGridPosition);
        }
    }
        
    //移动物品
    void PlaceItem(Vector2Int tileGridPosition)
    {
        bool complete = selectedItemGrid.PlaceItem(selectedItem, tileGridPosition.x, tileGridPosition.y, ref overlapItem);
        if (complete)
        {
            selectedItem = null;
            //如果存在重叠物品
            if (overlapItem != null)
            {
                selectedItem = overlapItem;
                overlapItem = null;
                selectedItem.transform.SetAsLastSibling();
            }
        }
    }
    //随机添加物品
    private void CreateRandomItem()
    {
         if (selectedItem) return; 
        Item item = Instantiate(itemPrefab).GetComponent();
        selectedItem = item;
        selectedItem.transform.SetParent(canvas.transform, false);
        selectedItem.transform.SetAsLastSibling();
        int index = UnityEngine.Random.Range(0, items.Count);
        item.Set(items[index]);
    }
    

    效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    最终效果

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

    源码

    整理好了我会放上来

    完结

    赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

    好了,我是向宇,https://xiangyu.blog.csdn.net

    一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

    【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]