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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

GameObject.SetActive acting weird

Discussion in 'Scripting' started by Eliotz, Jun 5, 2016.

  1. Eliotz

    Eliotz

    Joined:
    Jul 18, 2015
    Posts:
    81
    Hey guys! I have script here that is supposed to swap weapons when player presses some key and weapons that are not being used will be placed in their "resting positions" like on a back for example.

    Basically the problem appears when I try to set my objects back to active when they are about to be used in EquipWeapon() function, but for some reason it just won't and that's basically it, I tried a bunch of stuff and it didn't work and now I'm confused.

    I had the script working for a while until I realized that I can't use the Instantiate / Destroy way of approaching this, not because of performance, but because I have stuff like reloading will be almost useless if try to use Instantiate / Destroy. (Because you could just quickly swap to other gun and then back to previous gun to basically skip the whole reloading process).

    So now I use a method similar to object pooling so have more control over the behaviour of how my weapons work.

    Anyways, here is the code:

    To be clear, Weapon is a script attached to the actual weapon gameObject so I don't have to search for it every time I have to access it. It doesn't make a whole lot of difference but for me it's a little easier this way

    And WeaponStats is a class which as the name suggests holds the stats for the weapons(like - fireRate, damage, accuracy ... etc.) and the weapon itself.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class GunController : MonoBehaviour {
    6.  
    7.     public Transform hands;
    8.     public Transform[] holsters = new Transform[4];
    9.  
    10.     public List<WeaponStats> weapons = new List<WeaponStats>();
    11.  
    12.     WeaponStats ActiveWeapon;
    13.     int weaponOrder = 0;
    14.  
    15.     Weapon[] weaponsInRest = new Weapon[4];
    16.     Weapon gunInHands;
    17.  
    18.     float fireRate;
    19.     float damage;
    20.     float velocity;
    21.     float accuracy;
    22.     float range;
    23.  
    24.     //Sets the starting weapon
    25.     void Start()
    26.     {
    27.         EquipWeapon();
    28.     }
    29.  
    30.     //Assigns weapons to their slots
    31.     public void WeaponSupplier(WeaponStats _primaryStats, WeaponStats _secondaryStats, WeaponStats _tirtiaryStats, WeaponStats _quaternaryStats)
    32.     {
    33.         Weapon primaryWeapon = (Weapon)Instantiate(_primaryStats.weapon, Vector3.zero, Quaternion.identity);
    34.         primaryWeapon.gameObject.SetActive(false);
    35.         weapons.Add(_primaryStats);
    36.  
    37.         Weapon secondaryWeapon = (Weapon)Instantiate(_secondaryStats.weapon, Vector3.zero, Quaternion.identity);
    38.         secondaryWeapon.gameObject.SetActive(false);
    39.         weapons.Add(_secondaryStats);
    40.  
    41.         if (_tirtiaryStats != null)
    42.         {
    43.             Weapon tirtiaryWeapon = (Weapon)Instantiate(_tirtiaryStats.weapon, Vector3.zero, Quaternion.identity);
    44.             tirtiaryWeapon.gameObject.SetActive(false);
    45.             weapons.Add(_tirtiaryStats);
    46.         }
    47.         if (_quaternaryStats != null)
    48.         {
    49.             Weapon quaternaryWeapon = (Weapon)Instantiate(_quaternaryStats.weapon, Vector3.zero, Quaternion.identity);
    50.             quaternaryWeapon.gameObject.SetActive(false);
    51.             weapons.Add(_quaternaryStats);
    52.         }
    53.         ActiveWeapon = weapons[0];
    54.     }
    55.     //Equips the weapon
    56.     void EquipWeapon ()
    57.     {
    58.         for (int i = 0; i < weapons.Count; i++)
    59.         {
    60.             if (i != weaponOrder && weapons[i] != null) {
    61.                 weaponsInRest[i] = weapons[i].weapon;
    62.                 weaponsInRest[i].gameObject.SetActive(true);
    63.                 weaponsInRest[i].transform.position = holsters[i].position;
    64.                 weaponsInRest[i].transform.rotation = holsters[i].rotation;
    65.                 weaponsInRest[i].transform.parent = holsters[i].transform;
    66.                 Debug.Log(weaponsInRest[i]);
    67.             }
    68.             if (ActiveWeapon != null)
    69.             {
    70.                 Debug.Log(ActiveWeapon);
    71.                 gunInHands = ActiveWeapon.weapon;
    72.                 gunInHands.gameObject.SetActive(true);
    73.                 gunInHands.transform.position = hands.transform.position;
    74.                 gunInHands.transform.rotation = hands.transform.rotation;
    75.                 gunInHands.transform.parent = hands;
    76.                 gunInHands.Magazine(30);
    77.             }
    78.         }
    79.     }
    80.     void Update()
    81.     {
    82.         switch (Input.inputString)
    83.         {
    84.             case "1":
    85.                 weaponOrder = 0;
    86.                 ActiveWeapon = weapons[weaponOrder];
    87.                 EquipWeapon();
    88.                 break;
    89.             case "2":
    90.                 weaponOrder = 1;
    91.                 ActiveWeapon = weapons[weaponOrder];
    92.                 EquipWeapon();
    93.                 break;
    94.             case "3":
    95.                 if (weapons.Count >= 3)
    96.                 {
    97.                     weaponOrder = 2;
    98.                     ActiveWeapon = weapons[weaponOrder];
    99.                     EquipWeapon();
    100.                 }
    101.                 break;
    102.             case "4":
    103.                 if (weapons.Count == 4)
    104.                 {
    105.                     weaponOrder = 3;
    106.                     ActiveWeapon = weapons[weaponOrder];
    107.                     EquipWeapon();
    108.                 }
    109.                 break;
    110.             case "e":
    111.                 weaponOrder++;
    112.                 if(weaponOrder > weapons.Count - 1)
    113.                 {
    114.                     weaponOrder = 0;
    115.                 }
    116.                 ActiveWeapon = weapons[weaponOrder];
    117.                 EquipWeapon();
    118.                 break;
    119.             case "q":
    120.                 weaponOrder--;
    121.                 if (weaponOrder < 0)
    122.                 {
    123.                     weaponOrder = weapons.Count -1;
    124.                     Debug.Log(weaponOrder);
    125.                 }
    126.                 ActiveWeapon = weapons[weaponOrder];
    127.                 EquipWeapon();
    128.                 break;
    129.         }
    130.         //Sets the fire mode for the weapon
    131.         if (ActiveWeapon != null) {
    132.             switch (ActiveWeapon.weapon.type)
    133.             {
    134.                 case "Pistol":
    135.                     if (Input.GetMouseButtonDown(0))
    136.                     {
    137.                         Fire();
    138.                     }
    139.                     break;
    140.                 case "Rifle":
    141.                     if (Input.GetMouseButton(0))
    142.                     {
    143.                         Fire();
    144.                     }
    145.                     break;
    146.             }
    147.         }
    148.     }
    149.     void Fire()
    150.     {
    151.         gunInHands.Fire(ActiveWeapon.fireRate, ActiveWeapon.damage, ActiveWeapon.velocity);
    152.     }
    153. }
    154.  
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    Where is WeaponSupplier being called?
     
  3. Eliotz

    Eliotz

    Joined:
    Jul 18, 2015
    Posts:
    81
    WeaponSupplier() is called from another script - WeaponLibary.cs which finds out what are the stats for each weapon and then sends them to WeaponSupplier().

    WeaponSupplier() works completely fine you can also see that I tried to Debug.Log the weaponsInRest which is a type of Weapon and it never shows that its null.

    Like literary everything works except the SetActive part.

    Here is the WeaponLibary for everyone else to check that it actually works:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class WeaponLibary : MonoBehaviour {
    6.  
    7.  
    8.     //Variables
    9.     public Weapon[] WeaponSlots = new Weapon[4];
    10.  
    11.     WeaponStats[] wepStats = new WeaponStats[4];
    12.     GunController cg;
    13.     List<Weapon> avalibleWeapons = new List<Weapon>();
    14.  
    15.     Weapon weapon;
    16.     //Assigns the stats for the weapons in the slots
    17.     void Start()
    18.     {
    19.         cg = GameObject.FindGameObjectWithTag("Player").GetComponent<GunController>();
    20.         for(int i = 0; i < WeaponSlots.Length; i++)
    21.         {
    22.             if (WeaponSlots[i] != null)
    23.             {
    24.                 avalibleWeapons.Add(WeaponSlots[i]);
    25.             }
    26.         }
    27.         Libary();
    28.     }
    29.     //Figures out what stats does the weapons in the Slots have
    30.     void Libary()
    31.     {
    32.         for (int i = 0; i < avalibleWeapons.Count ; i++)
    33.         {
    34.             switch (avalibleWeapons[i].id)
    35.             {
    36.                 case "Pistol":
    37.                     wepStats[i] = new WeaponStats(avalibleWeapons[i], 160, 5, 20, 10, 10);
    38.                     break;
    39.                 case "RifleYellow":
    40.                     wepStats[i] = new WeaponStats(avalibleWeapons[i], 125, 10, 45, 12, 30);
    41.                     break;
    42.                 case "RifleGreen":
    43.                     wepStats[i] = new WeaponStats(avalibleWeapons[i], 75, 13, 35, 7, 10);
    44.                     break;
    45.                 case "RifleRed":
    46.                     wepStats[i] = new WeaponStats(avalibleWeapons[i], 60, 3, 30, 7, 15);
    47.                     break;
    48.             }
    49.         }
    50.         AssignWeapons(wepStats[0], wepStats[1], wepStats[2], wepStats[3]);
    51.     }
    52.     //Passes all the weapons with their stats to GunController
    53.     void AssignWeapons(WeaponStats wStats1, WeaponStats wStats2, WeaponStats wStats3, WeaponStats wStats4)
    54.     {
    55.         cg.WeaponSupplier(wStats1, wStats2, wStats3, wStats4);
    56.     }
    57. }
     
  4. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    Is it the behavior in Start() you are observing or while running, because i see you calling EquipWeapon() there? Then you refer to another gameobject within it. You need to be sure that the Start() of another script is activated before that, otherwise all gameobject references may be null. Same if you just switched scene they would be null. You can change script execution order from the top menus.
     
  5. Eliotz

    Eliotz

    Joined:
    Jul 18, 2015
    Posts:
    81
    Yeah I was gonna fix that, but my script worked fine when when I call EquipWeapon() from start. And It always worked fine because, I have made it so WeaponLibary will be always called before gunController. So once again - the guns are never null and you can actually see them in my hierarchy. Because you reminded me I did move EquipWeapon() as the last line in WeaponSuppiler() function and removed the start function and as you may guess.... Nothing happened, everything is the same.

    So far none of you have commented on the EquipWeapon() function which is where the actual problem exists, because my guess so far is that everything in EquipWeapon() written correctly, but for some reason unity just ignores that. 2016-06-06_1418.png
     
  6. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    More info needed. What does the debug say and what should it say?
    Print also these after you used SetActive
    Code (CSharp):
    1. Debug.Log(gunInHands.gameObject.activeInHierachy);
    2. Debug.Log(gunInHands.gameObject.activeSelf);
    A few typo words that would correct to: "tertiary", "available", "library".

    I too had some bugs with SetActive, but i tried to replicate that in new project and it worked without issues. If there is a bug i don't know how to reproduce reliably.
     
  7. Eliotz

    Eliotz

    Joined:
    Jul 18, 2015
    Posts:
    81
    Ok so I added the - Debug.Log(gunInHands.gameObject.activeSelf); line under the line where is set the gunInHands gameObject to active, the other line (the activeInHierarchy one) gave me a compiler error so I couldn't get it working, but I hope that this gives enough information.

    Console printed out "true" though, so does it mean that unity thinks that the objects are active when they are actually not or something like that?

    Those errors come from the line where I try to set the gunInHands parent to one of the "resting positions" or holsters as I like to call em.

    Also I noticed that when I manually activate the inactive guns in the inspector (while the game is running of course) their position didn't change, but the code sets all their position and rotation to match the holsters transform.

    Really I feel like nothing but the debug.Logs in EquipWeapon() function are working XD.

    Here is my console: Console.png
     
  8. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Those error messages would lead me to believe that you have your weapons set to a prefab in your project and not to the actual instance in the scene.
     
  9. Eliotz

    Eliotz

    Joined:
    Jul 18, 2015
    Posts:
    81
    Yeah but how are they not instances if you can actually see in the hierarchy (which I posted couple replies back) that they are indeed clones and in the code I'm trying to set the parent to those cloned objects or INSTANCES.
     
  10. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I see them in the scene hierarchy - doesn't mean that's what you have stuff assigned to in the Inspector. It looks like ActiveWeapon is assigned from the weapons list. How are you populating that list?
     
  11. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class GunController : MonoBehaviour {
    6.  
    7.    //Assigns weapons to their slots
    8.     public void WeaponSupplier(WeaponStats _primaryStats, WeaponStats _secondaryStats, WeaponStats _tirtiaryStats, WeaponStats _quaternaryStats)
    9.     {
    10.         Weapon primaryWeapon = (Weapon)Instantiate(_primaryStats.weapon, Vector3.zero, Quaternion.identity);
    11.         primaryWeapon.gameObject.SetActive(false);
    12.         weapons.Add(_primaryStats);
    13.  
    14.         Weapon secondaryWeapon = (Weapon)Instantiate(_secondaryStats.weapon, Vector3.zero, Quaternion.identity);
    15.         secondaryWeapon.gameObject.SetActive(false);
    16.         weapons.Add(_secondaryStats);
    17.  
    18.     //Equips the weapon
    19.     void EquipWeapon ()
    20.     {
    21.         for (int i = 0; i < weapons.Count; i++)
    22.         {
    23.             if (i != weaponOrder && weapons[i] != null) {
    24.                 weaponsInRest[i] = weapons[i].weapon;
    25.                 weaponsInRest[i].gameObject.SetActive(true);
    26.                 weaponsInRest[i].transform.position = holsters[i].position;
    27.                 weaponsInRest[i].transform.rotation = holsters[i].rotation;
    28.                 weaponsInRest[i].transform.parent = holsters[i].transform;
    29.                 Debug.Log(weaponsInRest[i]);
    30.             }
    31.             if (ActiveWeapon != null)
    32.             {
    33.                 Debug.Log(ActiveWeapon);
    34.                 gunInHands = ActiveWeapon.weapon;
    35.                 gunInHands.gameObject.SetActive(true);
    36.                 gunInHands.transform.position = hands.transform.position;
    37.                 gunInHands.transform.rotation = hands.transform.rotation;
    38.                 gunInHands.transform.parent = hands;
    39.                 gunInHands.Magazine(30);
    40.             }
    41.         }
    42.     }
    43.  
    44.  
    [/QUOTE]

    Ok, I think I see the problem. You are creating an instance called primaryWeapon based on most likely a prefab called _primaryStats.weapon. Then you are turning the instance off. However, you are adding _primaryStats to your list.

    Then later, you are assigning the weapons.weapon to the weaponsInRest and trying to set that active, which means you aren't targetting your instance, but targetting a prefab.
     
  12. Eliotz

    Eliotz

    Joined:
    Jul 18, 2015
    Posts:
    81
    OMG Barthnann you are the god, thanks you for your perfect eyes! Fixed the code and everything works again!

    It takes too long to explain what I did, so I ill just post the code. Most changes are in WeaponSupplier() funciton.

    Code (CSharp):
    1.     public void WeaponSupplier(WeaponStats _primaryStats, WeaponStats _secondaryStats, WeaponStats _tirtiaryStats, WeaponStats _quaternaryStats)
    2.     {
    3.         Weapon primaryWeapon = (Weapon)Instantiate(_primaryStats.weapon, Vector3.zero, Quaternion.identity);
    4.         _primaryStats.weapon = primaryWeapon;
    5.         weapons.Add(_primaryStats);
    6.  
    7.         Weapon secondaryWeapon = (Weapon)Instantiate(_secondaryStats.weapon, Vector3.zero, Quaternion.identity);
    8.         _secondaryStats.weapon = secondaryWeapon;
    9.         weapons.Add(_secondaryStats);
    10.  
    11.         if (_tirtiaryStats != null)
    12.         {
    13.             Weapon tirtiaryWeapon = (Weapon)Instantiate(_tirtiaryStats.weapon, Vector3.zero, Quaternion.identity);
    14.             _tirtiaryStats.weapon = tirtiaryWeapon;
    15.             weapons.Add(_tirtiaryStats);
    16.         }
    17.         if (_quaternaryStats != null)
    18.         {
    19.             Weapon quaternaryWeapon = (Weapon)Instantiate(_quaternaryStats.weapon, Vector3.zero, Quaternion.identity);
    20.             _quaternaryStats.weapon = quaternaryWeapon;
    21.             weapons.Add(_quaternaryStats);
    22.         }
    23.         ActiveWeapon = weapons[0];
    24.         EquipWeapon();
    25.     }
    26.     //Equips the weapon
    27.     void EquipWeapon ()
    28.     {
    29.         for (int i = 0; i < weapons.Count; i++)
    30.         {
    31.             if (i != weaponOrder && weapons[i] != null) {
    32.                 weaponsInRest[i] = weapons[i].weapon;
    33.                 Debug.Log(weaponsInRest[i].gameObject.activeSelf);
    34.  
    35.                 weaponsInRest[i].transform.position = holsters[i].position;
    36.                 weaponsInRest[i].transform.rotation = holsters[i].rotation;
    37.                 weaponsInRest[i].transform.parent = holsters[i].transform;
    38.               //  Debug.Log(weaponsInRest[i]);
    39.             }
    40.             if (ActiveWeapon != null)
    41.             {
    42.                 gunInHands = ActiveWeapon.weapon;
    43.                 gunInHands.gameObject.SetActive(true);
    44.                 gunInHands.transform.position = hands.transform.position;
    45.                 gunInHands.transform.rotation = hands.transform.rotation;
    46.                 gunInHands.transform.parent = hands;
    47.                 gunInHands.Magazine(30);
    48.             }
    49.         }
    50.     }
     
  13. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    Glad I could help. Thanks should also go to Zaflis for suggesting the debugs and KelsoMRK for confirming the error message was targeting a prefab. I just happen to take a closer look at your instantiate to figure out what you were trying to turn on.
     
  14. Eliotz

    Eliotz

    Joined:
    Jul 18, 2015
    Posts:
    81
    Teamwork baby!