- Home /
When Object Pooling Bullet Decal Arrays in UnityScript, My code use the original prefabs instead of the instantiated cloned prefabs
fairly new to coding and the unity fourms. im having a problem at the moment and i want to know if anyone can help... im object pooling and array of bullet hole decal gameobjects into an array and instantiating a Random gameobject with a specific pooled amount just to test. When I try to place my decals and set them active my code seems to be using the original prefabs in the Hierarchy. When taken out of the hierarchy, they use nothing at all instead of the pooled clones. here is the code snippet
var shotOrigin:Transform;
var shotDirection:Transform;
var shotDistance:float;
var fireRate:float;
var hit : RaycastHit;
var bulletHoleDecals:GameObject[];
var poolAmount = 2;
var triggerDown:boolean;
var Decals:GameObject[];
var vex:Vector3;
function Start ()
{
var bulletHoleDecals = new Array();
//Debug.Log(bulletHoleDecals.Length);
triggerDown=false;
for(var i = 0;i<poolAmount;i++)
{
var obj:GameObject=GameObject.Instantiate(Decals[Random.Range(0,2)]);
obj.SetActive(false);
bulletHoleDecals.Add(obj);
}
}
function Update ()
{
IsShooting();
Debug.DrawRay(shotOrigin.position,shotOrigin.forward,Color.red);
}
function IsShooting()
{
if(Input.GetAxisRaw("Triggers_360") && triggerDown == false)
{
if(Physics.Raycast(shotOrigin.position,shotOrigin.forward,hit,shotDistance))
{
DrawHoleDecals();
if(hit.collider.tag =="Enemy")
{
}
}
triggerDown=true;
}
if(Input.GetAxisRaw("Triggers_360")==0)
{
triggerDown=false;
}
}
function DrawHoleDecals()
{
for(i = 0; i < bulletHoleDecals.Length;i++)
{
// bulletHoleDecals[i]=
if(!bulletHoleDecals[i]==false)
{
Debug.Log("gotHere");
//Debug.Log("gotHere");
if(Physics.Raycast(shotOrigin.position,shotOrigin.forward,hit,shotDistance))
{
bulletHoleDecals[Random.Range(0,3)].SetActive(true);
bulletHoleDecals[Random.Range(0,3)].transform.position=hit.point;
//(bulletHoleDecals[Random.Range(0,2)],hit.point,Quaternion.FromToRotation(Vector3.up,hit.normal));
bulletHoleDecals[Random.Range(0,3)].transform.rotation=Quaternion.FromToRotation(Vector3.up,hit.normal);
}
break;
}
}
}
Answer by Davon92 · Mar 24, 2015 at 05:38 PM
thanks to NoseKills this is the new and improved script for anyone doing object pooling in unity's javascript along with a short example for raycasting and using decals to make anything from bullets to bloodsplatter appear in your own way the only thing this doesn't do is add a tiny position change to stop z fighting;
var shotOrigin:Transform;
var shotDistance:float;
//var fireRate:float;
var hit : RaycastHit;
var bulletHoleDecals:GameObject[];
var poolAmount:int;
var triggerDown:boolean;
var vex = new Array();
function Start ()
{
//bulletHoleDecals = new Array();
triggerDown=false;
for(var i = 0;i<poolAmount;i++)
{
var obj:GameObject=GameObject.Instantiate(bulletHoleDecals[Random.Range(0,3)]);
obj.SetActive(false);
vex.Add(obj);
}
}
function Update ()
{
IsShooting();
Debug.DrawRay(shotOrigin.position,shotOrigin.forward,Color.red);
}
function IsShooting()
{
if(Input.GetAxisRaw("Triggers_360") && triggerDown == false)
{
if(Physics.Raycast(shotOrigin.position,shotOrigin.forward,hit,shotDistance))
{
DrawHoleDecals();
if(hit.collider.tag =="Enemy")
{
}
}
triggerDown=true;
}
if(Input.GetAxisRaw("Triggers_360")==0)
{
triggerDown=false;
}
}
function DrawHoleDecals()
{
for(i = 0; i < poolAmount;i++)
{
if(!vex[i].activeSelf)
{
if(Physics.Raycast(shotOrigin.position,shotOrigin.forward,hit,shotDistance))
{
vex[i].transform.position=hit.point;
//this can be useful if you want to change which bullets are set active at a given time [Random.Range(0,2)] for var[i].SetActive(true);
vex[i].transform.rotation=Quaternion.FromToRotation(Vector3.up,hit.normal);
vex[i].SetActive(true);
break;
}
}
}
}
You should click the checkmark next to the answer to mark this thread as solved
Answer by NoseKills · Mar 24, 2015 at 02:23 PM
At least your DrawHoleDecals()
has some strange stuff in it.
if(!bulletHoleDecals[i]==false)
If you want to check which decal is not active yet (not used). use
if (!bulletHitDecals[i].activeSelf)
Then just make sure you set them back to inactive or you'll run out of decals quickly or have to create a pool of million decals.
You have an unnecessary "var" in the Start() method.
var bulletHoleDecals = new Array();
this makes it so that the array in Start() is a different one from the one you define in the class and use later in DrawHoleDecals . Make it just
bulletHoleDecals = new GameObject[poolAmount];
....
for(var i = 0;i<poolAmount;i++)
{
var obj:GameObject=GameObject.Instantiate(Decals[Random.Range(0,2)]);
obj.SetActive(false);
bulletHoleDecals[i] = obj;
}
And here...
bulletHoleDecals[Random.Range(0,3)].SetActive(true);
bulletHoleDecals[Random.Range(0,3)].transform.position=hit.point;
//(bulletHoleDecals[Random.Range(0,2)],hit.point,Quaternion.FromToRotation(Vector3.up,hit.normal));
bulletHoleDecals[Random.Range(0,3)].transform.rotation=Quaternion.FromToRotation(Vector3.up,hit.normal);
you take a new random number for each property you change so you might set decal 0 active, move decal 1 to hit.point
and rotate decal 2 to correct orientation.
for(i = 0; i < bulletHoleDecals.Length;i++)
{
if(!bulletHoleDecals[i].activeSelf)
{
if(Physics.Raycast(shotOrigin.position,shotOrigin.forward,hit,shotDistance))
{
bulletHoleDecals[i].SetActive(true);
bulletHoleDecals[i].transform.position=hit.point;
bulletHoleDecals[i].transform.rotation=Quaternion.FromToRotation(Vector3.up,hit.normal);
Thanks you nose kills for your advice. let me try to explain what i was doing and what i had changed.
$$anonymous$$y draw holes decal
if(!bulletHoleDecals[i]==false)
was a test to see what would make the inactive clones turns on. but originally i had it set to
if(!bulletHoleDecals[i].SetActiveInHeirarchy)
which again is suppose to look for any inactive decals and use those.
This is based off of the C# live demonstaration for Object Pooling on the Unity Website.
I've also since changed the BulletHoleDecals from a Random.Range back to just i
bulletHoleDecals[i].SetActive(true);
bulletHoleDecals[i].transform.position=hit.point;
bulletHoleDecals[i].transform.rotation=Quaternion.FromToRotation(Vector3.up,hit.normal);
I want to randomize the decals for better visual feedback, i want it to feel like the bullets are hitting the object differently from each other.As far as how the decals are being Randomly instantiated at start it is fine and to my liking. The fact is that i cant seem to figure out how to call the clones that I instantiated in the start function from the Drawholes() Section.
The way i understand it.
$$anonymous$$y start function immediately sets my temp var obj which stores my decal instantiate to inactive.
$$anonymous$$y bulletHoleDecals.ADD is suppose to add my temp variable to my bulletHoleDecals Array for further use.
that is why i called bulletholedecals[i] it in the DrawHoles()
i don't know what the i is for other than a random value.
Also the bulletholesdecal setup in the start function cant leave the start function which is what i think my problem comes from.
I had to create a new var in the start function in order to make a new Array locking that new array to the start function only.
so I cant call it down in the DrawHoles() like i want to. i can see where it breaks down i just don't know what should be there.
Oh i just spotted you have an unnecessary "var" in the Start() method.
var bulletHoleDecals = new Array();
this makes it so that the array in Start() is a different one from the one you define in the class and use later in DrawHoleDecals
. $$anonymous$$ake it just
bulletHoleDecals = new GameObject[x];
I'll modify my answer
im glad that i now know that that is the issue. but i cannot set it without the var i will get an error stating that i have
a `$$anonymous$$issing$$anonymous$$ethodException: UnityEngine.GameObject[].Add
Boo.Lang.Runtime.DynamicDispatching.$$anonymous$$ethodDispatcherFactory.ProduceExtensionDispatcher ()
Boo.Lang.Runtime.DynamicDispatching.$$anonymous$$ethodDispatcherFactory.Create ()
Boo.Lang.Runtime.RuntimeServices.DoCreate$$anonymous$$ethodDispatcher (System.Object target, System.Type targetType, System.String name, System.Object[] args)
Boo.Lang.Runtime.RuntimeServices.Create$$anonymous$$ethodDispatcher (System.Object target, System.String name, System.Object[] args)
Boo.Lang.Runtime.RuntimeServices+c__AnonStorey15.<>m__9 ()
Boo.Lang.Runtime.DynamicDispatching.DispatcherCache.Get (Boo.Lang.Runtime.DynamicDispatching.Dispatcher$$anonymous$$ey key, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.String cache$$anonymous$$eyName, System.Type[] cache$$anonymous$$eyTypes, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.Object[] args, System.String cache$$anonymous$$eyName, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
Boo.Lang.Runtime.RuntimeServices.Invoke (System.Object target, System.String name, System.Object[] args)
UnityScript.Lang.UnityRuntimeServices.Invoke (System.Object target, System.String name, System.Object[] args, System.Type scriptBaseType)
GunShot.Start () (at Assets/Scripts/GunShot.js:24)
`
and it wont produce any decals
sry i'm having trouble remembering / writing the JavaScript syntax. I'll keep modifying the answer as you find problems :D