How can I create a instantiate my border around a “bronze” when it is the closest and destroy the border when no longer the closest?

后端 未结 1 1033
生来不讨喜
生来不讨喜 2021-01-29 02:26

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

相关标签:
1条回答
  • 2021-01-29 03:09

    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

    • Instead of Instantiate and Destroy all the time rather only use SetActive
    • Instead of using FindObjectOfType in Update store them in a HashSet event driven: Each Bronze instance registers and unregisters itself
    • Depends on personal taste but I would use Linq to find the closest instance

    This 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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题