背包系统
需要写两个脚本 搭完UI过后Equip和Box 要分别加上脚本,脚本如下:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class HeroEquip : MonoBehaviour,
IBeginDragHandler,IDragHandler,IEndDragHandler
{
[Header("装备类型")]
public EquipType equipType = EquipType.Helmet;
private Image crtImage;
//记录当前的父对象是谁
private Transform parent;
private void Awake()
{
crtImage = GetComponent<Image>();
}
private void Start()
{
//记录原来的父对象
parent = transform.parent;
}
//在开始拖拽时给图片更换父对象
//让图片盖住所有的UI
//可以避免图片被盖住 射线检测不到
public void OnBeginDrag(PointerEventData eventData)
{
//记录原来的父对象
parent = transform.parent;
//把他的根对象(画布)设置为父对象 (设为画布的子对象)
transform.SetParent(transform.root);
//取消射线检测该图片 (穿透效果可以检测达图片后面的)
crtImage.raycastTarget = false;
}
//继承接口IDragHandler 实现拖拽图片的效果
public void OnDrag(PointerEventData eventData)
{
//把鼠标当前坐标的值赋给这张图片
transform.position = Input.mousePosition;
}
public void OnEndDrag(PointerEventData eventData)
{
/*
* 三种情况:
* 标签检测为Box
* 标签检测为Equip
* Other
*/
//标签检测Box
//如果后面是Box
//eventData.pointerEnter.transform.childCount == 0 这个是判断Box比装备图片要大,防止覆盖
if (eventData.pointerEnter.CompareTag("Box") && eventData.pointerEnter.transform.childCount == 0)
{
//格子接收装备
BoxReceive(eventData.pointerEnter.GetComponent<EquipBox>());
}
//标签检测Equip
else if (eventData.pointerEnter.CompareTag("Equip"))
{
//交换
Exchange(eventData.pointerEnter);
}
//其他情况
else
{
//回到原始坐标
BackToOrigin();
}
//恢复射线检测该图片
crtImage.raycastTarget = true;
}
/// <summary>
/// 交换的方法 封装起来了
/// </summary>
/// <param name="buttomObj"></param>
private void Exchange(GameObject buttomObj)
{
//下面的装备
HeroEquip buttomEquip = buttomObj.GetComponent<HeroEquip>();
//获取下面装备的父物体(Box)
EquipBox buttonEquipBox = buttomObj.transform.parent.GetComponent<EquipBox>();
//获取当前格子的父对象
EquipBox topEquipBox = parent.GetComponent<EquipBox>();
/*
//两个装备都在背包里不用检测类型
if (buttonEquipBox.equipType == EquipType.None &&
topEquipBox.equipType == EquipType.None)
{
//交换
//下面的格子接收当前装备
buttonEquipBox.SetEquip(this);
//上面的格子接收下面的装备
topEquipBox.SetEquip(buttomEquip);
}
//两个装备至少有一个在装备栏里,且两个装备类型匹配
else if (buttomEquip.equipType == equipType)
{
//交换
//下面的格子接收当前装备
buttonEquipBox.SetEquip(this);
//上面的格子接收下面的装备
topEquipBox.SetEquip(buttomEquip);
}
//两个装备既不在背包里,两个类型又不匹配
else
{
//回到原始坐标
BackToOrigin();
}
*/
if ((buttonEquipBox.equipType != EquipType.None ||
topEquipBox.equipType != EquipType.None) &&
buttomEquip.equipType != equipType)
{
BackToOrigin();
}
else
{
buttonEquipBox.SetEquip(this);
topEquipBox.SetEquip(buttomEquip);
}
}
/// <summary>
/// 格子接收装备 让检测到的背包box去处理当前装备的位置
/// </summary>
/// <param name="equipBox">拿到格子</param>
private void BoxReceive(EquipBox equipBox)
{
//调用格子的设置方法
equipBox.SetEquip(this);
}
/// <summary>
/// 射线检测如果不合法,图片回归到原始的位置
/// </summary>
public void BackToOrigin()
{
/* 封装
//要回归的内容有:
//(1)设回原来父对象
transform.SetParent(parent);
//(2)位置要放在父对象里面
transform.localPosition = Vector3.zero;
//(3)缩放(看情况)如果变大或变小了缩放要变回去
*/
SetParent(parent);
}
/// <summary>
/// 装备图片放到格子里
/// </summary>
/// <param name="box"></param>
public void SetToBox(Transform box)
{
SetParent(box);
}
/// <summary>
/// 设置新的父对象
/// </summary>
/// <param name="newParent"></param>
private void SetParent(Transform newParent)
{
//设回原来父对象
transform.SetParent(newParent);
//位置要放在父对象里面
transform.localPosition = Vector3.zero;
}
}
using UnityEngine;
public enum EquipType
{
None,//无
Helmet,//帽子
Ring,//戒指
Clothes,//衣服
Weapon,//武器
Shoes//鞋子
}
public class EquipBox : MonoBehaviour
{
[Header("装备栏类型")]
public EquipType equipType = EquipType.None;
/// <summary>
/// 把装备放入当前的格子里
/// </summary>
/// <param name="heroEquip">传入的参数 判断符不符合格子的类型</param>
public void SetEquip(HeroEquip heroEquip)
{
//判断
//(1)没有类型限制 可以接受
//(2)格子的类型限制和装备匹配
if (equipType == EquipType.None ||
equipType == heroEquip.equipType)
{
//设置
heroEquip.SetToBox(transform);
}
else
{
//不符合的回到原始坐标
heroEquip.BackToOrigin();
}
}
}