私は過去数日間、UIアイテムのドラッグアンドドロップシステムを開発し、できるだけ柔軟なものにしようとしていました。ユニティ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 <武器を>など)とのみ同じ基本型の同じ型ORのSlotHandlerにドロップできるようにします。
- ItemHandler <宝石> SlotHandler <宝石>とSlotHandler <項目>に入ります。
- ItemHandler <武器> SlotHandlerに移動<武器> SlotHandler <アイテム>。
私は特定のアイテムを削除できるスロットを制限したいので、この方法でやってみました。
問題はSlotHandler < Item>(すべてのアイテムの基本クラスであるコードスニペットに表示されるItemクラス)という特定のタイプのスロットを考慮する必要があるという事実に由来します。インベントリスロットは、あらゆる種類のアイテムを保持できる必要があります。
ここで、ItemHandler < Gem>はItemHandler < Item>(または他の派生型Item)のサブクラスではないため、これは機能しません。今では、なぜItemを格納するのではなく、Generic ItemTypeを格納するだけでいいのでしょうか?私はここではSlotHandlerを派生させ、各サブクラスで異なる動作をする(異なるタイプのスロットにアイテムを落とすことは別々のことを行う)ことを考えています。
これは私がそれをやろうとしている方法ではうまくいかないと思っていますが、私は気持ちの良い解決策を見つけることができません。申し訳ありませんが、私は問題が十分に明確でない場合は、私は何かをクリアする必要があります私にお知らせください。
私の問題を解決しようとするお手伝いをしてくれてありがとうございました!
あなたはUIシステム(Canvas)やメインゲームのシーンでこれをやっていますか? – Fattie
ユニティはECSシステムです。それは決して漠然としていても、OOシステムではありません。 (Unityが現時点でコンポーネントを書くために使っている言語、C#は実際にOO言語ですが、それは無関係で無関係です。いつでも他の言語に変更することができます)あなたがしているようなもの。私がやるべきことは、あなたがそれをドラッグ可能にするコンポーネント(もちろん、ECSシステム)にアタッチできるコンポーネント "Draggable"を書くことです。そして、それはそれの終わりです。物語の終わり。 「スロット」に関して、あなたがそれらを行動させたいと思えば.... – Fattie
...何らかの方法で行動します。すなわち、彼らはそれらにドラッグされたいくつかの項目を拒否することがあります、彼らはいくつかの場合、花火をプレイする可能性があります。その "スロットの振る舞い"、もちろん(それはUnityです)あなたは何かに落とせるはずです。関連する問題に関する最近のエッセイはありますか?http://stackoverflow.com/a/37243035/294884 – Fattie