- Home /
Deselect object when another instance is selected
I have seen this same question asked a couple times but I was unable to get it to work for my setup after reading through several solutions.
Relevant: C#, 2D My problem is I have a couple instances of a prefab that are selectable by mouse click. I want it so that when I select one of these objects, the previously selected object is de-selected. Currently I am attempting to do this with a static bool on the class that trips a deselect function, and using the OnMouseDown function to protect that certain instance from the deselect function. Here is my code: (Apologies for sloppy formatting)
public class spawnScript : MonoBehaviour {
public bool selected;
public bool notSelected = true;
//static bool for tripping deselect function
public static bool clear;
void Update () {
//if clear is tripped
if (clear) {
//run deslect method
clearSelection ();
//reset clear
clear = false;
}
}
public void OnMouseDown(){
//protect this gameObject from being cleared
notSelected = false;
//trips the clear boolean on all instances
spawnScript.clear = true;
//select this gameObject
selected = true;
}
public void OnMouseUp(){
//sets it up to be clearable in the future
notSelected = true;
}
//clears selection
public void clearSelection(){
//Instances not clicked are deselected
if (notSelected) {
selected = false;
}
}
}
currently, the deselect function isn't tripping correctly. I am pretty new to all this, and suspect my problem is using a static bool and then manipulating that bool within the same class. Almost positive this is the issue, but I've tried so many things that I kind of lost myself and fear I am trying the same things over and over.
I tried several raycast2D methods instead and couldn't get it to work.. Most likely I need to change my logic to a single SelectManager class that these prefabs reference instead, but I haven't tried that yet. Any advice to make this script work, or, advice pointing me in the best direction (retry raycasts, try a SelectManager, etc.) will be greatly appreciated.
Answer by robertbu · Nov 09, 2014 at 11:24 PM
Here is how I might approach your original solution using a static variable:
using UnityEngine;
using System.Collections;
public class spawnScript : MonoBehaviour {
static private Transform trSelect = null;
private bool selected = false;
void Update () {
if (selected && transform != trSelect) {
selected = false;
}
}
public void OnMouseDown(){
selected = true;
trSelect = transform;
}
}
I'm gonna test this at lunch but this seems to be the most simple answer. wow... I was messing around with static bools the entire time, I didn't realize at all you could use a static transform. It makes so much sense though. Thank you!!!
While I am proud of myself for making something work after days of struggle, Your solution is more simple and more practical. Thank you for showing me static transform and solving my original issue.
Thank you so much! Turns out its way more simplier then I thought.
Answer by JazzWolf · Nov 09, 2014 at 11:17 PM
I got something to work, not using static variables. I instead have the following script attached to a Player gameobject that manages the game. Here is the script for selection
public void Update(){
//On the units, I have an OnMouseDown that changes the tag to SelectMe
GameObject newSlot = GameObject.FindGameObjectWithTag ("SelectMe");
if (newSlot != null) {
//search for and store the Previously Selected Unit
GameObject oldSlot = GameObject.FindGameObjectWithTag("Selected");
//The last clicked unit becomes selected
spawnScript towerSelect = newSlot.GetComponent<spawnScript> ();
towerSelect.selected = true;
//Then becomes the latest Selected unit
newSlot.tag = "Selected";
//The previous Selected unit becomes de-selected
spawnScript towerDeselect = oldSlot.GetComponent<spawnScript>();
towerDeselect.selected = false;
//and is set back to Untagged
oldSlot.tag = "Untagged";
}
}
I have tested this and it works perfect. The obvious set back here is running several FindGameObjectWithTags. I know this is bad for overall performance, but for my current needs and Prototyping, it works. If you agree please upvote this answer I can use some reputation!
Answer by Kiwasi · Nov 09, 2014 at 11:38 PM
I tend to use a manager for this. The manager sends a message to each GameObject when it is selected and when it is deselected. This type of setup is very easily extendable for multiple selectable GameObjects.
Pseudo code:
public class SelectManager : MonoBehaviour {
public GameObject selectedObject {get; private set;}
public void ChangeSelection (GameObject newSelection){
if(selectedObject){
selectedObject.SendMessage ("Deselect");
}
selectedObject = newSelection;
selectedObject.SendMessage ("Select");
}
}
You can call ChangeSelection from a raycast or from OnMouseUp on the individual GameObjects. You should also consider the case where the selectedObject is destroyed while selected. I typically handle this by reverting the selection to the SelectManager if nothing else is selected.
Your answer
![](https://koobas.hobune.stream/wayback/20220613171034im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Unity5 UI - How to trigger button click event while preventing menu item deselect event? 1 Answer
How to individualize objects with same script? 0 Answers
How do i deselect an instance by selecting another instance of the same game Object? 2 Answers
EventSystem child element selection/deselection and click 0 Answers
Loss of GO selection 2 Answers