背包系统(二)之美_知识分享

背包系统(二)之美_知识分享_02

 

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;
}

这是一个信息结构体。

到这里背包系统就结束了。