【发布时间】:2016-05-22 11:15:40
【问题描述】:
在过去的几天里,我一直在尝试开发一个 UI 项目拖放系统,并使其尽可能灵活(它是使用 Unity 3D 开发的,尽管这与我的问题并不完全相关)。在我准确解释问题所在之前,这是代码:
public class ItemHandler<ItemType> : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IHoverHandler where ItemType : Item {
public ItemType item { get; protected set; }
...
}
public abstract class SlotHandler<ItemType> : MonoBehaviour, IDropHandler where ItemType : Item {
...
public ItemHandler<ItemType> itemHandler { get; protected set; }
...
public void OnDrop(PointerEventData eventData) {
// Retrieve the slots
SlotHandler<Item> originalSlotHandler = ItemManager.draggedItemParent.GetComponent<SlotHandler<Item>>();
SlotHandler<ItemType> destinationSlotHandler = this;
// Retrieve the handlers from their items
ItemHandler<Item> originalItemHandler = originalSlotHandler.itemObject != null ? originalSlotHandler.itemObject.GetComponent<ItemHandler<Item>>() : null;
ItemHandler<ItemType> destinationItemHandler = destinationSlotHandler.itemObject != null ? destinationSlotHandler.itemObject.GetComponent<ItemHandler<ItemType>>() : null;
// Add the original item to the destination slot
bool canAddToDestination = originalSlotHandler is SlotHandler<ItemType> || originalSlotHandler is SlotHandler<Item>;
bool canRemoveFromOrigin = originalSlotHandler is SlotHandler<ItemType> || destinationSlotHandler is SlotHandler<Item>;
// Swap the items
if(canAddToDestination == true && canRemoveFromOrigin == true) {
// Remove the old items
originalSlotHandler.RemoveItem();
destinationSlotHandler.RemoveItem();
// Add the new items
originalSlotHandler.AddItem(destinationItemHandler);
destinationSlotHandler.AddItem(originalItemHandler);
...
}
...
}
public virtual void AddItem(ItemHandler<ItemType> itemHandler) {
this.itemHandler = itemHandler;
}
}
这背后的想法是让 ItemHandler 具有给定类型(例如 ItemHandler、ItemHandler 等),然后只允许将它们放入相同类型或相同基本类型的 SlotHandler 中。
- ItemHandler
进入 SlotHandler 和 SlotHandler - 。
- ItemHandler 进入 SlotHandler 和 SlotHandler。
我尝试这样做是因为我想限制我可以在哪些插槽中放置特定物品。
问题在于我必须考虑特定类型的插槽,SlotHandler
现在,由于 ItemHandler 不是 ItemHandler 的子类(或任何其他派生的 Item 类型),这将不起作用。现在你可能会说为什么不只存储 Item 而不是存储 Generic ItemType?我会,但这里的想法是派生 SlotHandler 并在每个子类中具有特定的行为(将项目放入不同类型的插槽应该做不同的事情)。
我想我明白为什么这不会像我尝试的那样工作,但我找不到我觉得舒服的解决方案,所以我想我会尝试寻求帮助。抱歉,如果我对问题不够清楚,请告诉我是否应该解决问题。
提前感谢您尝试解决我的问题的任何帮助!
【问题讨论】:
-
你是在 UI 系统(Canvas)还是在主游戏场景中这样做?
-
Unity 是一个 ECS 系统。无论如何,它都不是一个面向对象的系统。 (Unity 目前碰巧用来编写组件的语言 c# 确实是一种 OO 语言。但那没什么,无关紧要。他们可以随时更改为组件的其他语言。)我可能不会这样做像你正在做的任何事情。我要做的是编写一个“可拖动”组件,您可以将其附加(当然是任何东西 - 它是一个 ECS 系统),这使得该东西可拖动。这就是它的结束。故事结局。关于“插槽”,如果您希望它们表现得...
-
...以某种方式表现 - 然后为此编写一个行为。即,他们可能会拒绝一些拖到他们身上的物品,在某些情况下他们可能会放烟花......无论如何。那种“插槽行为”,当然(它是 Unity),你应该能够放下任何东西。这是最近一篇关于相关问题的文章stackoverflow.com/a/37243035/294884
-
简而言之,您可能会将 the thing 与“您碰巧编写的可以放在 Unity 中的对象上的组件”混淆。请注意,例如您使用了语法时态
SlotHandler。什么是 SlotHandler? Unity 中不存在这样的东西,Unity 中也不可能存在。它只是一个游戏对象。如果你想做一个行为,也许是AcceptDrops,那么就去做吧。就像您在 Unity 中编写的任何脚本(也称为任何组件、任何行为)一样,它只是您可以放置在任何 GameObject 上的一种行为。 -
@JoeBlow:您的整个解释如果链接到“ECS 系统”会更有意义。