Slot Base
This component has the base functionality for the icon slots Item Slot, Spell Slot and Equip Slot.
How To Extend
Let's start building a new slot by extending from the Slot Base.
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using System;
using DuloGames.UI;
using Object = UnityEngine.Object;
public class CustomSlot : UISlotBase { }
Now define a class to contain our custom slot info.
public class MyCustomInfo
{
public int id;
public Sprite icon;
public string name;
}
/// <summary>
/// The assigned custom info.
/// </summary>
private MyCustomInfo m_MyCustomInfo;
/// <summary>
/// Gets the info assigned to this slot.
/// </summary>
/// <returns>The spell info.</returns>
public MyCustomInfo GetInfo()
{
return this.m_MyCustomInfo;
}
To keep track of what the slots contain we should add on assign and on unassign events so we can save that info. Also the use the slot we would need a click event.
Here is how to define the events we are going to use.
[Serializable] public class OnClickEvent : UnityEvent<CustomSlot> { }
[Serializable] public class OnAssignEvent : UnityEvent<CustomSlot> { }
[Serializable] public class OnUnassignEvent : UnityEvent<CustomSlot> { }
/// <summary>
/// The click event delegate.
/// </summary>
public OnClickEvent onClick = new OnClickEvent();
/// <summary>
/// The assign event delegate.
/// </summary>
public OnAssignEvent onAssign = new OnAssignEvent();
/// <summary>
/// The unassign event delegate.
/// </summary>
public OnUnassignEvent onUnassign = new OnUnassignEvent();
In order to check if the slot is assigned we need to override the IsAssigned() method.
/// <summary>
/// Determines whether this slot is assigned.
/// </summary>
/// <returns><c>true</c> if this instance is assigned; otherwise, <c>false</c>.</returns>
public override bool IsAssigned()
{
return (this.m_MyCustomInfo != null);
}
In order to handle the assign process of our new custom slot we must override the Assign(Object source) method. We are also going to define a new method to help us assign the slot by third party scripts.
/// <summary>
/// Assign the slot by the passed source slot.
/// </summary>
/// <param name="source">Source.</param>
public override bool Assign(Object source)
{
if (source is MyCustomSlot)
{
MyCustomSlot sourceSlot = source as MyCustomSlot;
if (sourceSlot != null)
return this.Assign(sourceSlot.GetInfo());
}
// Default
return false;
}
/// <summary>
/// Assign the slot by info.
/// </summary>
/// <param name="info">The info.</param>
public bool Assign(MyCustomInfo info)
{
if (info == null)
return false;
// Make sure we unassign first, so the event is called before new assignment
this.Unassign();
// Use the base class assign to set the icon
this.Assign(info.icon);
// Set the info
this.m_MyCustomInfo = info;
// Invoke the on assign event
if (this.onAssign != null)
this.onAssign.Invoke(this);
// Success
return true;
}
After we have handled the assign process let's do the unassign.
/// <summary>
/// Unassign this slot.
/// </summary>
public override void Unassign()
{
// Remove the icon
base.Unassign();
// Clear the info
this.m_MyCustomInfo = null;
// Invoke the on unassign event
if (this.onUnassign != null)
this.onUnassign.Invoke(this);
}
We're almost done, we still need to override the swapping methods to handle swapping of our custom slot.
/// <summary>
/// Determines whether this slot can swap with the specified target slot.
/// </summary>
/// <returns><c>true</c> if this instance can swap with the specified target; otherwise, <c>false</c>.</returns>
/// <param name="target">Target.</param>
public override bool CanSwapWith(Object target)
{
if (target is MyCustomSlot)
{
// It's MyCustomSlot we can swap
return true;
}
// Default
return false;
}
// <summary>
/// Performs a slot swap.
/// </summary>
/// <returns><c>true</c>, if slot swap was performed, <c>false</c> otherwise.</returns>
/// <param name="sourceSlot">Source slot.</param>
public override bool PerformSlotSwap(Object sourceObject)
{
// Get the source slot
MyCustomSlot sourceSlot = (sourceObject as MyCustomSlot);
// Get the source item info
MyCustomInfo sourceInfo = sourceSlot.GetInfo();
// Assign the source slot by this slot
bool assign1 = sourceSlot.Assign(this.GetInfo());
// Assign this slot by the source slot
bool assign2 = this.Assign(sourceInfo);
// Return the status
return (assign1 && assign2);
}
Now to handle the click event we must override the OnPointerClick(PointerEventData eventData) method.
/// <summary>
/// Raises the pointer click event.
/// </summary>
/// <param name="eventData">Event data.</param>
public override void OnPointerClick(PointerEventData eventData)
{
base.OnPointerClick(eventData);
// Make sure the slot is assigned
if (!this.IsAssigned())
return;
// Check for left click
if (eventData.button == PointerEventData.InputButton.Left)
{
// Invoke the click event
if (this.onClick != null)
this.onClick.Invoke(this);
}
}
Finally here's how to handle tooltips.
/// <summary>
/// Raises the tooltip event.
/// </summary>
/// <param name="show">If set to <c>true</c> show.</param>
public override void OnTooltip(bool show)
{
// Make sure we have info
if (this.m_MyCustomInfo == null)
return;
// If we are showing the tooltip
if (show)
{
UITooltip.InstantiateIfNecessary(this.gameObject);
// Prepare the tooltip
// Set the title and description
UITooltip.AddTitle(this.m_MyCustomInfo.name);
// Anchor to this slot
UITooltip.AnchorToRect(this.transform as RectTransform);
// Show the tooltip
UITooltip.Show();
}
else
{
// Hide the tooltip
UITooltip.Hide();
}
}
Complete MyCustomSlot Script
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using System;
using Object = UnityEngine.Object;
namespace DuloGames.UI
{
public class MyCustomSlot : UISlotBase
{
public class MyCustomInfo
{
public int id;
public Sprite icon;
public string name;
}
[Serializable] public class OnClickEvent : UnityEvent<MyCustomSlot> { }
[Serializable] public class OnAssignEvent : UnityEvent<MyCustomSlot> { }
[Serializable] public class OnUnassignEvent : UnityEvent<MyCustomSlot> { }
/// <summary>
/// The assigned custom info.
/// </summary>
private MyCustomInfo m_MyCustomInfo;
/// <summary>
/// The click event delegate.
/// </summary>
public OnClickEvent onClick = new OnClickEvent();
/// <summary>
/// The assign event delegate.
/// </summary>
public OnAssignEvent onAssign = new OnAssignEvent();
/// <summary>
/// The unassign event delegate.
/// </summary>
public OnUnassignEvent onUnassign = new OnUnassignEvent();
/// <summary>
/// Gets the info assigned to this slot.
/// </summary>
/// <returns>The spell info.</returns>
public MyCustomInfo GetInfo()
{
return this.m_MyCustomInfo;
}
/// <summary>
/// Determines whether this slot is assigned.
/// </summary>
/// <returns><c>true</c> if this instance is assigned; otherwise, <c>false</c>.</returns>
public override bool IsAssigned()
{
return (this.m_MyCustomInfo != null);
}
/// <summary>
/// Assign the slot by info.
/// </summary>
/// <param name="info">The info.</param>
public bool Assign(MyCustomInfo info)
{
if (info == null)
return false;
// Make sure we unassign first, so the event is called before new assignment
this.Unassign();
// Use the base class assign to set the icon
this.Assign(info.icon);
// Set the info
this.m_MyCustomInfo = info;
// Invoke the on assign event
if (this.onAssign != null)
this.onAssign.Invoke(this);
// Success
return true;
}
/// <summary>
/// Assign the slot by the passed source slot.
/// </summary>
/// <param name="source">Source.</param>
public override bool Assign(Object source)
{
if (source is MyCustomSlot)
{
MyCustomSlot sourceSlot = source as MyCustomSlot;
if (sourceSlot != null)
return this.Assign(sourceSlot.GetInfo());
}
// Default
return false;
}
/// <summary>
/// Unassign this slot.
/// </summary>
public override void Unassign()
{
// Remove the icon
base.Unassign();
// Clear the info
this.m_MyCustomInfo = null;
// Invoke the on unassign event
if (this.onUnassign != null)
this.onUnassign.Invoke(this);
}
/// <summary>
/// Determines whether this slot can swap with the specified target slot.
/// </summary>
/// <returns><c>true</c> if this instance can swap with the specified target; otherwise, <c>false</c>.</returns>
/// <param name="target">Target.</param>
public override bool CanSwapWith(Object target)
{
if (target is MyCustomSlot)
{
// It's MyCustomSlot we can swap
return true;
}
// Default
return false;
}
// <summary>
/// Performs a slot swap.
/// </summary>
/// <returns><c>true</c>, if slot swap was performed, <c>false</c> otherwise.</returns>
/// <param name="sourceSlot">Source slot.</param>
public override bool PerformSlotSwap(Object sourceObject)
{
// Get the source slot
MyCustomSlot sourceSlot = (sourceObject as MyCustomSlot);
// Get the source item info
MyCustomInfo sourceInfo = sourceSlot.GetInfo();
// Assign the source slot by this slot
bool assign1 = sourceSlot.Assign(this.GetInfo());
// Assign this slot by the source slot
bool assign2 = this.Assign(sourceInfo);
// Return the status
return (assign1 && assign2);
}
/// <summary>
/// Raises the tooltip event.
/// </summary>
/// <param name="show">If set to <c>true</c> show.</param>
public override void OnTooltip(bool show)
{
// Make sure we have info
if (this.m_MyCustomInfo == null)
return;
// If we are showing the tooltip
if (show)
{
UITooltip.InstantiateIfNecessary(this.gameObject);
// Prepare the tooltip
// Set the title and description
UITooltip.AddTitle(this.m_MyCustomInfo.name);
// Anchor to this slot
UITooltip.AnchorToRect(this.transform as RectTransform);
// Show the tooltip
UITooltip.Show();
}
else
{
// Hide the tooltip
UITooltip.Hide();
}
}
/// <summary>
/// Raises the pointer click event.
/// </summary>
/// <param name="eventData">Event data.</param>
public override void OnPointerClick(PointerEventData eventData)
{
base.OnPointerClick(eventData);
// Make sure the slot is assigned
if (!this.IsAssigned())
return;
// Check for left click
if (eventData.button == PointerEventData.InputButton.Left)
{
// Invoke the click event
if (this.onClick != null)
this.onClick.Invoke(this);
}
}
}
}