Search Unity

Instantiate & Destroy

Discussion in 'Scripting' started by Welly10, Jan 15, 2022.

  1. Welly10

    Welly10

    Joined:
    Aug 13, 2021
    Posts:
    40
    I'm trying to switch between weapons with (1, 2) but I need to destroy the weapon that I'm carrying when one of the two buttons had been pressed
    Code (CSharp):
    1. void Start()
    2.     {
    3.         managerWeapon = GameObject.Find("ManagerWeapon").GetComponent<ManagerWeapon>();
    4.         player = GameObject.Find("Player").GetComponent<PlayerController>();
    5.         primaryWeapon = managerWeapon.weapons[0];
    6.         Instantiate(primaryWeapon, pivotRifle);
    7.     }
    8.  
    9.     void Update()
    10.     {
    11.         ChangeWeapon(indexPerviousWeapon);
    12.     }
    13.  
    14.     public void ChangeWeapon(int weaponIndex)
    15.     {
    16.         indexPerviousWeapon = weaponIndex;
    17.         primaryWeapon = managerWeapon.weapons[0];
    18.         secondaryWeapon = managerWeapon.weapons[1];
    19.        
    20.         if(Input.GetKeyDown(KeyCode.Alpha1))
    21.         {
    22.             Instantiate(primaryWeapon, pivotRifle);
    23.             player.playerAnimator.SetLayerWeight(0, 1f);
    24.         }
    25.  
    26.         if(Input.GetKeyDown(KeyCode.Alpha2))
    27.         {
    28.             Instantiate(secondaryWeapon, pivotGun);
    29.             player.playerAnimator.SetLayerWeight(1, 1f);
    30.         }
    31.     }
    32. }
     
  2. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    You'll want to cache a reference to the current weapon instance so you can destroy it when changing to a new one.

    You'll probably also want to cache the index of the weapon so you can avoid doing anything if the weapon in question is already equipped.

    Code (CSharp):
    1. int currentWeaponIndex = -1;
    2. Weapon currentWeapon = null;
    3.  
    4. void Start()
    5. {
    6.     managerWeapon = GameObject.Find("ManagerWeapon").GetComponent<ManagerWeapon>();
    7.     player = GameObject.Find("Player").GetComponent<PlayerController>();
    8.  
    9.     SetCurrentWeapon(0);
    10. }
    11.  
    12. void Update()
    13. {
    14.     if(Input.GetKeyDown(KeyCode.Alpha1))
    15.     {
    16.         SetCurrentWeapon(0);
    17.     }
    18.     else if(Input.GetKeyDown(KeyCode.Alpha2))
    19.     {
    20.         SetCurrentWeapon(1);
    21.     }
    22. }
    23.  
    24. void SetCurrentWeapon(int weaponIndex)
    25. {
    26.     if(currentWeaponIndex == weaponIndex)
    27.     {
    28.         return;
    29.     }
    30.  
    31.     if(currentWeapon != null)
    32.     {
    33.         Destroy(currentWeapon.gameObject);
    34.     }
    35.  
    36.     currentWeaponIndex = index;
    37.  
    38.     var prefab = GetWeaponPrefab(weaponIndex);
    39.     var parent = GetWeaponParent(weaponIndex);
    40.     currentWeapon = Instantiate(prefab, parent);
    41.  
    42.     int layerIndex = GetAnimatorLayerIndex(weaponIndex);
    43.     player.playerAnimator.SetLayerWeight(layerIndex, 1f);
    44. }
    45.  
    46. Weapon GetWeaponPrefab(int weaponIndex) => managerWeapon.weapons[weaponIndex];
    47.  
    48. Transform GetWeaponParent(int weaponIndex) => weaponIndex == 0 ? pivotRifle : pivotGun;      
    49.  
    50. int GetAnimatorLayerIndex(int weaponIndex) => weaponIndex;
    51.  
     
    Welly10 likes this.
  3. Welly10

    Welly10

    Joined:
    Aug 13, 2021
    Posts:
    40
    Thanks for your reply and your time, First of all I'm still learning and trying to understand the logic behind the code, I understand some of what you told me but I'm still confused from line 36 to the end.
     
  4. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    Ah apologies, I was using some a bit more advanced C# features in my code just to compress everything into a smaller space without thinking about it :p

    The three members at the bottom are just normal methods but using the => syntax so they can be written in a single line. So this:
    Code (CSharp):
    1. int GetAnimatorLayerIndex(int weaponIndex) => weaponIndex;
    Is exactly the same as this:
    Code (CSharp):
    1. int GetAnimatorLayerIndex(int weaponIndex)
    2. {
    3.     return weaponIndex;
    4. }
    Inside the GetWeaponParent method I was also using the ?: operator which is just shorthand for if-else. So this:
    Code (CSharp):
    1. Transform GetWeaponParent(int weaponIndex) => weaponIndex == 0 ? pivotRifle : pivotGun;
    Is exactly the same as this:
    Code (CSharp):
    1. Transform GetWeaponParent(int weaponIndex)
    2. {
    3.     if(weaponIndex == 0)
    4.     {
    5.         return pivotRifle;
    6.     }
    7.     else
    8.     {
    9.         return pivotGun;
    10.     }
    11. }
     
    Welly10 likes this.
  5. Welly10

    Welly10

    Joined:
    Aug 13, 2021
    Posts:
    40
    Thanks a lot for the explanation it helped me a lot, and I think I've got an issue in the manager weapon script as I created the array but didn't sort the weapons in it.. does that make any problem with the manager weapon change script

    the Manager Weapon script is only an empty game object and attached the manager weapon script and created an game object array only..
     
  6. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    Good to hear that clarified things!

    I don't quite understand what you mean about not having sorted the weapons in the array?
     
  7. Welly10

    Welly10

    Joined:
    Aug 13, 2021
    Posts:
    40
    in the weapon script, I only created the game objects array without any other things
    Code (CSharp):
    1. public class ManagerWeapon : MonoBehaviour
    2. {
    3.     public GameObject[] weapons;
    4.    
    5.     void Start()
    6.     {
    7.        
    8.     }
    9.  
     
  8. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    Yeah you can just use a plain GameObject array instead of a Weapon array just as well.

    Just change
    Weapon currentWeapon
    into
    GameObject currentWeapon

    and
    Destroy(currentWeapon.gameObject)
    into
    Destroy(currentWeapon)
    .
     
    Welly10 likes this.
  9. Welly10

    Welly10

    Joined:
    Aug 13, 2021
    Posts:
    40
    Thank you a lot you explained a lot to me and enlighten me with a lot of new ways on how to approach things like that
    I've only one question ?
    currentWeapon = index (what does index refer to here)
    Code (CSharp):
    1.  
    2.     currentWeaponIndex = index;
    3.     var prefab = GetWeaponPrefab(weaponIndex);
    4.     var parent = GetWeaponParent(weaponIndex);
    5.     currentWeapon = Instantiate(prefab, parent);
     
    SisusCo likes this.
  10. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    Sorry that was an error on my part, it's supposed to be
    currentWeaponIndex = weaponIndex;
    .
     
    Welly10 likes this.
  11. Welly10

    Welly10

    Joined:
    Aug 13, 2021
    Posts:
    40
    Again Thank you a lot you helped me and explained a lot of things highly appreciated
     
  12. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    Awesome, I'm glad I was able to help :) Happy coding!