IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity2021 Inventory(背包)系统学习记录 -> 正文阅读

[游戏开发]Unity2021 Inventory(背包)系统学习记录

Unity2021 Inventory(背包)系统学习记录

最近学习了Unity背包系统设计的基本设计。学习资料主要参考了B站up主:M_Studio的教学视频。学习完后,在Assets Store上重新下载了一套GUI对学习到的知识进行了一次复盘。现在,对复盘的过程进行一次记录。这个背包系统主要实现了基本的背包功能,Player(玩家)在场景中拾取得到物品,然后物品能够在背包上出现,背包中的物品也能够进行移动以及交换位置。

? 使用的资源都是在Asset Store上下载得到的免费资源,本次使用的UI主要是GUI_Parts、Simple Fantasy GUI、Tiny RPG Forest。

1. 设置UI

  • 在场景中按照以下父子关系的顺序,创建UI。

在这里插入图片描述

  • 然后,对UI组件对象进行重新命名。

在这里插入图片描述

  • 把Slot设置为预制体,Slot表示一个装备栏,装备栏里有对应的游戏物品,这个装备栏显示的是物品的图片和物品的数量。

  • 设置好Slot预制体后,可以在游戏场景中删除Slot的UI对象。

在这里插入图片描述

  • UI的图片可以按照自己的喜好设置,这里需要注意的是Grid对象需要添加一个Grid Layout Group组件,使Grid做成网格布局。

在这里插入图片描述

  • 通过上述的UI组件设置,其在场景中生成的效果如下图所示。

在这里插入图片描述

2.设置ScriptableObject

ScriptableObject可以把数据存储在资源文件中,当退出运行时也一样会保持修改。这里把物品和背包设置成ScriptableObject对象。

  • 新建一个C#脚本Item.cs,用于创建物体的ScriptableObject对象。

    using UnityEngine;
    
    [CreateAssetMenu(fileName = "New Item", menuName = "Inventory/New Item")]//右键菜单快速创建
    public class Item : ScriptableObject
    {
        public string itemName;//设置物品的名称
        public Sprite itemImage;//设置物品的图片
        public int itemHeld;//设置物品的数量
        [TextArea]
        public string itemInfo;//设置物品的描述
    
        public bool equip;//设置物品可否装备
    }
    

在这里插入图片描述

  • 新建一个C#脚本Inventory.cs,用于创建背包的ScriptableObject对象。
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Inventory", menuName = "Inventory/New Inventory")]
public class Inventory : ScriptableObject
{
    public List<Item> itemList = new List<Item>();//设置背包里面物品的列表
}

在这里插入图片描述

3.在背包UI对象添加一个InventoryManger.cs脚本,用于控制物品栏里面的物品显示。

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

public class InventoryManger : MonoBehaviour
{
   private static InventoryManger instance;

   public Inventory myBag; // 获取背包的信息
   public GameObject slotGrid;//获取Grid网格对象
   //public Slot SlotPrefab;
   public GameObject emptySlot;//slot预制体
   public Text itemInformation;//物品描述
   public List<GameObject> slots = new List<GameObject>();//物品栏中的物品对象
   void Awake()//单例模式,保证只有一个实例
   {
      if (instance!=null)
      {
         Destroy(this);
      }

      instance = this;
   }

   private void OnEnable()
   {
      RefreshItem();//每次启动程序时,刷新背包里的物品
      instance.itemInformation.text = "";//物品描述设置为空
   }

   public static void UpdateItemInfo(string itemDes)
   {
      instance.itemInformation.text = itemDes;//设置物品描述信息
   }


   public static void RefreshItem()
   {
       //先删除物品栏中的所有游戏对象,遍历Grid挂载的子对象
      for (int i = 0; i < instance.slotGrid.transform.childCount; i++)
      {
          
         if (instance.slotGrid.transform.childCount==0)//如果Grid没有挂载子对象
         {
            break;
         }
          //每遍历一个就删除一个子对象
         Destroy(instance.slotGrid.transform.GetChild(i).gameObject);
         instance.slots.Clear();
      }
       //重新加载Invetory中的物品对象。
      for (int j = 0; j < instance.myBag.itemList.Count; j++)
      {
           instance.slots.Add(Instantiate(instance.emptySlot));
           instance.slots[j].transform.SetParent(instance.slotGrid.transform, false);
           instance.slots[j].GetComponent<Slot>().slotID = j;
           instance.slots[j].GetComponent<Slot>().SetupSlot(instance.myBag.itemList[j]);
      }
      
   }
   
}
  • 场景中的Bag物体对象,按以下组件设置。

在这里插入图片描述

  • Bag组件中的MoveBag.cs脚本主要时控制背包窗口的拖拽。

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class MoveBag : MonoBehaviour,IDragHandler
    {
        public Canvas canvas;
    
        private RectTransform currentRect;
        // Start is called before the first frame update
        void Awake()
        {
            currentRect = GetComponent<RectTransform>();
        }
    
        public void OnDrag(PointerEventData eventData)
        {
    
            currentRect.anchoredPosition += eventData.delta;
        }
    }
    

