unity3d - 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;
}
如果有人可以帮助我,我将不胜感激。我一直在努力,我快疯了。
解决方案
推荐阅读
- ui-grid - ui-grid - 启用全选时如何设置选择列的显示名称?
- c# - Linux 中的 .NET Core 和来自外部库的 DLLImport
- swift - Swift - 防止函数被调用两次
- matlab - 在simulink中更改变量值
- php - 用多个 or 重构 if 语句
- c++ - 在部分模板特化中使用 decltype
- c - 初始化 const 结构时重复字段
- android - 如何使用 android studio 应用程序使用数据库字段实现 firebase 身份验证字段?
- swift - 如何使用变量的字符串值来更改特定对象的文本
- java - 尝试使用正则表达式查找后跟逗号的数字的出现