add new item to list/ destroy from scene

hey
trying to add items to my inventory list and destroy them from the scene after player collected them… i thought adding it to a list would make a copy of it, but on destroying it from the scene the GO goes missing in the list…
I could of course do the create prefab thing, but i don’t want to have copies of the items in a folder, they all ready come from one prefab, get tweaked in the inspector and places all over the scene…

code:

#pragma strict
import System.Collections.Generic;

var actionKey: KeyCode;
var rayLenght: int;
private var collect=false;
private var hitObj:GameObject;
private var inventoryScript: inventorySystem;

function Start ()
{
	inventoryScript = gameObject.GetComponent(inventorySystem);
}

function Update () 
{
	var ray = new Ray (transform.position, transform.forward);
	var hit: RaycastHit;
	if(Physics.Raycast(ray, hit, rayLenght))
	{
		if(hit.collider.tag=="collectable")
		{
			collect=true;
			hitObj=hit.collider.gameObject;
		}
	}
	else
	{
		collect=false;
	}
	if(Input.GetKeyDown(actionKey)  hitObj !=null)
	{
		inventoryScript.ItemList.Add(new Items(hitObj));

		Destroy(hitObj);
	}
	
}
function OnGUI()
{
	if(collect)
	{
		GUI.Label(Rect(Screen.width/2-75, Screen.height/2-15, 150,30),GUIContent("press "+actionKey.ToString()+" to collect"));
	}
}

By default the item is added as a reference. Instead of destroying it why not just deactivate it and reinitialize and enable when you need to use it.

hitObj.SetActive( false );

because they would stay all over the scene… Its things like a fire cristal you collect and then get the fire power.

this is the cristals script:

#pragma strict

public enum names {fire=0, water=1, air=2, matter=3}
public enum types {solid=0, liquid=1, gass=2}
public var cristalName:names;
public var type:types=types.solid;
public var effect:GameObject;

function Start () 
{
	gameObject.name+=cristalName;

}

this is the part of my inventory script that defines the List:

public var ItemList:List.<Items>;

public class Items
{
	var Item:GameObject;
	var type:types;
	var effect:GameObject;
	function Items (item:GameObject)
	{
		type=item.GetComponent(cristals).type;
		effect=item.GetComponent(cristals).effect;
		Item=item;
	}
}

everything in the list gets filled, also the ‘effect’ var wich is just a particle system that occupies the effect GameObject var of the cristal script, so it copies the content of a var from the script attached to the gameObject but not the gameObject itself…

I’m getting confused as to whats happening

Ok if you want to copy the object then you need to use Object.Instantiate( original ).

This will create an other GameObject though. It sounds like you want a class to encapsulate your Crystaldata and share that.

E.G

[System.Serializable]
public class CrystalData
{
// Some crystal info
}


public CrystalPickup : Monobehaviour
{
 public CrystalData data = new CrystalData();
}

Now when you get the pickup you take the reference to CrystalData in your list and can safely delete the gameobject.

Even better you can add some inheritance into the mix using ScriptableObject

[System.Serializable]
public class CrystalData :ScriptableObject
{
// Some shared crystal info
}


public class FireCrystal : CrystalData
{
// Fire only stuff
}


public class IceCrystal : CrystalData
{
// ice only stuff
}


public CrystalPickup : Monobehaviour
{
 public CrystalData data; // Use instantiate to create an instance. You may want to add your own GUI component to add different ones.
}

wow karlij that seems exactly what i want thanks, will try it asap! I’m still new to working with these kind of things, but it looks like I’ll learn a lot from your example.
cheers mate!

Glad to help.

This is an example of the GUI component I mentioned:

// put it in a dir called editor
    [MenuItem("CONTEXT/CrystalPickup/Add Fire Crystal")]
    public static void AddFireCrystal( MenuCommand cmd )
    {
        ( cmd.context as CrystalPickup ).data = AddFireCrystal.CreateInstance<FireCrystal>();
    }

Now when you right click on the CrystalPickup instance in the inspector you should get an option called Add Fire Crystal which will set the CrystalData to be an instance of Fire Crystal.

Karl

ok I’ll have to experiment with this until i understand it, so if you don’t mind I’ll keeps asking some questions if i’m stuck.
ah ok and this is all C# i guess, hm i should try and translate it then, or switch but the problem is I’m collaborating with some people who only know a bit JS…

does this make sense?

#pragma strict

public class CrystalData extends ScriptableObject
{
	public enum types {fire=0, water=1, air=2, matter=3}
	public enum category {solid=0, liquid=1, gass=2}
	public enum molecules {H=0, HE=1, Li=2, Be=3, B=4, C=5, N=6, O=7, F=8, Ne=9}
}

public class FireCrystal extends CrystalData
{
	public var crystalType:CrystalData.types=0;
	public var typeCategory:CrystalData.category=2;
	public var components:CrystalData.molecules[];
}

public class WaterCrystal extends CrystalData
{
	public var crystalType:CrystalData.types=1;
	public var typeCategory:CrystalData.category=1;
	public var components:CrystalData.molecules[];
}

public var data:CrystalData; // Use instantiate to create an instance. You may want to add your own GUI component to add different ones.

You probably want your shared variables such as crystalType to be in your base class and assign them a value in the child classes. That way you can then have a reference to the base class and still examine the type.

E.G

#pragma strict


public class CrystalData extends ScriptableObject
{
    public enum types {fire=0, water=1, air=2, matter=3}
    public enum category {solid=0, liquid=1, gass=2}
    public enum molecules {H=0, HE=1, Li=2, Be=3, B=4, C=5, N=6, O=7, F=8, Ne=9}
    public var crystalType;
    public var typeCategory;
    public var components;
}


public class FireCrystal extends CrystalData
{
    void OnEnable()
    {
        crystalType = 0;
        typeCategory = 0;        
    }
}


public class WaterCrystal extends CrystalData
{
    void OnEnable()
    {
        crystalType = 1;
        typeCategory = 1;        
    }
}
 


public var data:CrystalData; // Use instantiate to create an instance. You may want to add your own GUI component to add different ones.

k

Ah ok that way, i think i need to find some tutorials about this magic :wink: just learned how to use a class to store data in a list a couple of weeks ago, actually i should just go and follow a orogramming course :smiley: if i had the time.
Again i appriciate your efforts to teach me. I’m a 3d artist normally, so if i can ever return you a favor, lemme know.