using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
/// <summary>
/// 鼠标拖动背包
/// </summary>
public class DragMe : MonoBehaviour, IBeginDragHandler, IDragHandler
{
private Vector3 dragOffset;
public void OnBeginDrag(PointerEventData eventData)
{
Vector3 worldPos;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, eventData.position, null, out worldPos))
{
dragOffset = new Vector3(transform.position.x - worldPos.x, transform.position.y - worldPos.y, 0f);
transform.position = worldPos + dragOffset;
}
}
public void OnDrag(PointerEventData eventData)
{
Vector3 worldPos;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, eventData.position, null, out worldPos))
{
transform.position = worldPos + dragOffset;
}
}
}
这个类主要是实现了鼠标拖动背包移动的功能,在这里面要注意为什么需要有一个偏移位置,当你没加上偏移位置时,鼠标点击背包时,会发现不管点击背包什么地方,鼠标会和背包中心对齐。这就是中心点的作用了,所以为了解决这个问题需要加上这个偏移位置。这个类拖到Backpack上面。
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class DropController : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
private Color hightLightColor;
private Color hideColor;
private Image image;
private void Start()
{
hightLightColor = new Color(1f, 1f, 1f, 0.2f);
hideColor = new Color(1f, 1f, 1f, 0f);
image = GetComponent<Image>();
}
public void OnDrop(PointerEventData eventData)
{
GameObject item = eventData.pointerDrag;
item.GetComponent<DragController>().PutItem(transform as RectTransform);
HideColor();
}
public void OnPointerEnter(PointerEventData eventData)
{
if (eventData.dragging)
{
image.color = hightLightColor;
}
}
public void OnPointerExit(PointerEventData eventData)
{
if (eventData.dragging)
{
HideColor();
}
}
public void HideColor()
{
image.color = hideColor;
}
}
这个类拖到格子ItemSlot上面。
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
/// <summary>
/// 物品抓取控制器,实现用鼠标拖动物品功能。
/// </summary>
public class DragController : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler
{
public RectTransform canvas;
// 储存物品最放的最近一个物品栏
public RectTransform lastSlot;
// 这个参数用来调整鼠标点击时,鼠标坐标与物品坐标的偏移量
private Vector3 dragOffset;
private CanvasGroup canvasGroup;
private void Start()
{
lastSlot = transform.parent as RectTransform;
canvasGroup = GetComponent<CanvasGroup>();
}
public void OnBeginDrag(PointerEventData eventData)
{
transform.SetParent(canvas);
canvasGroup.blocksRaycasts = false;
Vector3 worldPos;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(canvas, eventData.position, null, out worldPos))
{
dragOffset = new Vector3(transform.position.x - worldPos.x, transform.position.y - worldPos.y, 0f);
transform.position = worldPos + dragOffset;
}
}
public void OnDrag(PointerEventData eventData)
{
Vector3 worldPos;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(canvas, eventData.position, null, out worldPos))
{
transform.position = worldPos + dragOffset;
}
}
public void OnEndDrag(PointerEventData eventData)
{
// 没有对齐格子时,返回原来的背包格子
if (eventData.pointerEnter == null || eventData.pointerEnter.tag != "Slot")
{
PutItem(lastSlot);
}
}
// 将物品放入一个物品栏内
public void PutItem(RectTransform slot)
{
lastSlot = slot;
transform.SetParent(slot);
transform.localPosition = Vector3.zero;
canvasGroup.blocksRaycasts = true;
}
// 当有其他物品想要放在自己这格时,双方交换一下位置
public void OnDrop(PointerEventData eventData)
{
// 先让物品栏高亮效果消失
lastSlot.GetComponent<DropController>().HideColor();
var dc = eventData.pointerDrag.GetComponent<DragController>();
var tempSlot = dc.lastSlot;
dc.PutItem(lastSlot);
PutItem(tempSlot);
}
}
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Tooltips : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public RectTransform canvas; // Canvas 引用
public GameObject itemInfoPanel; // 物品信息面板
public Vector2 offset; // Tooltips 面板偏移量
private static float hoverTimer = 1.0f; // 鼠标悬停时间
private static GameObject tooltips = null; // 属性面板的唯一引用
private float timer = 0f;
private bool pointEntered = false;
private ItemInfo info;
void Start()
{
info.name = "火焰弓";
info.type = "弓箭";
info.prop = "攻击";
info.value = 5;
}
void Update()
{
if (pointEntered && timer <= hoverTimer)
{
timer += Time.deltaTime;
if (timer > hoverTimer)
{
PopupToolTips();
}
}
}
public void OnPointerEnter(PointerEventData eventData)
{
pointEntered = true;
if (eventData.dragging)
{
if (tooltips != null)
{
tooltips.SetActive(false);
}
}
}
public void OnPointerExit(PointerEventData eventData)
{
pointEntered = false;
timer = 0f;
if (tooltips != null)
{
tooltips.SetActive(false);
}
}
public void PopupToolTips()
{
Vector3 initPos = new Vector3(transform.position.x + offset.x, transform.position.y + offset.y, transform.position.z);
if (tooltips == null)
{
tooltips = Instantiate(itemInfoPanel, initPos, Quaternion.identity);
tooltips.transform.SetParent(canvas);
}
tooltips.transform.position = initPos;
tooltips.GetComponent<ItemInfoPanel>().SetInfoPanel(info);
tooltips.SetActive(true);
}
}
这两个类托到物品上面。
using UnityEngine;
using UnityEngine.UI;
public class ItemInfoPanel : MonoBehaviour
{
public Font font;
public void SetInfoPanel(ItemInfo info)
{
var childs = GetComponentsInChildren<Text>(true);
if (childs.Length > 0)
{
foreach (var child in childs)
{
Destroy(child.gameObject);
}
}
AddText("ItemName", string.Format("<color=cyan><b>{0}</b></color>", info.name));
AddText("ItemType", string.Format("物品类型:{0}", info.type));
AddText("ItemPro", string.Format("{0}: +{1}",info.prop,info.value));
}
private void AddText(string objectName, string text)
{
var obj = new GameObject(objectName);
obj.transform.SetParent(transform);
var typeText = obj.AddComponent(typeof(Text)) as Text;
typeText.font = font;
typeText.text = text;
}
}
这个类拖到信息提示面板上面。
public struct ItemInfo
{
public string name;
public string type;
public string prop;
public int value;
}
这是一个信息结构体。
到这里背包系统就结束了。