Preload to cache and use cached objects (Spawn Enemy)

I set a sphere gameobject as spawn enemy (=spawnEnemyPrefab, added rigidbody). And, there is a resetSpawnEnemy (=resetSpawnEnemy, Transform) empty game object.

I would like to preload it 100 times to cache.

How should I get the cached object and make it move and collide to act?

Here is the script:

SpawnEnemyPool.js

var spawnEnemyPrefab : GameObject;
var resetSpawnEnemy : Transform;
var spawnEnemyCache : int = 100;

private var index : int;
private var spawnEnemyArray : SpawnEnemy[];
private var activeIndex : int = 0;
private var newSpawnEnemy : GameObject;
private var thisSpawnEnemy : GameObject;
private var thisTransform : Transform;

function Start () {
   thisTransform = transform;
   spawnEnemyArray = new SpawnEnemy[spawnEnemyCache];

   for (var index = 0; index < spawnEnemyCache; index++) {
      newSpawnEnemy = Instantiate(spawnEnemyPrefab, resetSpawnEnemy.transform.position, Quaternion.identity);
      spawnEnemyArray[index] = newSpawnEnemy.GetComponent(SpawnEnemy);
      newSpawnEnemy.active = false;
   }
   MoveLoop();
}

function MoveLoop() {
    while(true) {
        Moving();
        yield WaitForSeconds(5);
    }
}

function Moving() {
    spawnEnemyArray[activeIndex].gameObject.active = true;
    spawnEnemyArray[activeIndex].transform.position = thisTransform.position;
    activeIndex = (activeIndex + 1) % 100;
    if(activeIndex >= spawnEnemyCache) {
        activeIndex = 0;
    }
}

public function Recycle(thisSpawnEnemy : SpawnEnemy) {
    thisSpawnEnemy.transform.position = resetSpawnEnemy.transform.position;         
    thisSpawnEnemy.gameObject.active = false; 
}

SpawnEnemy.js

var explosionPrefab : GameObject;
private var thisTransform : Transform;
var spawnEnemyPool : SpawnEnemyPool;

function Awake() {
    thisTransform = transform;
    spawnEnemyPool = gameObject.FindObjectOfType(SpawnEnemyPool);
}

function OnEnable() {
    TimeOutSpawnEnemy();
}

function Update () {    
    spawnEnemyPool.rigidbody.AddForce(transform.forward * 2000, ForceMode.Acceleration); //how to make the cached object move?
}

function TimeOutSpawnEnemy() {
    yield WaitForSeconds(5);
    KillSpawnEnemy();
}

function KillSpawnEnemy() {
    spawnEnemyPool.Recycle(this);
}

function OnCollisionEnter() {
    KillSpawnEnemy();
}

Your code is close…it just looks like you were manipulating the wrong game object:

var explosionPrefab : GameObject;
private var thisTransform : Transform;
var spawnEnemyPool : SpawnEnemyPool;

//  Cache rigidbody component just like you did with
//  Transform:

private var thisRigidbody : Rigidbody;

function Awake() {
    thisTransform = transform;
    thisRigidbody = rigidbody;
    spawnEnemyPool = gameObject.FindObjectOfType(SpawnEnemyPool);
}

function OnEnable() {
    TimeOutSpawnEnemy();
}

// Your update here is pointing at the spawnEnemyPool, which
// probably doesn't even have it's own rigidbody
// Do physics operations in FixedUpdate as below

/*
function Update () {   

spawnEnemyPool.rigidbody.AddForce(transform.forward * 2000, ForceMode.Acceleration); //how to make the cached object move?
}
*/

function FixedUpdate()
{
   thisRigidbody.AddForce(thisTransform.forward * 2000, ForceMode.Acceleration);
}

function TimeOutSpawnEnemy() {
    yield WaitForSeconds(5);
    KillSpawnEnemy();
}

function KillSpawnEnemy() {
    spawnEnemyPool.Recycle(this);
}

function OnCollisionEnter() {
    KillSpawnEnemy();
}

When I play it, it has error:

NullReferenceException: Object reference not set to an instance of an object
SpawnEnemyPool.Moving () (at Assets/Scripts/SpawnEnemyPool.js:32)

But, I did new it in Start()

spawnEnemyArray = new Enemy[spawnEnemyCache]; //is it js enabled?
for (var index = 0; index < spawnEnemyCache; index++) {
      newSpawnEnemy = Instantiate(spawnEnemyPrefab, resetSpawnEnemy.transform.position, Quaternion.identity);
      spawnEnemyArray[index] = newSpawnEnemy.GetComponent(Enemy);
      newSpawnEnemy.active = false;
}

Also, how can I get the cached object and set it start to moving at certain point?

And, how should use

var explosionPrefab : GameObject;

function OnCollisionEnter() {
    KillSpawnEnemy();
}

to make a collider explosion?

The null reference is probably caused by the elements of the array rather than the array itself. You would get this error if the spawnEnemyPrefab variable is not linked correctly from the inspector - it would be worth checking that you have dragged a prefab onto this variable.

I’m not too sure what you mean by a collider explosion. Do you want to throw the colliding object into the air or draw an explosion with particles or something else?

Dear Sir

I finally fixed the error.

Here is the code:

SpawnEnemyPool.js

var spawnEnemyPrefab : GameObject;
var resetSpawnEnemy : Transform;
var spawnEnemyCache : int = 10;

