Way of queuing multiple instantiations?

I have a loop that instantiates objects in objectManagerScript.js, and each object has its own individual meshGeneratorScript.js on it.

At the moment, it instantiates many Mesh generating objects simultaneously and it causes massive slowdowns, I want to pause the loop every time it instantiates one object, and include a line at the end of the instantiated object mesh generator code with sendsmessage.unpause_loop back to instantiation loop script.

it would more sense than WaitForSeconds which doesn’t really work in the given scenario.

can I pause and continue a loop dynamically? how do I queue instantiations until current instantiation mesh is rendered?

Instantiate a pool up front and take items from it....

I had a think about pooling objects, in this scenario max 15 objects have to appear every few seconds... It makes sense to pool objects when they all have mesh, but if its empty objects with scripts that have to destroy and renew the mesh every time the object is moved, it should be perhaps faster to instantiate and destroy the entire object?

There's a lot of reflection going on serializing the components on a game object too... It would be better just to reuse them.

1 Answer

1

There are a lot of ways you can accomplish what you want. I will go over two of them.

Option 1:
Put your loop into a corotuine with this kind of logic (pseudo code):

IEnumerator CreateObjects() {

	while(!enoughObjectsExist) {
		instantiate object
		yield return null
	}
}

This will allow you to make one object per frame instead of making all the objects in one frame. Unless your object mesh generator code is somehow putting off the work till later there is no need to use send message. If that works for you, great! If not, queue option 2.

Option 2:
Create a function that creates objects. No loop. Instead, allow the object to check if you currently have enough objects made (pseudo code).

public void CreateObject() {
	if(enoughObjectsExist)
		return
	else
		instantiate new object
}

Then you can use send message as you indicated, calling the CreateObject method as each mesh generation function is completed. Warning:

This option assumes that your object mesh generator code is somehow delayed, either by the object initially being inactive, put into some coroutine, etc. If not, you will see no performance difference from what you currently are doing.

Like I said these are just two example options. Depending on how your object mesh generator code is being called there might be other more efficient options available.

hi that's cool, thanks! perhaps i will use an empty loop after instantiation that counts through fixed updates until it gets a send message from mesh being generated. it's an environment gen, so it just generates missing spaces when the player moves, it can be any number of meshes, just i have to stagger the next instantiations until the previous are processed.

@whydoidoit brings up a good point. For an environment gen I would bet that you can reuse parts of the environment that are currently not visible. If that is the case, creating a pool upfront to take items from would indeed be the best. You can then return unneeded items to the pool so that they can be reused later. This would completely eliminate the necessity for creating new meshes every time the player moves!

Hi, i have a terrain tiling code that switches around tiles that are out of view and its faster than instantiation, and that is what i will do with the marching cubes also after, it's just for testing , if i move all the meshes in one go it's slow. With marching cubes i have to erase the mesh and make a new mesh every time, and with tiles i just change the y height of vertices. for the moment it's just testing with instantiation and then will change with moveable objcts :) the difficulty is queing things in a loop/ pausing code when fps is slow.

perhaps if i place this line in all the codes it would queue processing: for (var n:int = 0; n < 1000; n ++){ if ( Time.deltaTime > 0.04 ){yield WaitForFixedUpdate(); } else break; ... except i cant use yield in the multithreading mesh code... :/

@ZoomDomain: That doesn't work because Time.deltaTime as well as Time.time are constant during a frame. They only change in between frames. You have to use Time.realTimeSinceStartUp