#I've got trouble with my weapon swap

1 messages · Page 1 of 1 (latest)

near radish
#

the way i want it to work is the following , my player has a grenadelauncher with 3/6 bullets , next to him is an item spawner with a rocket launcher with 2/2 bullets , i want the players item to go in the item spawner and the item inside the item spawner to go inside the player hand , this is the code for equiping that i currently have:

private void OnTriggerStay2D(Collider2D collision)
    {
        if (collision.GetComponent<ItemSpawner>() == null) { return; }

        if (hasinteracted) 
        {
            if (equippedweapon == null)
            {
                //EQUIP
                if (collision.GetComponent<ItemSpawner>().spawneditem != null)
                {
                    Destroy(equippedweapon);
                    equippedweapon = Instantiate(collision.GetComponent<ItemSpawner>().spawneditem, weaponholdpoint);
                }

                collision.GetComponent<ItemSpawner>().RemoveItem();
            }
            else 
            {   
                //SWAP
                if (collision.GetComponent<ItemSpawner>().spawneditem != null)
                {
                    
                    auxweapon = collision.GetComponent<ItemSpawner>().spawneditem;

                    Destroy(equippedweapon);
                    equippedweapon = Instantiate(collision.GetComponent<ItemSpawner>().spawneditem, weaponholdpoint);

                    collision.GetComponent<ItemSpawner>().spawneditem = auxweapon;
                }
            }

        }
    }
#

also here is the code for my item spawner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemSpawner : MonoBehaviour
{
    public SpriteRenderer itemspawnsprite;

    public GameObject[] itemtospawnlist;
    public GameObject spawneditem;

    public float timetospawn=0,timebetweenspawns=10;

    // Update is called once per frame
    void Update()
    {
        if (spawneditem == null)  
        {
            if(timetospawn < timebetweenspawns)
            {
                timetospawn += Time.deltaTime;
            }
            else 
            {
                Spawnitem();
                timetospawn = 0;
            }
        }
        
        if (Input.GetKeyDown(KeyCode.O)) { Spawnitem(); } ;
    }

    //[SerializeField] GameObject[] spawneditemammoview; //just to se the random projectiles inside the gun 
    

    public void Spawnitem() 
    {
        int randomitemindex = Random.Range(0, itemtospawnlist.Length); //random gun prefab from list

        spawneditem = itemtospawnlist[randomitemindex];

        spawneditem.GetComponent<Gun>().GenerateAllRandomAmmo();

        //spawneditemammoview = spawneditem.GetComponent<Gun>().projectile;//delete after only to see bullets

        AsignTexture();
        
    }

    public void RemoveItem()
    {
        itemspawnsprite.sprite = null;
        spawneditem = null;
    }
    public void AsignTexture() 
    {
        if (spawneditem.GetComponent<HandThrow>() != null)
        {
            itemspawnsprite.sprite = spawneditem.GetComponent<HandThrow>().projectile[0].GetComponent<SpriteRenderer>().sprite;
            itemspawnsprite.color = spawneditem.GetComponent<HandThrow>().projectile[0].GetComponent<SpriteRenderer>().color;
        }
        else 
        {
            itemspawnsprite.sprite = spawneditem.GetComponent<SpriteRenderer>().sprite;
            itemspawnsprite.color = spawneditem.GetComponent<SpriteRenderer>().color;
        }
    }
}
golden geyser
#

so actually, you just need to change child GameObjects of both parents

near radish
#

how do i do that ? the thing i tried instantiates multiple weapons on my player and stuff

#

also , the item spawner dosen't have any child gameobjects , the gameobject in only described in code

golden geyser
#
private GameObject parent;
private GameObject child;

child.transform.SetParent(parent.transform);
golden geyser
#

so

near radish
#

the item spawner dosen't instantiate anything

#

it only selects items from a prefab list randomly

golden geyser
#

you have GameObject and their children
you need to delete all children and Instantiate them as another GameObject's (ItemSpawner) children?

near radish
#

and when the player presses E then the brefab gets instantiated to the players holdpoint and the item gets removed from spawner

#

what i was saying is that the item spawner never has children

golden geyser
near radish
#

no

#

as i said it only has a gameobject field wich holds the prefab

golden geyser
#

are they just like this?

public GameObject newPrefab; // random prefab
near radish
#

pretty much

golden geyser
#

so you should just Instantiate prefab that you have as player's child?

#

np then ???

#

Instantiate has a few overloads

near radish
#

my player has an instantiated gameobject attached to him but the item spawner dosen't , so idk how that works

golden geyser
#

you do not know how to get prefab from script?

#

or what?

near radish
#

i tried doing the following

gameobject auxweapon;
auxweapon = equippedweapon;

equippedweapon = weaponfromspawner;

weaponfromspawner = auxweapon;
#

but it dosen't work

golden geyser
#

idk what you need to do

#

You have ItemSpawner.cs. You need to get public GameObject from that script.
Then Instantiate this GameObject as player's child

near radish
#
{
Gameobject auxweapon;
auxweapon = collision.GetComponent<ItemSpawner>().spawneditem;

equippedweapon = Instantiate(collision.GetComponent<ItemSpawner>().spawneditem, weaponholdpoint);

collision.GetComponent<ItemSpawner>().spawneditem = auxweapon;
}
#

idk why it dosent do the collor thing , the formatting i mean

golden geyser
#

are yousure that your auxweapon is not null?

near radish
#

