- Home /
Instantiate prefab and Add to a Generic List
I have a simple script attached to a projectile shot from a weapon. The projectile fires a raycast out in front of itself and when the raycast hits something, a bullet hole prefab is instantiated at the hit point of the collision.
What I would like to do next is add this bullet hole prefab to a generic list I have in a script (impactDecalsList) attached to a separate gameobject (impactDecalsContainer). But before I add it I need to check whether the list is bigger than a certain max length/size; if it isn't I add it, if it is I want to use RemoveAt on the first object in the list and destroy it. Here is my script:
var impactDecalsContainer : GameObject;
var impactDecalsList : ImpactDecalsList;
var bulletHoleGeneral : GameObject;
var offsetFromSurface : float = 0.001;
var raycastDistance : float = 1;
function Start () {
impactDecalsList = impactDecalsContainer.GetComponent("ImpactDecalsList");
}
function Update () {
var hit : RaycastHit;
//Shoot a ray infront of the bullet/rocket, check it's tag on impact and instantiate the relevant decal
//Parent the decal prefab instance to the object it hit
Debug.DrawRay(transform.position, transform.forward * raycastDistance, Color.red);
if (Physics.Raycast (transform.position, transform.forward, hit, raycastDistance)) {
if (hit.transform.CompareTag ("Environment")) {
var mybullet : GameObject;
myBullet = Instantiate (bulletHoleGeneral, hit.point + (hit.normal * offsetFromSurface), Quaternion.LookRotation(hit.normal));
myBullet.transform.parent = hit.transform;
//Check the length of the list, if it's too big remove and destroy the first item in the list
//Otherwise add myBullet to the list
/*if (impactDecalsList.allImpactDecals.Count >
impactDecalsList.maxListSize) {
impactDecalsList.allImpactDecals.RemoveAt(1);
//Destroy(impactDecalsList(0));
}
else {*/
impactDecalsList.allImpactDecals.Add(myBullet);
//}
}
}
}
And here is the script (impactDecalsList) from the impactDecalsContainer gameobject:
import System.Collections.Generic;
var allImpactDecals = new List.<GameObject>();
var maxListSize : float = 40;
function Start () {
}
function Update () {
}
Unfortunately though when the projectile hits I am getting a: NullReferenceException: Object reference not set to an instance of an object, on line 28 of the code. I've tried referencing the other gameobject in a few different ways but I always get this same error. I've also read through the many Array Add/Remove questions but I haven't found one which deals with accessing a generic list in another gameobject. Any ideas what I'm doing wrong?
Here is the Unity Package: Simple Version 8.5MB
Plenty of bullets, but the list is still at size 0. Why?
ok, your referencing .allDecalsList, which doesn't exist in component, makes sure impactDecalsList is its correct type.
Thanks for your help, I've updated the script above and added the script of the impactDecalsList (the component on the impactDecalsContainer gameobject). I'm still getting the same error on the same line though. Is that what you meant or am I still doing something wrong?
Answer by Fornoreason1000 · Apr 30, 2013 at 09:42 AM
there are many things that could be going wrong here for example: impactDecalsContainer is null;
making impactDecalsList null; remember your using a List, not an array.
I've managed to duplicate you error and allImpactDecals.Length is returning null, that's the problem. Null Reference means something is Null and your trying to do something with it when you obviously can't. (I don't recall Length being in List it used it be Count, maybes its a Mono thing).
anyway... when using Count instead of length, the Null ref up and leaves. why it didnt call a "No method" error instead is new to me.
impactDecalsList.allImpactDecals.Count // returns number of items
heres an insight on List, its all in C#,C++ and VB but you get the idea http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx#inheritanceContinued
You're right "Length" was wrong, changing it to "Count" fixed the error. Thanks so much! I normally only use arrays which is where the error came from. I have two questions:
1) Is there any information about Generic Lists available in the Unity docs, because I can only found it on arrays?
2) The prefab instance "myBullet" isn't getting added into the list, but the list size increases in size as per the maxListSize variable in the impactDecalsList script. Am I not adding it correctly? I tried commenting out the if check for the count (see above) as well but it still doesn't add it.
there are mono docs (unity uses mono), but unity never mention generics at all, Generics bar http://docs.unity3d.com/Documentation/$$anonymous$$anual/GenericFunctions.html which as little to do with List.
I need a little more detail on the inspector, does my bullet appear in the inspector? does it appear blank?. also I believe generic are zero indexed. so your removing the second element not the first.
Ok sure, "myBullet" is the variable name declared at line 21 when instantiating an instance of the "bulletHoleGeneral" prefab, at line 22. So no it does not actually appear in the inspector so I cannot check it that way. I think the problem is at line 34:
impactDecalsList.allImpactDecals.Add(myBullet);
This is the line where I try to add the instantiated gameobject into the list, but I must have the syntax wrong because it doesn't add it. The list "impactDecalsList" simply stays at size 0 during runtime when it should be adding each newly instantiated object.
the syntax is perfect, it adds in $$anonymous$$e when i use this
var weapon : GameObject;
function Update() {
impactDecalsList = gameObject.GetComponent("SomethingAswell");
if (Input.Get$$anonymous$$ey("e")) {
var hit : RaycastHit;
var myBullet : GameObject;
myBullet = Instantiate (weapon, hit.point + (hit.normal * .1), Quaternion.LookRotation(hit.normal));
myBullet.transform.parent = hit.transform;
//Check the length of the list, if it's too big remove and destroy the first item in the list
//Otherwise add myBullet to the list
/*if (impactDecalsList.allImpactDecals.Count >
impactDecalsList.maxListSize) {
impactDecalsList.allImpactDecals.RemoveAt(1);
//Destroy(impactDecalsList(0));
}
else {*/
impactDecalsList.allImpactDecals.Add(myBullet);
//}
}
}
import System.Collections.Generic;
var allImpactDecals = new List.<GameObject>();
var maxListSize : float = 40;
function Start () {
}
function Update () {
}
make sure bulletHoleGeneral is assigned? if so is this line being called?
if (Physics.Raycast (transform.position, transform.forward, hit, raycastDistance)) {
if (hit.transform.CompareTag ("Environment")) {
That's really strange then. The bulletHoleGeneral is definitely assigned and at runtime the list variable, impactDecalsList, gets assigned as well as it's visible in the inspector. I'm quite sure the raycast is working also because it alone checks the tag of each object before instantiating the bullet hole on it, and it only instantiates when I actually hit objects with the required tag. Really not sure what I'm doing wrong.
If you wouldn't $$anonymous$$d, I've exported a simplified version of my scene into a unity package. Could you possibly have a look at it and let me know why it's not working for me? I've put a link at the bottom of the original question. The package is about 8.5 mb, that's the smallest I could make it.
Answer by delVhar · Apr 30, 2013 at 09:42 AM
This could be caused by the execution order of the scripts. Try making the impactDecalsList script a higher priority in the execution order. (http://docs.unity3d.com/Documentation/Components/class-ScriptExecution.html)
The other possibility is that impactDecalsList is never actually getting set correctly, can you see its value change to the correct object when rinning in the editor? Make sure impactDecalsContainer is set to the right GameObject.
Thank you for you help, yes I had tested both the impactDecalsList and the impactDecalsContainer variables and they are both assigning properly at runtime.
Your answer
Follow this Question
Related Questions
Store Game Object Into List For Later Reinstantiation? 0 Answers
Destroy and rebuild game objects from lists 1 Answer
Destroying a GameObject w/ children isn't properly destroying everything? 1 Answer
A node in a childnode? 1 Answer
Mouse Methods (OnMouseDown, OnMouseOver etc) stop working after certain circumstances 0 Answers