Pick me! Pick me!
Say you’re developing an RTS or maybe a connect-the-dots sort of game. What would be the easiest way to go about handling object selection? This is my suggested solution.
In the given example, I’m taking advantage of the object-mouse event handling that MonoBehaviours on GameObject with colliders on them give for free. You might be in a scenario where raycasting or otherwise resolving selection requests makes more sense, but the basic logic still applies. This example is merely intended to get your from start to goal as fast as possible.
First off, we need a selection manager class (cleverly named SelectionManager in my example). This is where we store selection state and via static accessors, we can get and modify the current selection. Seeing as this class is both public and all accessors are static, you can put its source anywhere. In my example I’ve simply put it right after the MonoBehaviour used for testing it.
SelectionManager
public class SelectionManager
{
private static GameObject s_ActiveSelection;
public static GameObject ActiveSelection
{
get
{
return s_ActiveSelection;
}
set
{
s_ActiveSelection = value;
}
}
{
if (selectionValue)
{
Select (gameObject);
}
else
{
Deselect (gameObject);
}
}
{
ActiveSelection = gameObject;
}
{
if (ActiveSelection == gameObject)
{
ActiveSelection = null;
}
}
{
return ActiveSelection == gameObject;
}
}
And the promised MonoBehaviour using the SelectionManager class:
public class SelectableObject : MonoBehaviour
{
public Rect m_SelectionWindowRect = new Rect (10.0f, 10.0f, 300.0f, 100.0f);
{
SelectionManager.Select (gameObject, !SelectionManager.IsSelected (gameObject));
}
{
SelectionManager.Deselect (gameObject);
}
{
renderer.material.color = SelectionManager.IsSelected (gameObject) ? Color.green : Color.white;
}
{
if (SelectionManager.IsSelected (gameObject))
{
m_SelectionWindowRect = GUI.Window (GetInstanceID (), m_SelectionWindowRect, SelectionWindow, gameObject.name);
}
}
{
GUILayout.Box ("I am the selection and my name is " + gameObject.name);
GUI.DragWindow ();
}
}
And that is all there is to it. By popular demand, I’m now starting to provide pre-built projects with these tips and tricks posts. Download, unzip, open and play. Requires Unity 2.6.1:
SelectableObject
Very useful script, adding it to a project I’m tinkering with now.
Many Thanks. Tried it out, worked perfectly. Much nicer than my initial attempt that just logged the object name to the debug log.
Excellent scripts, thanks a lot. The sample works perfectly and I can’t wait to implement the techniques you show in my projects.
Cheers!
-arbbot