Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question SetActive() not working

Discussion in 'Scripting' started by Sekudo, Aug 9, 2023.

  1. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36
    Hey all,
    I'm trying to make it so that when the player dies, all objects with tag "dashcrystal" will be set to active. I have these two pieces of code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class KillObject : MonoBehaviour
    7. {
    8.     public Vector2 spawnPos;
    9.     private Vector2 crystalSpawn;
    10.     [SerializeField] private bool shouldReload;
    11.  
    12.     private void OnCollisionEnter2D(Collision2D collision)
    13.     {
    14.         if (collision.gameObject.CompareTag("Player"))
    15.         {
    16.             // Activate all objects with the "DashCrystal" tag
    17.             ActivateDashCrystals();
    18.  
    19.             // Reload the current scene
    20.             collision.gameObject.transform.position = spawnPos;
    21.         }
    22.     }
    23.  
    24.     private void SceneReload()
    25.     {
    26.         int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    27.         SceneManager.LoadScene(currentSceneIndex);
    28.     }
    29.  
    30.     private void ActivateDashCrystals()
    31.     {
    32.         GameObject[] dashCrystals = GameObject.FindGameObjectsWithTag("DashCrystal");
    33.  
    34.         // smth
    35.  
    36.         foreach (GameObject dashCrystal in dashCrystals)
    37.         {
    38.             dashCrystal.SetActive(true);
    39.         }
    40.     }
    41. }
    42.  
    Code (CSharp):
    1.     private void OnTriggerEnter2D(Collider2D other)
    2.     {
    3.         if (other.CompareTag("Coin"))
    4.         {
    5.             // Increment the player's score
    6.             score++;
    7.             // Destroy the coin object
    8.             Destroy(other.gameObject);
    9.         }
    10.  
    11.         if (other.CompareTag("DashCrystal"))
    12.         {
    13.             // Reset the dash
    14.             canDash = true;
    15.             // Destroy the crystal
    16.             other.gameObject.SetActive(false);
    17.         }
    18.     }
    There is nothing else that sets the Dash Crystals to false. I even tried using a Debug.Log instead of the SetActive and it ran. Thank you for reading.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,718
    SisusCo and bugfinders like this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    This is why it's always better to go the Unity Way(tm) and drag all the stuff into some public field you can reliably access.

    Anytime you use GetComponent<T>() or any Find, or any of its kin (in Children, in Parent, plural, etc) to try and tease out Components at runtime is definitely deep into super-duper-uber-crazy-Ninja advanced stuff.

    This sort of coding is to be avoided at all costs unless you know exactly what you are doing.

    If you run into an issue with any of these calls, start with the documentation to understand why.

    There is a clear set of extremely-well-defined conditions required for each of these calls to work, as well as definitions of what will and will not be returned.

    In the case of collections of Components, the order will NEVER be guaranteed, even if you happen to notice it is always in a particular order on your machine.

    It is ALWAYS better to go The Unity Way(tm) and make dedicated public fields and drag in the references you want.
     
  4. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,900
    I prefer to write these GetComponent parts in the Reset method (and setup proper RequireComponent relationships), so it happens mostly automatically. I don't like manually dragging and dropping references to other components...
     
    Kurt-Dekker likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Very smart... I admit to being too lazy most of the time... BUT... occasionally I have even stuck some
    #if UNITY_EDITOR
    code in my Reset()s to actually go digging for actual disk assets!!!

    Since you mention it, I think I will try to make that a step from now on.

    For others wondering what Lurk and I are on about...

    Serialized properties in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

    - what the class constructor makes (either default(T) or else field initializers, eg "what's in your code")

    - what is saved with the prefab

    - what is saved with the prefab override(s)/variant(s)

    - what is saved in the scene and not applied to the prefab

    - what is changed in Awake(), Start(), or even later etc.

    Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

    Here's the official discussion: https://blog.unity.com/technology/serialization-in-unity

    Field initializers versus using
    Reset()
    function and Unity serialization:

    https://forum.unity.com/threads/sensitivity-in-my-mouselook-script.1061612/#post-6858908

    https://forum.unity.com/threads/crouch-speed-is-faster-than-movement-speed.1132054/#post-7274596
     
    Lurking-Ninja likes this.
  6. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,900
    Yes, just for clarity: what we described with the Reset method goes into this category and NOT in the
    because Reset is an editor-only method, it populates the field in the editor, it gets saved with scene just as if you would have populated it with dragging and dropping. If you use the Reset menu point in the component's hamburger menu, it will be reset to the thing you wrote in there. But again, editor only.
     
    Kurt-Dekker likes this.
  7. Sekudo

    Sekudo

    Joined:
    Dec 4, 2022
    Posts:
    36