Overengineering
This month I focused on creating the consumable items and also the shortcut bar to hold them and use them during the game.
Since this was the third drag a drop operation (after the equipment screen and the crafting menu) I decided to try to make something more flexible that I could reuse in the future. In those two previous occasions, I wrote an script in each case to control the interaction. One of the reasons was that I wanted to implement several control modes, not only drag&drop but also "click to grab" and "click to socket into an slot".
I did plenty of copy paste but also plenty of modifications (for example, in the equipment system anything that is equiped on a creature gets removed from the inventory, while when crafting the ingredients are only removed when you actually craft), so now that I had to do it a third time and maybe would have to make it again in the future, I thought of isolating that behaviour and make a script that would fit all the cases using the two I already had as a template.
Then the overengineering started. I worked on this script for two days:
public interface IHasIcon
{
Sprite GetIcon();
}
public class SelectOrDragIntoSlot<ContentType,SlotType>
where SlotType : Slot<ContentType>
where ContentType : IComparable, IHasIcon
{
private enum AssignationState
{
None,
SelectedSlot,
SelectedItem,
}
public delegate void ContentSlotted(SlotType slot, ContentType content);
public event ContentSlotted ContentSlottedEvent;
public event ContentSlotted ContentRemovedFromSlotEvent;
private ContentType selectedContent;
private SlotType selectedSlot;
private AssignationState state;
private GameObject draggingItem;
private void IngredientEventsUnsubscribe()
{
IngredientSlot.SlotClickedEvent -= SlotClick;
IngredientSlot.SlotRightClickedEvent -= SlotRightClick;
ScrapableDisplay.ScrapableClickedEvent -= ContentClick;
}
private void IngredientEventsSubscribe()
{
IngredientSlot.SlotClickedEvent -= SlotClick;
IngredientSlot.SlotRightClickedEvent -= SlotRightClick;
ScrapableDisplay.ScrapableClickedEvent -= ContentClick;
}
/// <summary>
/// Try to put content into slot
/// </summary>
private void SetSlotContent(SlotType slot, ContentType content)
{
if ( slot.ValidateContent(content) )
slot.SlotContent(content);
}
public void SlotClick(SlotType slotClicked)
{
if (state == AssignationState.SelectedItem)
{
SetSlotContent(slotClicked, selectedContent);
Deselect();
}
else
{
SelectSlot(slotClicked);
}
}
public void ContentClick(ContentType contentClicked)
{
if (state == AssignationState.SelectedSlot)
{
SetSlotContent(selectedSlot,contentClicked);
Deselect();
}
else
{
SelectContent(contentClicked);
}
}
public void SlotRightClick(SlotType slotDisplay)
{
slotDisplay.Unslot();
Deselect();
}
private void SelectContent(ContentType newSelectedContent)
{
Deselect();
selectedContent = newSelectedContent;
draggingItem = CreateDragGraphic(newSelectedContent);
state = AssignationState.SelectedItem;
}
private void SelectSlot(SlotType newSelectedSlot)
{
Deselect();
selectedSlot = newSelectedSlot;
ContentType slotContent = selectedSlot.GetContent();
if (slotContent.Equals(default) == false)
draggingItem = CreateDragGraphic(slotContent);
state = AssignationState.SelectedSlot;
}
private void Deselect()
{
selectedContent = default;
selectedSlot = default;
GameObject.Destroy( draggingItem );
state = AssignationState.None;
}
private GameObject CreateDragGraphic(ContentType item)
{
GameObject draggedItemGO = new GameObject("DraggedObject");
draggedItemGO.AddComponent<RectTransform>();
draggedItemGO.AddComponent<Image>();
DraggedItem draggedItem = draggedItemGO.AddComponent<DraggedItem>();
draggedItem.SetImage(item.GetIcon());
return draggingItem.gameObject;
}
private void Update()
{
if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) &&
(state != AssignationState.None))
{
if ((EventSystem.current.currentSelectedGameObject == null) ||
(state == AssignationState.SelectedItem && EventSystem.current.currentSelectedGameObject.GetComponent<SlotType>() == null) ||
(state == AssignationState.SelectedSlot && (EventSystem.current.currentSelectedGameObject.GetComponent<ContentType>() == null && EventSystem.current.currentSelectedGameObject.GetComponent<InventoryPanel>() == null)))
{
Deselect();
}
}
}
}
And I just though to myself "this can't be right". So I watched a youtube tutorial. I had already watched one before starting the first drag and drop system, but I grew it into a monstrosity. Tehy just used the drag and drop interfaces and I decided to do the same. It is true that it is not very flexible and I lost "the click to grab, click again to drop" but I gained sanity. I think I may add those controls again if I find a simple way to implement them.
Here is the dragging and dropping and using items on creatures in action:
Get Pack
Pack
Action RPG with creature collection mechanics.
Status | In development |
Author | FeitizoGames |
Genre | Role Playing |
Tags | 3D, Action RPG, Loot, Monsters, pokemon, Strategy RPG, Top-Down, Unity |
Languages | English |
More posts
- New creature! Volcark, the blacksmith hermit crabJun 20, 2024
- Creatures as charactersJun 03, 2024
- Dialogue systemJan 09, 2022
- All initial creatures are ready!Sep 29, 2020
- Gameplay polishingSep 20, 2020
- Controlling particles in unity with custom vertex streamsJul 22, 2020
- Gameplay video, new crafting systemJun 27, 2020
- Pack DEMO is now AVAILABLE!Feb 23, 2020
- Demo available on 23rd of February!Feb 08, 2020
Leave a comment
Log in with itch.io to leave a comment.