I\'ve been stuck at this for a while. What I want is for my outline object to be instantiated at the location of my bronze Base game object and for it to destroy when the bronze
In the Bronze
in notSelected
you are destroying the prefab selectBox
!
You probably rather wanted to destroy the clone
instance.
Anyway I would suggest a few things that I would do different
Instantiate
and Destroy
all the time rather only use SetActive
FindObjectOfType
in Update
store them in a HashSet event driven: Each Bronze instance registers and unregisters itselfLinq
to find the closest instanceThis could look somewhat like
public class Bronze : MonoBehaviour
{
// Every instance of this component registers and unregisters itself here
public static readonly HashSet<Bronze> Instances = new HashSet<Bronze>();
[Header("References")]
public Animator anim;
[SerializeField] private GameObject selectedBox;
[SerializeField] private GameObject bronzeBase;
[Header("Debugging")]
[SerializeField] bool _isSelected = false;
private GameObject clone;
// Have a property for the selection
public bool IsSelected
{
// when something reads this property return _isSelected
get => _isSelected;
// This is executed everytime someone changes the value of IsSelected
set
{
if(_isSelected == value) return;
_isSelected = value;
clone.SetActive(_isSelected);
}
}
// Update is called once per frame
void Awake()
{
// Instantiate already returns the type of the given prefab
clone = Instantiate(selectedBox, bronzeBase.transform);
// Register yourself to the alive instances
Instances.Add(this);
}
private void OnDestroy ()
{
// Remove yourself from the Instances
Instances.Remove(this);
}
}
And then use it
using System.Linq;
public class FindBronze : MonoBehaviour
{
private Bronze currentSelected;
private void Update()
{
UpdateClosestBronze();
}
void UpdateClosestBronze()
{
if(Bronze.Instances.Count ==0) return;
// This takes the instances
// orders them by distance ascending using the sqrMagnitude
// of the vector between the Instance and you
// sqrMagnitude is more efficient than Vector3.Distance when you only need to compare instead of the actual distance
// then finally it takes the first item
var newClosest = Bronze.Instances.OrderBy(b => (b.transform.position - transform.position).sqrMagnitude).First();
// skip if the result is the same as last time
if(newClosest == currentSelected) return;
// otherwise first deselect the current selection if there is one
if(currentSelected)
{
currentSelected.IsSelected = false;
}
// Then set the new selection
currentSelected = newSelected;
currentSelected.IsSelected = true;
}
}