it isn't but this happens whenever i try to swap (look in the hierachy)

golden geyser
near radish
#

ok so ill add destroy.gameobject

golden geyser
#

so you spawn your prefabs all childs, then

#

what is the problem?

near radish
#

on the player yes , they get spawned as childs

golden geyser
#

yes

near radish
#

the problem is that idk how to do the weapon swap correctly , i want to swap the item from the player with the item from the item spawner

#

that is all that i am trying to do

golden geyser
#

no problem then ??

near radish
#

this is the code with the destroy weapon added , the duping stopped but the item swap is still not working

 if (collision.GetComponent<ItemSpawner>().spawneditem != null)
                {
                    
                    auxweapon = collision.GetComponent<ItemSpawner>().spawneditem;

                    Destroy(equippedweapon);
                    equippedweapon = Instantiate(collision.GetComponent<ItemSpawner>().spawneditem, weaponholdpoint);

                    collision.GetComponent<ItemSpawner>().spawneditem = auxweapon;
                }
golden geyser
#
private GameObject player;
private GameObject itemSpawner;

// change the index of the child you need to get
private GameObject playerWeapon = player.transform.GetChild(0); // first child
private GameObject itemSpawnerWeapon = itemSpawner.transform.GetChild(0); // first child too

Instantiate(itemSpawnerWeapon, player.transform); // spawn itemSpawnerWeapon in player
Instantiate(playerWeapon, itemSpawner.transform); // spawn playerWeapon in itemSpawner

Destroy(playerWeapon); // destroy playerWeapon
Destroy(itemSpawnerWeapon); // destroy itemSpawnerWeapon
near radish
#

my item spawner dosen't have any children , the spawnpoint is just where to display the texture
private GameObject itemSpawnerWeapon = itemSpawner.transform.GetChild(0); // first child too

golden geyser
#

how do you wanna swap the child GameObjects if it does not have children?

#

or what do you wanna swap?

near radish
#

the gameobjects , i want the weapon that the player is holding to go inside the gameobject field that the itemspawner has and the item inside the spawner to get instantiated inside the players hands

#

but i feel that instead of swaping the gameobject i am just refferencing them or something idk

golden geyser
#

ok

#

let me think

#

you have GameObject weaponPrefab in ItemSpawner.cs
after some action this weaponPrefab is child of the player
then weaponPrefab is actually the previous player's child

near radish
#

i am okay with refactoring code if that means improving it , the way i've done the things is like this just because i didn't know better , it's just that idk how to properly do that

golden geyser
#

just almast the same as in my previous answer

near radish
#

so you are saying that first thing , my item spawner should have a child right ? (the child beeing the item i want spawned)

golden geyser
#

I was doing that as I have though it does have a child

near radish
#

oh

golden geyser
#
private GameObject player;
private ItemSpawner itemSpawner; // do smth with this instance

private GameObject playerWeapon = player.transform.GetChild(0); // for example
private GameObject itemSpawnerWeapon = itemSpawner.weaponPrefab; // it can be diff from yours

Instantiate(itemSpawnerWeapon, player.transform);

itemSpawner.weaponPrefab = playerWeapon;

Destroy(playerWeapon);
#

smth like that

near radish
#

i tried goint the instantiate route but the item started following my cursor

#

ininstantiated the gun and it follows the cursor in update

golden geyser
#

what?

#

I didn't understand anything, @near radish

near radish
#

it dosen't matter anymore , i am trying a different aproach , i am trying to make an equip and swap method inside itemspawner

golden geyser
#

ok, pin me when you need help

near radish
#

ok , THX

near radish
#

@golden geyser hello , so I succeded in making the itemswap but the code is very ugly and hard to understand , i also get this error which happens when I use Destroy(spawneditem) which I think happens because spawned item is sometimes a prefab , is there a condition to preventing this error or something ?

   public GameObject Swapitem(GameObject equippedweapon,Transform holdpoint) // very ugly code 
    {
        GameObject auxobject;//create an auxilary object

        auxobject = Instantiate(equippedweapon); // create a copy of the equiped item at a far away position

        equippedweapon = Instantiate(spawneditem, holdpoint); // create a copy of the spawned item and equip it to the player

        Destroy(spawneditem); //destroy previously spawned item wich was = to auxobject to not fill the scene with 1000 gameobjects
        spawneditem = auxobject;//set spawneditem refference to the newly instantiated auxobject

        AsignTexture();
        timetospawn = 0;

        return equippedweapon; //return weapon to be equipped
    }
near radish
#

yes i thank that is what happens , but the item is not always a prefab

golden geyser
#

you should destroy GameObject, not prefab

near radish
#

i get that but spawneditem can be Gameobject and prefab at different times so idk what to do

golden geyser
#
[SerializeField] private GameObject weaponPrefab; // this is prefab in your scene

private void NiceMethod()
{
    GameObject weapon = Instantiate(weaponPrefab); // that's already not prefab

    Destroy(weapon); // no error
}
#

@near radish smth like that

#

you should consider it somewhere in your code

near radish
#

but i am a bit confused because in my code what happens is the following ,cs auxobject = Instantiate(prefab); Destroy(Spawneditem);// which was the previous auxobject and then spawneditem = auxobject

golden geyser
#

@near radish please, try to follow default C# coding convertions

#
auxObject = Instantiate(prefab);

// spawnedItem should not be prefab here, otherwise you destroy GameObject in your Assets
Destroy(spawnedItem);

spawnedItem = auxObject