首页 > 解决方案 > Unity 从库存中拖放

问题描述

我对 Unity 很陌生,所以请原谅我对事物的业余理解。我目前正在尝试在统一 3d 中实现一个界面,其中包含一个包含 2D 图标的清单,我想从清单中拖放这些图标,然后应该让 gameObejct 产生。我已尝试在 YouTube 上实施 Jayanam 的确切代码,并在此处添加链接:创建库存 UI: https ://www.youtube.com/watch?v=-xB4xEmGtCY&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY

库存脚本: https ://www.youtube.com/watch?v=Hj7AZkyojdo&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY&index=2

库存 UI 拖放: https ://www.youtube.com/watch?v=Pc8K_DVPgVM&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY&index=3

掉落物品: https ://www.youtube.com/watch?v=db6ofSbAXnE&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY&index=4

一切正常,直到我达到我想要放下物品的地步。我可以看到它调用了 drop-function,但我的 gameObject 没有产生。我在这里添加我的代码,希望有人能给出答案。

游戏对象:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Child : MonoBehaviour, IInventoryItem
{
    public string Name
    {
        get
        {
            return "Child";
        }
    }

    public Sprite _Image = null;

    public Sprite Image
    {
        get
        {
            return _Image;
        }
    }

    
    public void OnPickup()
    {
        // TODO: Add logic what happens when child stays in the sun for too long
        gameObject.SetActive(false);
    }

    public void OnDrop()
    {
        RaycastHit hit = new RaycastHit();
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast(ray, out hit, 1000))
       {
            gameObject.SetActive(true);
            gameObject.transform.position = hit.point;
        }
    }


}


用于处理库存的 HUD 脚本:

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

public class HUD : MonoBehaviour
{

    public Inventory Inventory;

    // Start is called before the first frame update
    void Start()
    {
        Inventory.ItemAdded += InventoryScript_ItemAdded;
        Inventory.ItemRemoved += Inventory_ItemRemoved;
    }

    private void InventoryScript_ItemAdded(object sender, InventoryEventArgs e)
    {
        Transform inventoryPanel = transform.Find("InventoryPanel");
        foreach(Transform slot in inventoryPanel)
        {
            // Border ... Image
            Transform imageTransform = slot.GetChild(0).GetChild(0);
            Image image = slot.GetChild(0).GetChild(0).GetComponent<Image>();
            ItemDragHandler itemDragHandler = imageTransform.GetComponent<ItemDragHandler>();

            // We found the empty slot
            if (!image.enabled)
            {
                image.enabled = true;
                image.sprite = e.Item.Image;

                // TODO: Store a reference to the item
                itemDragHandler.Item = e.Item;

                break;
            }
        }
    }

    private void Inventory_ItemRemoved(object sender, InventoryEventArgs e)
    {
        Transform inventoryPanel = transform.Find("InventoryPanel");
        foreach (Transform slot in inventoryPanel)
        {
            Transform imageTransform = slot.GetChild(0).GetChild(0);
            Image image = imageTransform.GetComponent<Image>();
            ItemDragHandler itemDragHandler = imageTransform.GetComponent<ItemDragHandler>();

            //We found the item in the UI
            if (itemDragHandler.Item.Equals(e.Item))
            {
                image.enabled = false;
                image.sprite = null;
                itemDragHandler.Item = null;
                break;

            }
        }
    }

    
}

项目拖动处理程序将项目图像拉出库存:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class ItemDragHandler : MonoBehaviour, IDragHandler, IEndDragHandler
{
    public IInventoryItem Item { get; set; }
    public void OnDrag(PointerEventData eventData)
    {
        transform.position = Input.mousePosition;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
            transform.localPosition = Vector3.zero;
    }
}

    

物品掉落处理程序:


 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class ItemDropHandler : MonoBehaviour, IDropHandler
{
    public void OnDrop(PointerEventData eventData)
    { 
        RectTransform invPanel = transform as RectTransform;

        if(!RectTransformUtility.RectangleContainsScreenPoint(invPanel, Input.mousePosition))
        {
          Debug.Log("Drop item");
        }
    }


}

库存脚本:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Inventory : MonoBehaviour
{
    private const int SLOTS = 4;

    private List<IInventoryItem> mItems = new List<IInventoryItem>();

    public event EventHandler<InventoryEventArgs> ItemAdded;

    public event EventHandler<InventoryEventArgs> ItemRemoved;

    //TODO: delete collider, Item should be picked up by mouse
    public void AddItem(IInventoryItem item)
    {
        if(mItems.Count < SLOTS)
        {
            Collider collider = (item as MonoBehaviour).GetComponent<Collider>();
            if (collider.enabled)
            {
                collider.enabled = false;

                mItems.Add(item);

                item.OnPickup();

                if (ItemAdded != null)
                {
                    ItemAdded(this, new InventoryEventArgs(item));
                }
            }
        }
    }

    public void RemoveItem(IInventoryItem item)
    {
        if (mItems.Contains(item))
        {
            mItems.Remove(item);

            item.OnDrop();

            Collider collider = (item as MonoBehaviour).GetComponent<Collider>();
            if (collider != null)
            {
                collider.enabled = true;
            }

            if (ItemRemoved != null)
            {
                ItemRemoved(this, new InventoryEventArgs(item));
            }
        }
    }
}

库存项目类

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IInventoryItem
{

    string Name { get; }

    Sprite Image { get; }

    void OnPickup();

    void OnDrop();
}

public class InventoryEventArgs: EventArgs
{
    public InventoryEventArgs(IInventoryItem item)
    {
        Item = item;
    }

    public IInventoryItem Item;
}

如果有人可以帮助我,我将不胜感激。我一直在努力,我快疯了。

标签: unity3duser-interfacedrag-and-dropspawninventory

解决方案


推荐阅读