#How to spawn entities when scene starts?
1 messages · Page 1 of 1 (latest)
this example only shows OnUpdate()
but i only need to spawn a thing single time
OnCreate or with smth else
well, what stops you from doing NextSpawnTime the time that will never be there?
or using bool to disable whole thing
or just destroying entity that holds component for spawn
idk asking if there is some generally good approach to spawn hundred entities and forget about everything
Hey! All the examples shows that we want to do it inside the OnUpdate and just set the "state.Enabled = false; " to create a system that just runs once. Here is how I do it in my project:
{
state.Enabled = false;
EnemySpawnerConfigComponent spawnConfig = SystemAPI.GetSingleton<EnemySpawnerConfigComponent>();
var random = new Random(123);
var ecb = new EntityCommandBuffer(Allocator.Temp);
for (int i = 0; i < spawnConfig.SpawnCount; i++)
{
Entity enemyEntity = ecb.Instantiate(spawnConfig.EnemyEntityPrefab);
ecb.SetComponent(enemyEntity, new LocalTransform
{
Position = new float3
{
x = random.NextFloat(0, spawnConfig.SpawnRadius),
y = random.NextFloat(0, spawnConfig.SpawnRadius),
z = 0,
},
Scale = 1,
Rotation = quaternion.identity,
});
}
ecb.Playback(state.EntityManager);
}
I hope it helps!
thanks, ig there is no other way then
will just do it in update and disable the system
There is also a https://docs.unity3d.com/Packages/com.unity.entities@1.0/api/Unity.Entities.ISystemStartStop.html interface that your ISystem can implement so that you can use:
Called before the first call to OnUpdate and when a system resumes updating after being stopped or disabled.```
I am not sure if you would gain anything by using it.
either way (state.Enabled = false) or this are very awful 😅
they will work until spawn time matches first frame and is not needed to execute multiple times (new game/reload and etc)
well, what's a proper way then
just to like spawn some prefab stuff and then erase the spawner entity
Actually as i think about it, i'd like to schedule a task and wait until it's finished to then spawn a player in the game world
For now gonna have the same mesh for each terrain chunk
So game goes like
Start
await Spawn meshes
Enable player and camera
Hey, I think you can use coroutines to wait for certain methods to finish executing before starting your game😀
Well, how do i integrate them into systems
Can you be more specific about your process?
Well. Im making a chunk system for a big world. For now i'd like to at least repeat the same mesh/material/collider, in a 96x96 grid while user is on loading screen scene
So when the world is set up(9216 chunks), i'd like to unload the loading screen scene and let player walk around
Are the loading scene and the scene that the player can move two separate scenes?
Yeah, gonna use additive loading
Main menu -> Loading Screen(and Game scene in background preparing everything) -> Game
But well, loading screen is not a thing right now, so i'm trying to just setup the game scene
Have the prefab of a mesh, material and mesh collider
Need to place it 9216 times in a grid
And let player use Input.GetKey(...) to move around
Then you can uninstall the loading scene after the game scene is loaded
Yeah, i can
But the problem is with spawning prefabs and then not wasting runtime resources on useless systems
Schedule 9216 chunk spawns, wait for them to finish, and then let user spawn in
Does this mean that after loading the scene, the game scene does not produce a prefab?
After chunks are spawned, prefab is not needed anymore
As well as system which spawned those chunks
Another system might start which would dynamically change mesh and texture resolutions as player approaches some chunk or walks away
OK
Right now im spawning 9216 GameObjects with mesh, material, and collider
And it gives ~3 fps
So well, entities might give better performance
And well, it's 18.4k triangles in total, but fps is low cuz cpu dies
Processing 9216 individual objects each frame seems to eat a lot of cpu resources
I sent you a private message
You can group your systems into ComponentSystemGroups and declare a condition for each group to update. For example SpawnGroup will only update if there is a GameLoadedTag, and CombatGroup will only update if there is a EntitySpawnedTag.
for (int i = -3; i < 3; i++)
{
for (int j = -3; j < 3; j++)
{
int x = i * 64;
int z = j * 64;
EntityCommandBuffer ecb = new(Allocator.Temp);
Entity chunk = ecb.Instantiate(spawner.ValueRO.mesh);
// ecb.AddComponent(chunk, new ChunkComponent());
ecb.Playback(state.EntityManager);
var transform = state.EntityManager.GetComponentData<LocalTransform>(chunk);
transform.Position = new float3(x, 0, z);
state.EntityManager.SetComponentData(chunk, transform);
}
}```
couldn't you just destroy the EnemySpawnerConfigComponent singleton instead of disabling the system?
probably
or set SpawnCount to 0 when you finish spawning
idk what is a enemyspawnerconfigcomponent
and what is spawncount
oh
it's not my code
oh, I guess I was looking at Sunny Valley Studio's example
what's wrong with this sample above
using an ecb that you playback immediately is pointless, you might as well just use the EntityManager to instantiate immediately.
what you've written here is basically your own ecb... so if you use this code in a system that is playing back a buffer of requests, then this is perfect
the point of an ecb is to defer structural changes that interrupt jobs and invalidate lookups so that you can do them all at once later
how do i instantiate several things at once then
using ecb or not
just like you're doing it, but use the EntityManager
unless you're asking me something else?
the overall way you should try to organize your systems is to run as many systems as you can before making structural changes... so if you want to instantiate things in other systems, you might just write to a DynamicBuffer on your singleton entity with the data necessary for all the instantiations to happen at once later in the frame
you'll also notice that the built in system order has a lot of pre-built entity command buffers that you can use
but in your case, since you need to be able to edit the entity immediately upon instantiation, it might make sense for you to do it like you are right now and just position your system next to one of the existing entity command buffer systems in the frame
idk really
i just opened up first YT guide and tried to go modify the output to suit my purposes
and it doesn't work
here in this code i spawn a grid of meshes
i want to spawn them single time
just to test if unity can handle 9216 meshes on my pc
the error you were getting was because you were trying to use the entity value passed from the entity command buffer with the EntityManager. The EntityCommandBuffer is for deferring commands to EntityManager. Use either one or the other, don't mix them.
Alr so ig for spawning 9200 meshes at the same time i should use a buffer
Right?
Pass it somewhere and tell unity to execute all of the commands
I'm not sure where the misunderstanding is coming from... I think maybe what is unusual about ECS compared to what you might be used to is that it matters when things get executed in a frame. The point of the buffer is to control when in the frame the execution happens.
i'm extremely new to ECS so yeah
if you are just testing something and don't care when in the frame it happens, then just use the entitymanager
i only used buffers for compute shaders before
if you care when in the frame it happens, use the buffer
alr then i shouldn't use buffer ig
is there a way to execute the spawning process on a separate thread and wait for thread to finish to execute some other code?
no, spawning is a structural change and structural changes have to happen on the main thread
thus why you would usually buffer them
(that and making structural changes while iterating through entities will break the lookups and so break the iteration loop)
what is a structural change
Entities aren't inherently visible. They're just data. If an entity represents something renderable, you should see that appear in the scene
you should see it in the scene view too
i don't
you should 😛
I'm not familiar with anything that would cause them not to appear in the scene view
might it be because i'm spawning a prefab
tho i love how fps went from 3 to 75
while i have 9216 entities on the scene
and not 9216 gameobjects
there's a number of things you could do to make this code cleaner, but none of this would have any effect on seeing something in game view that you don't in the scene view. The culprit is more likely to be in your scene viewport settings, shader settings, material settings, or something like that
it's HDRP lit shader
and i touched nothing
just installed Entities and Entities Graphics
alr gtg to the job
cya
If you are used to OOP than indeed it looks awful. In Data Oriented design you have systems that runs constantly based on data. One way that works for me is to have an "IEnableableComponent" that I add to an entity and this triggers a spawn system and disable. I do this to add compoanion object to entities. Another way would be to have some Singleton data component that has some Bool flag. If the flag is True you could do the spawning once and set the bool flag to false. Either way its all doable. Just a bit different than OOP
That's not very data oriented (what I called awful), because it's system oriented (which implies you treat it as object).
Your system supposed to only rely on component data and never rely on system's Enabled state or OnStartRunning.