private var index : int;
private var spawnEnemyArray : SpawnEnemy[];
private var activeIndex : int = 0;
private var newSpawnEnemy : GameObject;
private var thisSpawnEnemy : GameObject;
private var thisTransform : Transform;

function Start () {
   thisTransform = transform;
   spawnEnemyArray = new SpawnEnemy[spawnEnemyCache];

   for (var index = 0; index < spawnEnemyCache; index++) {
      newSpawnEnemy = Instantiate(spawnEnemyPrefab, resetSpawnEnemy.transform.position, Quaternion.identity);
      spawnEnemyArray[index] = newSpawnEnemy.GetComponent(SpawnEnemy);
      newSpawnEnemy.active = false;
   }
   MoveLoop();
}

function MoveLoop() {
    while(true) 
    {
        Moving();
        yield WaitForSeconds(3);
    }
}

function Moving() {
    spawnEnemyArray[activeIndex].gameObject.active = true;
    spawnEnemyArray[activeIndex].transform.position = thisTransform.position;
    activeIndex = (activeIndex + 1) % 100;
    if(activeIndex >= spawnEnemyCache) {
        activeIndex = 0;
    }
}

public function Recycle(thisSpawnEnemy : SpawnEnemy) {
    thisSpawnEnemy.transform.position = resetSpawnEnemy.transform.position;         
    thisSpawnEnemy.gameObject.active = false; 
}


SpawnEnemy.js

var force : float = 10; 
var explosionPrefab : GameObject;
private var thisTransform : Transform;
var spawnEnemyPool : SpawnEnemyPool;

private var thisRigidbody : Rigidbody;

function Awake() {
    thisTransform = transform;
    thisRigidbody = rigidbody; 
    spawnEnemyPool = gameObject.FindObjectOfType(SpawnEnemyPool);
}

function OnEnable() {
    TimeOutSpawnEnemy();
}

function Update () {    
    thisRigidbody.rigidbody.AddForce(-transform.forward * force);
}

function TimeOutSpawnEnemy() {
    yield WaitForSeconds(3);
    KillSpawnEnemy();
}

function KillSpawnEnemy() {
    spawnEnemyPool.Recycle(this);
}

function OnCollisionEnter() {
    KillSpawnEnemy();
}

When I run it, it starts in PreloadSpawnEnemy gameobject’s transform.position which is out of screen.

PreloadSpawnEnemy gameobject has SpawnEnemyPool.js, resetSpawn as Transform and a spawnenemy prefabs.

In spawnenemy prefabs, I added the SpawnEnemy.js.

In Moving function,
spawnEnemyArray[activeIndex].transform.position = thisTransform.position;

I expect the spawnenemy prefabs would be loaded in the transform.position of resetSpawnEnemy and then start to move in Update().

newSpawnEnemy = Instantiate(spawnEnemyPrefab, resetSpawnEnemy.transform.position, Quaternion.identity);

However, it did not.

What’s wrong with the code?

ok, I finally fix it by changing:

spawnEnemyArray[activeIndex].transform.position = thisTransform.position;

to:

spawnEnemyArray[activeIndex].transform.position = resetSpawnEnemy.transform.position;

Because thisTransform.position is the PreloadSpawnEnemy position, but not the resetSpawnEnemy position.

I have another question:

I want to apply the same code to bullet, when I press button on screen, it calls Moving function.

function LateUpdate()
{
	if(shootJoystick.IsFingerDown()) 
  	{   	
  		for (var i = 0; i < iPhoneInput.touchCount; ++i) 
        { 
           var touchObj : iPhoneTouch = iPhoneInput.GetTouch(i);      
           if (touchObj.phase == iPhoneTouchPhase.Began) 
           {     	 
           	  var bullet = gameObject.AddComponent(SpawnEnemyPool);
           	  bullet.Shoot();
           	  DestroyImmediate(bullet);
           }
        }            
    } 
}

Error:
‘Moving’ is not a member of ‘UnityEngine.Component’.

How should I call the Moving function of SpawnEnemyPool.js from another script after it loading those objects?

function Moving() {
    spawnEnemyArray[activeIndex].gameObject.active = true;
    spawnEnemyArray[activeIndex].transform.position = resetSpawnEnemy.transform.position; 
    activeIndex = (activeIndex + 1) % 100;
    if(activeIndex >= spawnEnemyCache) {
        activeIndex = 0;
    }
}

Any help?

I fixed the fire bullet:

var bullet : BulletPool;
function Awake()
{
	bullet = gameObject.FindObjectOfType(BulletPool);
}

function LateUpdate()
{
	if(shootJoystick.IsFingerDown()) 
  	{   	
  		for (var i = 0; i < iPhoneInput.touchCount; ++i) 
        { 
           var touchObj : iPhoneTouch = iPhoneInput.GetTouch(i);      
           if (touchObj.phase == iPhoneTouchPhase.Began) 
           {     	 
           	   bullet.Shoot();
           }
        }            
    } 
}

If the character move on z axis, the bullet can be fired forward.

If I move the character move on x axis, e.g. left or right hand sides, the bullet CANNOT fire to the left, right or backward, it will still be fired forward to the top f the screen.

Here is the bullet.js

function Update () 
{    
    thisRigidbody.rigidbody.AddForce(spawnPoint.transform.GetChild(2).forward * 100, ForceMode.Acceleration);
}

The Player has a child called “spawnPoint” which used for the start of the bullet.

The spawnPoint moves 360 degree depends on how you move the direction of the character (player).

I do not understand why the AddForce does not make the bullet move to the direction of the spawnPoint.

Any help?