4.Slot预制体的设置

  • Slot预制体挂载一个Slot.cs脚本,这个脚本主要时控制物品的图片和物品的数量。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class Slot : MonoBehaviour
    {
        public int slotID;
        public Item SlotItem;
        public Image SlotImage;//物品图片
        public Text slotNum;//物品数量
        public GameObject itemInslot;
        public string slotInfo;
        public void ItemOnClick()
        {
            InventoryManger.UpdateItemInfo(slotInfo);//点击该物品时,物品描述将会更新
        }
    
        public void SetupSlot(Item item)
        {
            if (item==null)//如果物品不存在,物品栏并不会激活
            {
                itemInslot.SetActive(false);
                return;
            }
    
            SlotImage.sprite = item.itemImage;
            slotNum.text = item.itemHeld.ToString();
            slotInfo = item.itemInfo;
        }
    }
    
    
  • Slot预制体中组件的设置如下

在这里插入图片描述

5.物品的拖拽

  • 在Slot预制体中的Item物体中挂载ItemOnDrag.cs组件

    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class ItemOnDrag : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler
    {
        public Transform orignalParent;
        private RectTransform m_RT;
        public Inventory myBag;
        private int currentItemID;
        //开始拖拽
        public void OnBeginDrag(PointerEventData eventData)
        {
            orignalParent = transform.parent;//记录物体原先的位置
            currentItemID = orignalParent.GetComponent<Slot>().slotID;
            transform.SetParent(transform.parent.parent);//把物体从父节点中分离,使其能够在最上层显示
            transform.position = eventData.position;
            GetComponent<CanvasGroup>().blocksRaycasts = false;
        }
    	//拖拽
        public void OnDrag(PointerEventData eventData)
        {
            //transform.position = eventData.position;
            Vector3 pos;
            m_RT = gameObject.GetComponent<RectTransform>();
            RectTransformUtility.ScreenPointToWorldPointInRectangle(m_RT,eventData.position,eventData.enterEventCamera,out pos);
            m_RT.position = pos;
            //Debug.Log(eventData.pointerCurrentRaycast.gameObject.name);
        }
    	//放开拖拽
        public void OnEndDrag(PointerEventData eventData)
        {
            //使用射线来检测物体下方是不是有物品,如果有物品则交换位置
            if (eventData.pointerCurrentRaycast.gameObject.name=="Item Image")
            {
                transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform.parent.parent);
                transform.position = eventData.pointerCurrentRaycast.gameObject.transform.parent.parent.position;
                
                //itemList的物品存储位置改变。
                var temp = myBag.itemList[currentItemID];
                myBag.itemList[currentItemID] =
                    myBag.itemList[eventData.pointerCurrentRaycast.gameObject.GetComponentInParent<Slot>().slotID];
                myBag.itemList[eventData.pointerCurrentRaycast.gameObject.GetComponentInParent<Slot>().slotID] = temp;
                
                eventData.pointerCurrentRaycast.gameObject.transform.parent.position = orignalParent.position;
                eventData.pointerCurrentRaycast.gameObject.transform.parent.SetParent(orignalParent);
                
                GetComponent<CanvasGroup>().blocksRaycasts = true;
                
                return;
            }
            //如果放开位置没有物品,则直接放下。
            transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform);
            transform.position = eventData.pointerCurrentRaycast.gameObject.transform.position;
            myBag.itemList[eventData.pointerCurrentRaycast.gameObject.GetComponentInParent<Slot>().slotID] = myBag.itemList[currentItemID];
            myBag.itemList[currentItemID] = null;
            GetComponent<CanvasGroup>().blocksRaycasts = true;
        }
        
    }
    
  • Item物体的组件设置情况如下。

    在这里插入图片描述

6.Player(玩家)组件的设置

在这里插入图片描述

  • Player上挂载一个PlayerMovement.cs脚本,用于控制Player的移动,以及控制背包的打开。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PlayerMovement : MonoBehaviour
    {
        Rigidbody2D rb;
        Collider2D coll;
        Animator anim;
        public GameObject myBag;
        private bool isOpen;
        public float speed;
        Vector2 movement;
    
        private void Awake()
        {
            rb = GetComponent<Rigidbody2D>();
            coll = GetComponent<Collider2D>();
            anim = GetComponent<Animator>();
        }
    
        private void Update()
        {
            Movement();
            SwitchAnim();
            OpenMyBag();
        }
    
        void Movement()//移动
        {
            movement.x = Input.GetAxisRaw("Horizontal");
            movement.y = Input.GetAxisRaw("Vertical");
            rb.MovePosition(rb.position + movement * speed * Time.deltaTime);
    
        }
    
        void SwitchAnim()//切换动画
        {
            if (movement != Vector2.zero)//保证Horizontal归0时,保留movment的值来切换idle动画的blend tree
            {
                anim.SetFloat("horizontal", movement.x);
                anim.SetFloat("vertical", movement.y);
            }
            anim.SetFloat("speed", movement.magnitude);//magnitude 也可以用 sqrMagnitude 具体可以参考Api 默认返回值永远>=0
        }
    
        void OpenMyBag()
        {
            if (Input.GetKeyDown(KeyCode.O))
            {
                myBag.SetActive(!myBag.activeSelf);
            }
        }
    }
    

7.效果演示

  • 背包初始状态

在这里插入图片描述

  • 物品转移到背包里面

在这里插入图片描述

  • 交换物品

在这里插入图片描述

  • 拖拽物品
    在这里插入图片描述
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-12-16 18:01:25  更:2021-12-16 18:03:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 21:07:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码