Skip to content

Pick me! Pick me!

by AngryAnt on March 10th, 2010

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

using UnityEngine;

public class SelectionManager
{
    private static GameObject s_ActiveSelection;

    public static GameObject ActiveSelection
    {
        get
        {
            return s_ActiveSelection;
        }
        set
        {
            s_ActiveSelection = value;
        }
    }

    public static void Select (GameObject gameObject, bool selectionValue)
    {
        if (selectionValue)
        {
            Select (gameObject);
        }
        else
        {
            Deselect (gameObject);
        }
    }

    public static void Select (GameObject gameObject)
    {
        ActiveSelection = gameObject;
    }

    public static void Deselect (GameObject gameObject)
    {
        if (ActiveSelection == gameObject)
        {
            ActiveSelection = null;
        }
    }

    public static bool IsSelected (GameObject gameObject)
    {
        return ActiveSelection == gameObject;
    }
}

And the promised MonoBehaviour using the SelectionManager class:

using UnityEngine;

public class SelectableObject : MonoBehaviour
{
    public Rect m_SelectionWindowRect = new Rect (10.0f, 10.0f, 300.0f, 100.0f);

    public void OnMouseDown ()
    {
        SelectionManager.Select (gameObject, !SelectionManager.IsSelected (gameObject));
    }

    public void OnDisable ()
    {
        SelectionManager.Deselect (gameObject);
    }

    public void Update ()
    {
        renderer.material.color = SelectionManager.IsSelected (gameObject) ? Color.green : Color.white;
    }

    public void OnGUI ()
    {
        if (SelectionManager.IsSelected (gameObject))
        {
            m_SelectionWindowRect = GUI.Window (GetInstanceID (), m_SelectionWindowRect, SelectionWindow, gameObject.name);
        }
    }

    void SelectionWindow (int id)
    {
        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

From → Tips and tricks

3 Comments
  1. Very useful script, adding it to a project I’m tinkering with now.

  2. Many Thanks. Tried it out, worked perfectly. Much nicer than my initial attempt that just logged the object name to the debug log.

  3. 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

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS

*

Spam protection by WP Captcha-Free