U3D背包系统
u3d背包系统功能,通过按键在格子中增加物品,通过鼠标拖动可以自由的拖拽物体,鼠标进入物体时候可以显示物品属性;
如图:
目录结构:
基本实现逻辑:
- 在Assets/StreamingAssets(必须使用这个文件名,放在Unity项目中名为StreamingAssets文件夹中的任何文件将会被一字不差地复制到目标机器上的特定文件夹里 MAC/Win: path = = Application.dataPath + “/StreamingAssets”; iOS: path = Application.dataPath + “/Raw”; Android: path = "jar:fil;)中存放着数据配置文件,该数据文件用xml(或者ini)编写记录着背包中的物品的字段和属性,如类型,名字,描述等,在代码中通过Configitem.cs类对该数据配置文件进行读取,并保存在一个字典容器中。之后通过代码加载,值得一提的是,Resources中的资源通过load加载,StreamAssets中的资源通过www加载。
- 通过itemInfo类控制物品属性的显示,即鼠标进入格子的时候出现一个面板显示物品信息,为了显示一个渐渐的效果,通过控制CanvasGroup的alpha值0~1来实现。
- 通过item类控制物品。item脚本加在物品上,item类继承自TriggerEventer事件触发器,这是因为当我们鼠标进入item时需要触发itemInfo的函数,所以需要实现OnPointerEnter方法。在item类中实现了对鼠标操作物品的逻辑,当鼠标拖动物品移动后再点击将物品放下时,需要进行判断:如果当下item中有物品时要进行交换操作;如果当下item为空时,将物品存储在当下item中。具体操作流程:item.cs(onPointerDown时判断鼠标上是否有物品)->如果没有,调用itemMouse.cs的Item属性加载图片,并把图片保存在item的icon中。(在我们平时玩的游戏中,其实通常是通过鼠标松开来实现物品的放下或者交换操作,此时就应该在onPointerUp时候进行判断),鼠标的位置信息是在ui的每一帧都在实时的获取。(还有一种实现方法:通过重写鼠标松开事件,在鼠标松开时,获得当前鼠标下的物品栏,将拖动的物品的父类设置为该物品栏,同时将该物品栏里的子物品的父类设置为拖动的物品之前的父类)
- 在bag.cs下有很多的items,通过PanelRoleBag.cs对所有的item进行操作。
//GameUI.cs,程序入口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameUI : SingletonMono<GameUI> {
private RectTransform rect;
private PanelRoleBag bag;
public bool isPickItem;//鼠标上是否拾取了物品
private ItemMouse itemMouse;//鼠标上的物品
private Vector3 itemMouseOldPos;//保存鼠标上物品的初始位置
public ItemMouse ItemMouse
{
get {
return itemMouse; }
set {
itemMouse = value; }
}
//物品提示框
public bool isShowItemInfo;//是否显示物品信息提示框
private ItemInfo itemInfo;//物品的信息提示
/// <summary>
/// 隐藏鼠标拾取物品
/// </summary>
public void hideMousePickItem()
{
itemMouse.transform.localPosition = itemMouseOldPos;
isPickItem = false;
}
public override void Awake()
{
base.Awake();
//配置数据加载
//print("配置数据调用前");
ConfigItem.init();
//print("配置数据调用后");
bag = transform.Find("PanelRoleBag").GetComponent<PanelRoleBag>();
itemMouse = transform.Find("ItemMouse").GetComponent<ItemMouse>();
itemMouseOldPos = itemMouse.transform.localPosition;
rect = this.GetComponent<RectTransform>();
itemInfo = transform.Find("ItemInfo").GetComponent<ItemInfo>();
}
void Start () {
}
// Update is called once per frame
void Update () {
//更新物品提示框的位置
if (isShowItemInfo)
{
Vector2 point = Vector2.zero;
RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, Input.mousePosition, null, out point);
itemInfo.transform.localPosition = point;
}
//鼠标拾取到物品之后
if (isPickItem)
{
Vector2 point = Vector2.zero;
//该函数是将屏幕坐标转化以第一个参数对象的子节点坐标
//参数一:需要转换的坐标以该对象作为父节点
//参数二:鼠标点
//参数三:参数一对象以哪个摄像机渲染(由于该参数一画布没有相机渲染,故为null)
//参数四:返回一个需要转换的目标点
RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, Input.mousePosition, null, out point);
itemMouse.transform.localPosition = point;
}
//按空格键盘,模拟生成物品
if (Input.GetKeyUp(KeyCode.Space))
{
int randId = Random.Range(0, ConfigItem.ItemCount);//物品ID
ConfigItem data = ConfigItem.Get(randId);//通过物品ID得到物品的数据信息
bag.storeItemToBag(data);//通过数据添加物品
}
}
/// <summary>
/// 显示物品提示信息
/// </summary>
/// <param name="str"></param>
public void showItemInfo(string str = "")
{
isShowItemInfo = true;
itemInfo.show(str);
}
/// <summary>
/// 隐藏物品提示信息
/// </summary>
public void hideItemInfo()
{
isShowItemInfo = false;
itemInfo.hide();
}
}
//PanelRoleBag,对item进行操作的脚本
using System.Collections;
using System