#archived-dots
1 messages ยท Page 73 of 1
there are also cases where you you want it to be controlled to work the same always, like if you do deterministic gameplay and you just need to scatter the values by random
@dull copper thanks, that's how i understand seeds to work as well. thats sort of where i'm running into the issue. i guess i should mention the job i am running is a IJobForEachWithEntity.
public class Test : JobComponentSystem
{
EndSimulationEntityCommandBufferSystem m_EntityCommandBufferSystem;
struct FindJob : IJobForEachWithEntity<Translation>
{
public uint seed;
public void Execute(Entity entity, int index, [ReadOnly] ref Translation ltw)
{
Unity.Mathematics.Random rand = new Unity.Mathematics.Random(seed);
float f1 = (float)rand.NextInt(-2, 2);
float f2 = (float)rand.NextInt(-2, 2);
float3 fl = new float3(ltw.Value.x + f1, 0f, ltw.Value.z + f2);
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var job = new FindJob
{
seed = Helpers.GlobalSeed,
}.Schedule(this, inputDeps);
return job;
}
}
here's a simple example. what i would like, is different numbers for each entity for f1 and f2. right now, i'm assuming it's because i'm instantiating a new random for each execute (with the same seed)
i also tried to add the index to the seed. which seemed to give different numbers, but only slightly... like one would be 0.044 and one would be 0.043
am i just doing this wrong?
Similar seeds yield similar results, I believe it was @junior fjord who had that issue previously. Try multiplying your index with some pretty high number (but not so high it'll overflow). (Sorry for@ing you, but it's the precise issue you had, so you should be more help than me)
@tawdry tree that seems to work much better, thanks!
is there a method of referencing a component in a component? i know you can ref an entity by it's id.. can you do that with a component?
i am trying to make a sort of AI state machine sort of thing, where an entity is given a job. it'd be useful to be able to queue jobs (eg: moveTo(food) THEN use(food)) separately, my first instinct is to chain something like that so when move is done, start use
just one thing to think about @winter veldt before you get too far (you may already have), is if you want to handle moveTo(food) THEN moveTo(table) given you can't have two components of the same type on one entity. Totally doable just thought I'd raise it as that can be a pain.
i have realized that previously ๐ but i see where things would fall apart as soon as you want 2 moveto in a chain. having a hard time seeing how this would work out in ecs. but that is why i'm trying to learn it ๐
totally - you can either a)store all commands in a buffer of some kind per-entity or b) create an entity per command (this is the approach I take) - so each 'MoveTo' would be on a separate entity with a component that references the relevant entity to move etc
๐ฎ thats why i don't get ecs yet.. i really didn't think of.. and entity for each move. thanks!
Hey guys, I am completely new to ECS. Could you please tell me what the exact problem is in this code and how I can fix them maybe?
using UnityEngine;
using Unity.Entities;
public class Rotator : MonoBehaviour
{
public float speed;
}
class RotatorSystem : ComponentSystem
{
struct Components
{
public Rotator rotator;
public Transform transform;
}
protected override void OnUpdate()
{
Entities.ForEach((ref Components e) =>
{
e.transform.Rotate(0f, e.rotator.speed * Time.deltaTime, 0f);
});
}
}
It says "Cannot convert lambda expression to type 'EntityQueryBuilder.F_E'"
@wet fable I am pretty sure that you are not supposed to use the "ref" keyword
Also, that rotator is a MonoBehaviour
You prooobably want it to be a public struct SomeName : IComponentData
It is strongly advised to take a look at the examples https://github.com/Unity-Technologies/EntityComponentSystemSamples
They should at least help get you started with some very basic stuff, then you can come here when they're not enough ๐
So you advice me to use Pure ECS? Also thank you very much:)
@winter veldt it was the issue I had. There is a whole discussion on random last week. Consensus was: 1 rand per thread passed in from system, each seeded by master random from main thread. Rands with similar seeds yield similar results so using index for seeding won't work. Apparently though there are some noise functions where are designed for speed which may also help.
The rands lived in a native array of length = processor threadcount, and the threadindex was used inside job to access the array
i think you want to do this jayden
class RotatorSystem : ComponentSystem
{
EntityQuery MyQuery;
protected override void OnCreate()
{
MyQuery = GetEntityQuery(new EntityQueryDesc
{
All = new [] { ComponentType.ReadWrite<Transform>(), ComponentType.ReadWrite<Rotator>() }
});
}
protected override void OnUpdate()
{
Entities.With(MyQuery).ForEach((Transform transform, ref Rotator rotator) =>
{
transform.Rotate(0f, rotator.speed * Time.deltaTime, 0f);
});
}
}
Thank you
Why only the Rotator needs ref? I thought it'd be the other way around, ref Transform because you wanna modify it, no ref Rotator because you're only needing the .speed value.
I'm so new i'm kinda embarrassed asking this question..
Guys, I can't find what seems like the obvious...
I have an ISharedComponentData on my entity. How am I meant to get a value from it?
query is just for better organisation, im not sure if foreach works if you dont put ref in front of a struct in this situation
you dont need it but the previous code example looked like the injection workflow, which was the precursor to queries
Times like this I feel fortunate to read Japanese https://www.f-sp.com/entry/2019/04/18/175747 just found it. Going to digest now
ๅใซUnityใฎECSใซใคใใฆ่ชฟในใฆ่จไบใๆธใใพใใใใ ใใใใไปๅพใใฐใใไฝฟใใใจใฏใชใใจๆใใใใฎใงใ ๅฟใใชใใใกใซ็พ็ถใฎUnity ECSใซใคใใฆใพใจใใฆใใใใจใซใใพใใ www.f-sp.com โฆโฆใจใใๅๆฉใง่จ...
so.. if i have an entity with a transform component, can i create a second entity that references the same transform component so that changing it effects the first entity?
I don't think you can make components as reference types?
The closest might be to use it as a SharedComponent and then iterate over all entities with the value (ie. in the chunk(s)) when changing the value or some other workaround.
But... depending on what you're trying to accomplish, you could just use the attach system or what it's called? Basically parents two entities the same way you would gameobjects
you can create another entity that has a component that references the first entity
are you trying to parent something or something else?
@winter veldt yup, you'd use something like a ComponentDataFromEntity<Translation> allTranslations and in the job do if(allTranslations.Exists(theOtherEntity)) allTranslations[theOtherEntity];
So you can't .Add() to a NativeList concurrently, so using a NativeQueue and .Enqueue() during a Job would work concurrently. I could then just loop through and Dequeue to a NativeArray (or List) either OnUpdate() or in another Job but this seems messy. Is there a better way?
What is the final list used for, and how long will it live?
Its for batch destruction. Pretty much I run through all Lifetime Components and check if their lives are up and should be destroyed. So very short life Temp or TempJob
My previous way was just Destroying entities using a Concurrent ECB, but I am trying to make it less heavy when a lot of entities are being destroyed
I believe the 'correct' method here is to use command buffers. Basically, you queue up entity/component changes and they're all done at once, later, efficiently. Unfortunately I can't tell you any more than that since I haven't used them, and for all I know they might have been replaced like so many other things, but it should at least be able to guide your search.
Also, why do you specifically need to dequeue into a list from the queue? I mean, if you can already create an enumerable of any kind (the queue), you can just enumerate over them to destroy them.
Well I was reading this article:
https://gametorrahod.com/batched-operation-on-entitymanager/
I was under the impression that queue'ing up commands for ECB isn't different from iterating over and destroying but batched Instantiation/Destruction (using NativeArrray) gets more performance
Honestly, I could be completely misunderstanding batching
Huh, TIL.
Batches sounds like the kinda thing which would be the most effective, yeah, I just misunderstood ECB. I thought it batched stuff
As with all things perf, depends on how much impact the 'default' way has; if it's more complicated or time-consuming to do, it might not be worth it if you're not spending a lot of CPU time on it.
Well this is a testing project - not any particular thing. Essentially, it is spawning a bunch of things with moevement, collision, rotation, etc. Then destroying them later on based a lifetime value. So potentially nothing can be destroyed up to thousand of things getting destroyed
So use case wise, at the bottom it wouldn't matter as much with the concurrent ECB approach but at the upper limit I would imagine batching would make quite the difference
Hmm, maybe intentionally crank that up and profile it?
Yeah, I can do that in the next day or two. Only some many hours can be alloted to experimenting with ECS before I have to do real work ๐ฆ
Hmm... I guess that currently there's no way to manually re-run certain systems multiple times in a single frame, correct?
I'm asking because I want to achieve a behavior for some systems that gets executed per camera, just before culling
You could just put a loop in the system and iterate over the cameras?
A loop? Don't think I've ever heard of something like this in unity ECS
Oh, wait, I got what you mean. Unfortunately, no, that'll bloat things considerably for my needs
This is bloat?
foreach(camera in camerasFromSomewhere){
//do thing
}
In my case - yes, at least if I'm not missing out on something
hmm any reason a converted to entity prefab is not accepting getting components added to it?
also is there a way to set entity debugger names with command buffers?
Not sure if asked before, but is there a way to manually use the UpdateBefore/After attributes on e.g. a list of Systems to sorting systems that I want to run in FixedUpdate manually?
anyone know how to euler z rotation from a math.quaternion?
q.eulerAngles.z?
Hey, is there a way to use IConvertGameObjectToEntity for any other world seperate of the default world?
@minor sapphire something roughly like: ```cs
float halfPi = (float)math.PI / 2f;
float4 q = yourQuaternion;
//// yaw (z-axis)
float siny_cosp = +2.0f * (q.w * q.z + q.x * q.y);
float cosy_cosp = +1.0f - 2.0f * (q.y * q.y + q.z * q.z);
float zval = math.atan2(siny_cosp, cosy_cosp);```
@mystic mountain you can use UpdateBefore/After on systems that are within the same ComponentSystemGroup... you can also use the attribute between ComponentSystemGroups too
serious math entered the scene
anyone run into issues where entity stuff is just not rendering?
I have a project that's pretty much an exact copy of the HelloECs Entity Spawner example (just names are changed) and Running it creates the entities, but the rendering components don't get added
i even copied the spawner code over to this project, ran it, and nothing gets the renderer components
a ha! i was missing the hybrid render packaage
new Hybrid Renderer and Jobs packages
btw. thanks so much to all you fine people who help us all out. it's what makes dabbling in ecs right now sane, since docs, tutorials, articles could be drastically different than the current implementation. you're all rock stars!
also Entities 0.0.12p31
i just updated my collections package but I dont know if I was just lagging or a new release was secretly pushed out
oooo
p31 is only on staging atm
new hybrid package and jobs are on regular registry as well
collections updated as well
###Upgrade guide
* Serialized entities file format version has changed, Sub Scenes entity caches will require rebuilding.```
### Changes
* Adding components to entities that already have them is now properly ignored in the cases where no data would be overwritten. That means the inspectable state does not change and thus determinism can still be guaranteed.
* Restored backwards compatibility for `ForEach` API directly on `ComponentSystem` to ease people upgrading to the latest Unity.Entities package on top of Megacity.
* Rebuilding the entity cache files for sub scenes will now properly request checkout from source control if required.
### Fixes
* `IJobForEach` will only create new entity queries when scheduled, and won't rely on injection anymore. This avoids the creation of useless queries when explicit ones are used to schedule those jobs. Those useless queries could cause systems to keep updating even though the actual queries were empty.
* APIs changed in the previous version now have better obsolete stubs and upgrade paths. All obsolete APIs requiring manual code changes will now soft warn and continue to work, instead of erroring at compile time. These respective APIs will be removed in a future release after that date.
* LODGroup conversion now handles renderers being present in a LOD Group in multipe LOD levels correctly
* Fixed an issue where chunk utilization histograms weren't properly clipped in EntityDebugger
* Fixed an issue where tag components were incorrectly shown as subtractive in EntityDebugger
* ComponentSystem.ShouldRunSystem() exception message now more accurately reports the most likely reason for the error when the system does not exist.```
they got changelog now on entities package itself
that's nice
animations ๐ haven't got anywhere near that far yet ๐ i'm still just trying to get expected results from things i try to make
but i think i'm getting there. i think i'm understanding how to get things done anyways. which type of system, when to run it.. to use jobs or not.. that's another story...
tho the batched stuff on entitymanager article posted yesterday was really cool, had no idea you could just throw an entityquery at em to add components, delete entities etc.
oh my god i got the animation package in without it erroring
its on the staging registry, its not meant for public consumption yet @winter veldt ๐
then again, are any of DOTS things meant for that
i've had that type of fun too. Had lots of issues with the Tiny Mode packages.. which version of unity to use, which version of each package... i feel your pain
well, burst and new math lib at least lost their preview status
ah Entities is off staging
or should i say on the main registry
and it fixes the hybrid entity selection console error bug ๐
although now I cant appear to collapse components in the debugger
Does anyone know the most efficient way to simply destroy a bunch of entities with the same tag?
oooh, seems like EntityManager.DestroyEntity(query);?
dont suppose anyone else has messed around with the staging animation package?
I haven't but I would definitely be curious to hear about it... please report back if you take a look. Esp curious re performance.
I'd expect the usability to be the main issue for a long time
^ yeah - it has a menu to convert rigs/clips to dots assets but im unsure of the actual workflow. the rig seemingly gets converted and not sure how to do clips but on play i get a null blob error for the rig(i think?)
so tantalisingly close and yet so far
the skinnedmesh does get converted to a pure ecs representation so thats nice to see
Am i doing something wrong here?
namespace Game.Systems {
using Unity.Entities;
using Unity.Burst;
using Game.Data;
using Unity.Jobs;
using UnityEngine;
public class InputSystem : JobComponentSystem {
[BurstCompile]
struct InputJob: IJobForEach<InputData> {
public float horizontalAxis;
public float verticalAxis;
public void Execute(ref InputData inputData) {
inputData.Horizontal = horizontalAxis;
inputData.Vertical = verticalAxis;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps) {
InputJob job = new InputJob() {
horizontalAxis = Input.GetAxis("Horizontal"),
verticalAxis = Input.GetAxis("Vertical")
};
return job.Schedule(this, inputDeps);
}
}
}
it's giving me an error saying that InputJob must be a not null value. I don't know why. I read the documentation and it doesn't say anything regarding this issue.
Google is your friend
@glad solar try setting a default value to your horizontal and vertical axis. I think that may be your issue.
@gusty comet i know:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/structs
However, i copied the example in https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/entity_iteration_job.html. i think i'll return to the old way without using "Job". I even replicated the same example (not changed a single line) in the docs page and it's giving me the same error in the line after [BurstCompile].
Ah
@wise monolith thank you. thats not the case. Structs cannot be initialized the public variables, i even created a constructor and didn't solve it
@glad solar well sorry I couldnโt help you. Only other thing I can think of would be to search unity bug reports or forums. (but you seem to have that covered all ready) I wish you good luck in your search. 
@wise monolith yeah. thank you so much for answering me!
I feel bad, because wouldn't come to Discord if i find something, but i keep searching deeper though.

Well... i just give up.
it's something related with IJobForEach.
The error goes away when the struct have no interface.
well is unity giving you those errors too?
wait what is your component
what does InputData look like?
for the record this works just fine
public struct InputData : IComponentData
{
public float Horizontal;
public float Vertical;
}
public class InputSystem : JobComponentSystem
{
[BurstCompile]
struct InputJob: IJobForEach<InputData>
{
public float horizontalAxis;
public float verticalAxis;
public void Execute(ref InputData inputData) {
inputData.Horizontal = horizontalAxis;
inputData.Vertical = verticalAxis;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
Debug.Log(Input.GetAxis("Horizontal"));
InputJob job = new InputJob() {
horizontalAxis = Input.GetAxis("Horizontal"),
verticalAxis = Input.GetAxis("Vertical")
};
return job.Schedule(this, inputDeps);
}
}
so i am assuming its something to do with your InputData component
I feel so ashame of myself. now i find out the github link.
yes. just because it weren't IComponentData
Took me 3 hours until you you said wait what is your component.
sometimes i imagine myself as an ostrich hitting my head inside a hole. thank you so much!
dont feel ashamed, i had a similar problem where one missing component(on a parent entity), made it impossible to attach a child entity, wasted more than 3hrs on it ๐ฆ
so many times its just the little things
@amber flicker I tried adding systems to a group, but they don't seem to care about the UpdateBefore/After when created manually?
so... it should affect the order (if it doesn't, we can look at why) but what it doesn't do is guarantee that one system will be complete before another system
for that, you need to either rely on the dependency chain (which you can't always do) or manually call .complete() on the previous job
Maybe I did something wrong?
https://pastebin.com/Wkz8t5pD
hmm haven't done much wrt manual system update lists but one thing is that I would expect both TestSystem & TestSystemTwo to have [UpdateInGroup(typeof(FixedUpdateGroup))] above them in addition to the UpdateAfter
also you shouldn't need UpdateBefore as well as UpdateAfter but I get you were probably just trying to make it actually work
Yeah, I just tried to put all the hints xD
And UpdateInGroup didn't change order to be correct :/
it could be that all those are doing behind the scenes is changing the order in which AddSystemToUpdateList is called :/
this is a big part of my frustration with custom worlds atm - I've no idea how to create a custom world and respect those attributes
Someone poked me that they added some short time workaround in their new Samples for my problem at least
https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/ReleaseNotes.md#new-samples
Oooh nice!
Aaand.. its bad x) It's the simplest case of only one system running, and they do it the same way of having one MonoBehaviour hardcoding the system to run...
@amber flicker Got another reply that helps^^ ComponentSystemGroup has SortSystemUpdateList (god knows how I missed that), and it's kind of self explanatory.
hmm thanks for the update @mystic mountain - that works does it? You call it after adding all the systems?
Yeah
aces
Somone gave some more ideas as well how to solve it for now https://forum.unity.com/threads/playerloop-fixedupdate-jobcomponentsystem.670675/#post-4491883 as well, if they maybe suit better
I look forward to them just moving it to FixedUpdate ๐
am I the only person here who wouldn't want it to run on FixedUpdate?
I'd want ECS system that does the fixed timestepping itself, not yet again dependency on Unity's closed source codebase
I can do that manually today, but I'd want them to do more modifiable design by default
I'd appreciate something akin to [UpdateIn(SimulationGroup)], [UpdateIn(FixedUpdateGroup)] or whatever... but I'd also appreciate some simplicity... with a lot of overlapping timings (e.g. FixedUpdate running at higher frequency), jobs taking as long as they take (possibly multiple updates?), syncing them at the right time feels non-trivial. Combine that with ecbs, other worlds running at different frequencies etc... I like the power but I hope they find a way to elegantly represent the complexity I guess. Decoupling updates (physics or any other) from rendering feels essential of course.
Hey, I'm a little confused about entities. Can I have multiple entities that are generated from the same archetype, but still have different meshes. Vertex count and triangle count etc. would be the same, only vertex positions would change. Thank you
Short answer: Yes.
Slightly longer: The archetype just describes a recipe of sorts to use for spawning or filtering entities. Otherwise everything of one archetype would have the same position, hm?
Think of archetypes as a search filter - Not only can you get all sorts of results, but different filters can give you the same search result (this only applies to existing entities that you might have added new components to, of course. You know what you get if you make an entity from an archetype, think recipe.
Alright thanks, how do I add a mesh to an entity then? Is there some built in ecs mesh renderer component? The only one I found was using shared component...
I don't know of any besides the RenderMesh component
Which is a part of Unity.Rendering
So you guys always use the same mesh on entities?
Well I am under the impression that every shared "unique" mesh will be place in memory together for rendering so you can use multiple meshes but the entities's RenderMesh that have the same properties will render together
I guess I could just test multiple meshes real quick
RenderMesh is also ISharedComponentData, meaning that it's not recommended to use multiple copies of it, right?
If you could, I'd be thankful
Shared components are a special kind of data component that you can use to subdivide entities based on the specific values in the shared component (in addition to their archetype). When you add a shared component to an entity, the EntityManager places all entities with the same shared data values into the same Chunk. Shared components allow your systems to process like entities together. For example, the shared component Rendering.RenderMesh, which is part of the Hybrid.rendering package, defines several fields, including mesh, material, receiveShadows, etc. When rendering, it is most efficient to process all the 3D objects that all have the same value for those fields together. Because these properties are specified in a shared component the EntityManager places the matching entities together in memory so the rendering system can efficiently iterate over them.
So that means it's doable?
Oh, alright, thank you. I can't change the mesh inside a job though right?
I haven't tried but I would imagine if you changed it inside the job it would have to move that entity to a new chunk
There are a lot of smart people around here, so someone might interject later but that's what I have understood so far
Ok so how would I go about changing the mesh during runtime
Create a system that requests a mesh and then sets it once it's done?
Well you can SetComponentData using the EntityManager (queue up commands in a job or do it in the mainthread)
Or you could try just changing the mesh in the RenderMesh component itself in a job if you have a new mesh to change to - I have never tried this though
Alright I'm starting to see the picture in my head now. I'm going to try and do it now, thank you for you help
No problem, good luck
Note: Over using shared components can lead to poor Chunk utilization since it involves a combinatorial expansion of the number of memory Chunks required based on archetype and every unique value of each shared component field. Avoid adding unnecessary fields to a shared component
Also, I can't use SetComponentData with RenderMesh
Yeah, I mentioned how it would have to move it to a new Chunk (with similar shared values) based on changes
SetSharedComponentData
Ah alright
If you do it in a job, remember to use the CommandBuffer for changing the sharedComponentData.
And if you want to change is for all meshes in this chunk is will be even more efficient but it depends on the use case.
Hey guys, can somebody explain me the different between SharedComponent and ChunkComponent and maybe give me an example usecase when it is better to use a chunkComponent instead of a sharedComponent?
that's a good quesetion, i'd like to see an answer too to that. My guess is that since chunk component is only data shared across a chunk (and executed once?) that you can either leave more rough calculations to the chunk component to save processing or that it's more jobifiable since it isn't shared with more stuff as a shared component it?
is there a way to test for an entity not existing with GetSingleton?
ie GetSingletonEntity<PlayerWeaponInventory>().Equals(Entity.Null) just returns an error if it is a null entity rather than being useful
I believe HasSingleton<T>() where T : IComponentData is what you're looking for, otherwise an entityQuery.CalculateLength() check might suffice too
thanks!
Hello, anyone around? Got a fairly simple question about ecs...
How does one track time in an ecs system?
Does time.deltaTime still hold relevance? Does the value of it need to be passed in manually?
Also, any tips towards being able to have an entity's processing skipped for several frames at a time would be useful, in this case could i use a system based time tracking method? Or would that be adding unnecesary processing?
Can i simply use some method of
if(timer>wait)
{
//process like normal
}
else
{
timer+=time.deltaTime;
}
of course, substituting the time.deltaTime with the valua handed in to the job at its start?
Also, are there any time specific functions in ecs? the mathematics library certainly doesnt seem to have anything.
public struct ExampleJob : [Whatever IJob]
{
[ReadOnly] public float deltaTime; // name dt or something
}```
Then you would just pass it in like so:
```cs
var exampleJob = new ExampleJob
{
deltaTime = Time.deltaTime,
}; // schedule or something
It does have to be passed in but you could make an Timer component and decrease it in a job
Much like a lifetime system
To give an idea of the use case, my entities are like the background "life" of my universe, 95% of which is out of sight, but not just unrendered, they are activ in other systems a player must jump to, so to be able to give them updates once every few seconds would drastically decrease the processing needed. I want it to run by doing a few ships per frame, to also avoid bottlenecks.
Is it gonna be inefficient if i have the system basically do say 30-50 ship updates as normal, then begin adding timers and stuff, somehow remembering where it was for next frame, then, processing the rest of the objects differently, by incrementing their timers? Or, should i use the chunking system to somehow seperate the ships intended for full processing this frame from those intended for timer increments?
Im gonna fiddle with some code, if anyone has answers, please @me :)
anyone tried to build standalone with latest Entities/Collections packages?
I get instant crash on 2019.2 build startup
will check 2019.1 next
ok, no crashing on 2019.1, but it does crash on both 2019.2.0a13 and a14
even older ECS packages crash it
alpha is too dodgy for me ๐ฌ
2019.2 alphas has gone more crashy the further the alphas has gone
it started pretty stable
I guess this is why it's still alpha and not bumped to beta stage yet
can't really complain for alphas crashing tho, it's part of the deal
installing a11 now as I think could still build ECS projects in standalone with it
will double check as I don't trust my memory
a13 and a14 were instant crash to desktop from standalone builds
what's funny is that I'd want to move to 2019.3 alphas already ๐
2019.3 will eventually be bumped to be the LTS and it's the version when HDRP is supposed to get rid of preview status but I wouldn't really be surprised if they delayed HDRP to 2020
a11 is nope too ๐ค
I just downloaded 2019.2 as well... fortunately, havent loaded in any projects yet.
would still love to hear if ECS makes 2019.2 builds crash for others too
but it's very likely
Im about to try building my first few systems, so crashing is the last thjng i need hehe
Did you read my post?
Any thoughts?
HDRP was only for pc, in the version i looked at, is that how its gonna stay?
HDRP is meant for high end PC and consoles. So it will kind of stay like this. For low end devices like low end pcs or mobile you should LWRP.
@golden heron Did I understood your use case correct that you have a massive amount of entities to update and you want to split them to processed part by part over more then one frame?
I never tried it and I ask a question about ChunkComponent before but I have the feeling this could be a use case for that? Give the chunks a chunkComponent which hold your last update time and then discard chunks which are not ready to update yet. Just an idea, never used it ๐
Thats kinda what i was thinking yes...
If you used two different systems, then you could more easily make them act differently.
and yes, you did understand correctly. As an idea, the objects will be 2000 systems in existence on my server with orbiting planets and stuff, as well as ships, about 50% of the systems will have 2-10 ships under ai control, flying to destinations for trade and the like.
but players will likely only occupy a few systems at once.
So im thinking run the simulations at realtime where the players are, and in longer time but correctly interpolated distances for the unoccupied systems.
it's not meant for high end computers by design, only it's high end feats are
their idea is that it will scale down if needed but their approach will have more overhead on really low end devices
main difference between the two if you disable fancy feats for HDRP is that it runs a lot of things on GPU compute
it's the compute capability itself that limits HDRP out of mobiles unless you only target high end mobiles that have this capability
but all PC GPUs have it for example
ok so, a9 is last version that doesn't crash on build if there's ECS packages in the project
from 2019.2 alphas obviously
So, just putting together my first systems now...
In the GetEntityQuery it has the first as Rotation in the example, and the latter is the custom data struct, so, it must be referencing the rotational component of the entity like a transform, but, then it seems another one is using "Translation". Is this a new name for position, or is it something else? Should i be using Position instead of Rotation to turn the rotation system into a movement one?
Or, should i be setting the Translation component?
Also, it says on the first component, typeof, and on the latter a readonly thing, this seems like i should change them both to be typeof is i want to be able to write to the data on the custom component, but am i right in thinking this is a purely efficiency based difference, use read only is faster if the feedback to the data isnt needed? I.e, if my component is a speed which is affected by drag and so reduces over time, i need typeof, but, if i am making say a spinning windmill that always and forever spins at the same speed, then use the readonly thing cos itll be faster?
makes me think of type-o-negative
rattles the cage impatiently hehehehe :D :D
(i jokes)
you're right on both counts - Translation used to be called Position - renamed for more consistency with matrix operations I believe
and ReadOnly (or WriteOnly) for that matter are to inform the dependency chain of what needs to wait on what
then jobs can be scheduled safely and efficiently is the idea
So, i could use typeof all the time, but its not as efficient? Theoretically if you ignore speed and consider logic only, it wont make a difference?
(aside from the obvious access exceptions liekly to occur if you try to write to a readonly value, if you use readonly)
Have you used ecs much yourself?
Yea, most of the past 4 months or so - the main issue is you often want to use the result from job A in job B
and often you want to do things in parallel
so you can only read from something when you know it's not being written to
Well, im intending some complex systems, im likely to encounter that myself.
Obviously, as mentioned, im still at the very beginning currently.
sure... for now you can just use typeof and then add in read/write as you need later
but after a few days I'll be surprised if you're not just writing what the requirements are as you do it - it makes it much easier to debug problems and get the best performance by default
Well, i was also thinking one way to overcome the issues of the dependencies is to use the chunk system, but, to make the system do all the things at once.
I dont know yet of course how well that would go.
Or if it would work well... i mean using one system compared to multiple systems has to make a difference, tho not sure if good or bad.
hmmm honestly I'm not really sure what the issue is... I'd say write some systems and see how you fair?
In my case, its in space, and nearly all the entities will have identical data.
I was mostly chatting about what you think the effect would be, if i condensed all the systems into one?
I'd say the whole setup is designed around many systems doing small tasks rather than big monolithic systems.... that said, it completely depends on what data you have and what you want to do with it
so, i suppose if the data isnt too deep and not too much total processing, it might work, but if its complex, splitting systems is better.
which leads me to a question about physics.
I was considering how to work out without failing to catch hits the effects of shooting bullets and moving ships trying to collide, in excess of 500ms
and, my thoughts...
To use a kind of mathematical simulation of the ships tunnels, imagine the tunnel being all the space the ship has occupied between this frame and last frame, and run all the ship movments first, followed by the bullets just moving, but checking if they pass through the ship colliders.
it sounds complex, but its a case of 3-10 ships maximum, and i was gonna make it so that only ships in range of a bullet at the frame start would do it, so chances are 2 ships max most of the time.
basically, it would be an aabb of roughly the ships size at interpolated positions along the ships path, no more than 2-3 i expect.
(So yeah, im gonna probably need to split the systems hehe)
sure - some kind of raycast system, some bullet spawner, some ship destroyer, some pfx spawner etc etc - you'll have many by the time you're done... you may not want to do everything in ECS-land
I dont need raycasts for aabbs... thats the beauty of it.
sure... until you care about spawning particles where a bullet hits the ship exactly.. but anyway, that stuff is just standard c# either way
You basically avoid all complex computational requirements by instead using a simple if (pos.x < max.x&& pos.x > min.x) and so on
Well, that wont matter extensively, when the ship is moving fast enough for this to come into play, no man on earth could say that the particle was in the wrong place by eye. And, the aabb will provide an approximation anyways.
After all, if the ship doesnt move fast enough for its total distance to extend beyond its length, this is a moot point.
Anyways, ill stop throwing ideas at you and code some instead hehe, thanks @amber flicker
Have fun ๐
var chunkTranslations = chunk.GetNativeArray(TranslationType);
var chunkMovers = chunk.GetNativeArray(MoverType);
for (var i = 0; i < chunk.Count; i++)
{
var translation = chunkTranslations[i];
var mover = chunkMovers[i];
//var move = chunkTranslations[i].Value + chunkMovers[i].velocity;
// move the object at speed given by moverData.
chunkTranslations[i] = new Translation
{
Value = chunkTranslations[i].Value + (chunkMovers[i].velocity*DeltaTime)
};
It doesnt move them!
beats it with a stikk
Nope, still not working... hehe
so does this look right? is it likely that actually my velocity isnt right?
easy to test by putting in a float ๐
I'm not spotting anything obviously wrong with that but your problem could be outside that code
i just realised
the two vars - translation and mover - arent used...
it shortcut direct to their values.
thanks tho
hahahah its my velocity...
i had an as yet unused position variable which i was gonna use for feedback, seems im setting that not the velocity to the random speed value its set to for testing
yay it works
Nice and your project sounds awesome. If you have something to show... ๐
@crystal zephyr ill dm
Hm, so I'm working with hybrid stuff and looking into the new entity things. I don't really see how to use things like Animator with the Convert to Entity script. As far as I understand the Convert And Destroy destroys the MonoBehaviours when it destroys the gameObject, and ConvertAndInject doesn't keep positions in sync, and I can't use "Copy Transform from GameObject Proxy" since it needs GameObjectEntity which is mutually exclusive with ConvertToEntity ^^ Does this mean there isn't a clean way to do this yet, or you should stick to using the GameObjectEntity on these objects?
is that your thread Olento?
I think i read something about needing to set up an animator system which progresses the animations for you
Anyone know how hierarchies work in ecs?
Can i have a parent to move around and have children move too like normal? I read something that suggested when you convert a gameobject to an entity its children are seperate entities, does that mean they lose the relationship?
Or does it just mean they end up in the same hierarchical relationship but as entities instead?
Answered question myself... seems that the objectd sre not seperated. I just added some stiffly attached cubes as children to my tester prefab, and they move with the parent like a charm.
yes, that's my thread, just posting it here for awareness
filed a bug report, if you use Entities, it will crash standalone build now for 2019.2.0a11-a14 at least
try development build option in build settings
well, it does crash on after collections have been used, seems like some allocation issue
it's totally out of my hand as it's crashing on Unity's player
so, I leave further debugging to Unity at this point, I just narrowed it down for them
Yeah, but just FYI I had crashes on player start too, but it seemed to work with dev build
I'd wish I had full source access for stuff like this
I mean, now it's only happening on alpha, but people get crashes on stable releases all the time and there's nothing one can do if it happens on closed source side of things
if you are lucky, you can work around it
ya
which engine version you use now?
19.2.0a11
I noticed also that immediately the player would crash
no idea why dev build is working
yeah weird lol
it's not a real solution but can be used as a workaround for the time being
maybe confirm that on your thread so unity see a pattern heh
I'll add it to the issue report, thanks ๐
ah, I don't need to
lol
Thanks for getting in touch, this is actually a known issue that has already been fixed in 2019.3.0a2.
I asked them ๐
I don't think I'll get an estimate, other than "around the time 2019.2 betas ship"
I did ask ETA for 2019.3 alphas + ETA for the 2019.2 fix backport
the roadmap has no information on .3
considering we got 2019.2 alphas when it hit a4, so if it's close to that, then maybe 2019.3 alphas start rolling out in the end of this month or so
well, roadmap is pretty outdated anyway
they recently filled it with old already implemented entries
but the roadmap webpage has been pretty useless for few years already
if you really want to know what Unity is doing, just watch some roadmap talk from Unite or now from last GDC
yeah, I'm most interested in the unity physics and ecs stuff atm anyway
there's practically no public roadmap for DOTS
the GDC's DOTS roadmap talk didn't really answer almost any real questions
just vague mentions on what they are building but only got few estimates that weren't 2022
hehe
I'd wish they'd be more open on DOTS development, now they do a lot of work behind the curtains and then just boom, release it
it means early adopters end up doing a ton of duplicate or extra work as they can't plan anything in advance
I'd personally want that DOTS editor really badly, as long as you can also use old gameobject scene along with it
this is the first time I've been an early adopter, just wanted to try something new
it would simplify Unity's ECS debugging and usage sooooo much
I don't enjoy the conversion workflow at all, it seems like hacky step to avoid doing the proper editor
at first I was confused about what was going on with that, I thought "this is what 'hybrid ecs' must mean"
then I was like, oh, this is the recommended way...
currently yes
it's not the most horrible thing but I really miss having proper editor where I can select objects and examine them directly from the scene
I mean at runtime
oh yeah definitely
just having entity debugger for it isn't doing it all
everything disappears and gets lost
well, you can still examine the entities at runtime like the old gameobjects, but you can't quickly select them from the scene view itself
it's hard to find the entities I'm looking for
and by default the conversion scripts just name things like entity 0, 1 etc but that's just one switch away to make it use old gameobject names on the entity debugger
scene hierarchy is just like 'search'
I still wonder why they don't have it like that by default
and it's a hierarchy so easier to find
that too
especially if you have meshes with lots of submeshes ๐
each gets it's own entity
and I mean now actual meshes, not materials (I dunno why Unity somewhere calls those submeshes)
you can have submeshes when your original mesh exceeds the vert count
if you have a whole bunch of entities, (because you know, ECS allows you to deal with more entities than GOs theoretically....), and you want AI for these suckers, what approaches to AI are out there? I can't really see how a behaviour tree would integrate well for example...
new AI Planner is ECS based but I don't think it's designed to be used from ECS
all I know it's some GOAP kinda thing but even their own docs are so vague that it feels Unity itself doesn't know what it is about
it's not a good sign that docs can't even describe the basic idea
looks like a machine learning thing?
Use the AI Planner package to create agents that generate and execute plans. For example, use AI Planner to create an NPC, generate storylines, or validate game/simulation mechanics. The AI Planner package also includes authoring tools and a plan visualizer.
not really
ML goes into bit different AI category
I guess I'll watch this
https://www.youtube.com/watch?v=78nhJNPS0vA
Recent advances in the fields of autonomous robotics and machine learning open exciting perspectives for applying AI to multiple aspects of game development....
figuring how my agents are going to make decisions seems to be a pretty important thing to figure out haha
normally I would be able to turn to behaviour trees, or goap or whatever, but with DOD, dunno what the options are lol
I'm not too obsessed on being able to run every game logic on ECS atm
will try pure ECS probably only after few years once Unity gets their systems in place
it's a huge time sink now, trying to work around the limitations of current DOTS framework
and then next Entities package releases and bunch of things change again
you keep constantly rewriting your logic
what was the attribute to make something run before something else?
UpdateBefore/After
haha nice
thanks
[UpdateBefore(typeof<MoverSystem>)]
?
doesnt seem to ike it hehe
[UpdateAfter(typeof(TestSystem))]
thanks, jsut worked it out ๐
do i need to do it both ways, or will one suffice?
does it matter? hehe they seem like doing either one or both results in the same between two speicific systems
I've just been using UpdateAfter
Hmm... if a data component is processed once is it able to be processed again? if two systems both use the same components, will they both get the components naturally? I have a kinda ai routine controlling a speed in a move routine
ai sets speed, the move should move... but not happening
yes, multiple systems can act on the same component
just make sure you pay attention to readonly attributes and stuff so scheduling is optimal
For that it is important to use the ReadOnly attributes.
Multiple system can read the same data in parallel but write access is in a sequence.
well thats why i was asking about the before and after - the speed is calculated for the move system by the previous ai calculation system
Sure if you define a before or after then the schedule system will respect that and will not run these systems in parallel ๐
And in the order as you want ๐
hmmm.... still not getting movement now tho. Altho my movement system worked fine
var translation = chunkTranslations[i];
var ship = chunkUniverseShips[i];
var mover = chunkMovers[i];
if (ship.systemDestination == 0)
{
// same system
float3 distanceVector = new float3();
float distance = 0;
distanceVector.x = ship.destination.x - translation.Value.x;
distanceVector.y = ship.destination.y - translation.Value.y;
distanceVector.z = ship.destination.z - translation.Value.z;
distance = math.sqrt((distanceVector.x * distanceVector.x) + (distanceVector.y * distanceVector.y) + (distanceVector.z * distanceVector.z));
ship.distanceToDestination = distance;
ship.directionToDestination = distanceVector/distance;
}
if (ship.distanceToDestination > 10)
{
mover.velocity = ship.directionToDestination * mover.maxSpeed;
}
chunkMovers[i] = mover;
//var move = chunkTranslations[i].Value + chunkMovers[i].velocity;
// move the object at speed given by moverData.
chunkTranslations[i] = translation;
chunkUniverseShips[i] = ship;
Check in the entity debugger. This should show the correct order, just to see if your UpdateBefore worked out.
ok
they show in the order they should be in the list, but no indication beyond that?
is the list order the run order?
yes
ah, then its doing as it should
I guess we looking in the case ship.distanceToDestination > 10 ?
does the ship has already a directionToDestination?
So... the entity debugger shows the recorded data as expected in this component's data, but not in the moverdata
because it will only set here in the case of SystemDestination == 0
no, it calculates it, and that works fine
forget it, just look wrong
that 0 is set manually
its a static value atm, never used, intended to indicate that the ship is in the same system as the intended destination.
ok... so im guessing i nevewr set that - thanks dude ๐
Even it is called maxSpeed I would assume you planned to have a currentSpeed and doing a acceleration somewhere else ๐
YAY it worked
waits to see if ai choices work
maybe 1000 units for first move was a bit much hehe
dude...
thats gotta be the most entertaining list of numbers changing ive ever seen
๐
i fixed the one error you pointed out, and not only did they move, but the distance and ecerything fed back properly and the drag co-efficient even worked nicely for it to slow to a halt sensibly once the "ai" routine stopped directing.
Thanks for being my second eyes tho @crystal zephyr
You're welcome. I am happy when I can help.
this is gonna be so much fun ๐
I also enjoy helping when i am able too ๐
in fact i recently wrote a statistical analysis routine that could generate crazy amounts of output from varying formulae just to help a friend choose a good points formula for his game ๐
wow, you are really into maths write? ๐ Really cool.
hehe yeah
this is why, now i have realised how deeply ecs can be used with pure maths, im quite excited hehe
its like taking the huge library of confusing functions away might actually work out easier hehe
@golden heron, waits to see if ai choices work <- what kind of AI choices are you talking about?
that was a tongue in cheek reference.
so you're not dealing with AI in ECS?
Its not an ai, or anything complex yet its just an if then decision choice.
I will however be making an ai to fill in that point in the system processing
um, yes, if i understand what you mean by roadmap - i am self taught, dont know all the right words hehe
but... well lets jsut say ive had some fun successes ๐
I guess what I'm really asking is
You have experience with ai in ecs, @minor sapphire ?
no, that's why I'm asking hehe, seeing if you have ideas
Ah, i see, well, i do have many.
How should decision making for ECS entities be approached, that's what I'm considering
One of those successes was teaching an ai (rigid choice ai, not learning) to fly a spaceship by visual recognition in another game.
interesting
Well it depends how your particular game is gonna be laid out
I'm playing with 2D, top down, sorta space ships I guess?
agents that fly around, wanna do some trading, wanna do some attacking...
Does the ai need to dodge, or just shoot and approach? or follow any wierd paths?
ok, so its a large environment
well, potentially
for now I'm just practicing getting them to have a bit of a dogfight
but I'm mean with AI techniques, you want something you can scale, adding more complexity and decision outcomes over time
you should be able to begin by making your usual rotation and movement systems, but with an ai function like mine at the beginning, with a set of instructions to go through, its there that the real ai programming takes place. A good ai is good because it has lots of carefully made choices matched to the right conditions.
oh, so you already have a framework?
no I have no framework for AI, I've just started a project in ECS, added some basics systems to get them to fly and shoot each other
but it's all traditional inflexible AI technique
i get you
it won't scale
yeah exactly
thats where im at atm.
What you can do i suppose is begin with dodging abilities.
Then possible add more complex behaviours, these would be more like staged arrangements tho, the ai would need a theoretical state machine to follow the kind of movements needed to, for example, creep up behind a players ship and shoot them in the back.
but if you break each step down, and use an integer value to record the current state of the machine, you can do it quite easly
hmm
Anyone know if it is possible to use the ConvertToEntity in context of hybrid?
for example, your ai choice routine has defined choices available to it dependent on what is state is, then you can write in some kind of override values too, like if im creeping and i get shot - ovrride current behaviour with shooting
Tahts what its for i think, jaws
to take the monobehaviour and make it into an entity
thats what hybrid means, otherwise, pure ecs creates the entities in code.
(i think :D)
I think hybrid means your game world is a mix of entities and GOs
But I want to use e.g. physics, animators etc, that are not pure ECS yet.
physics has Unity Physics in preview, but I get your point
I think you have to write a system to keep some GOs in sync with entity transforms
Jaws, its not really possible for gameobjects and entities to naturally react to each other?
With GameObjectEntity you can have systems that react on Transforms and IComponentData
the ConvertToEntity GOs should be thought of your setup for the entity side
oh interesting ok you know more than me I think ๐
yeah, shinyclef, so either way you are copying the gameobject as an entity, or the entity as a gameobject, so they can react? in hybrid i mean, if you wanted an entity and a GO to collide for example?
ooh, whats that jaws?
like an extension to a monobehaviour?
if you want them to colide, they both have to exist as entities with unity.physics, or both as gameobjects with physx colliders
upon close inspection that reaction is much politer than it initially appeared ๐
lol
is unity.physics like documented? hehe
'juuustt' enough to get by lol
I implemented a collision event system in ECS with their trigger colliders
but it takes like 80% of the CPU time lol
well, depends how many entities you end up having haha
the fact that it's stateless means no caching... I wish they didn't decide that but I guess they want to differentiate with havok or something
I'll get you link
ooh thanks
there are some cool queries in there
like 'closest hit' query
doing nearest neighbour searches always sucks lol
so glad they did it for me ๐
There's UnityPhysicsEamples in the ECSSample repo
buuutt how much will havok cost ๐ฆ
ima write me own hehe
your own physics engine?
its all raycasts and colliders....
I wanna do it with pure math anyways
and some smoke and mirrors ๐
I dont need to model gravity direcly for example, and i can probably avoid the need to ever use a collider more complex than a cube.
even if that's the case, you can stick to kinematic bodies and just do casts and stuff
let them do collision detection etc
I dont want to do any casts thats the point
right
if its done with pure math, in the burst compiler, i should be able to make it be still fast, but also be able to reduce the calculations to only whats really needed.
true
Something as computationally expensive as ray or collider casting seems like it would eat up the bonuses
hehe like pacman
lol, very nice Nys...
Here is a question... what about particle systems?
yeah no idea, particles sys has to roll your own for now, or do a hybrid
Im quite happy rolling my own... i guess ill need to look into the rendering of sprites, i'd guess not much more complicated than 3d, less if anything
is there some special way to retrieve the entities transforms in a monobehaviour? Simple use would be to make it follow an entity?
Hmm, all you need is access the ecs World object I guess right?
can you set some static variable somewhere from one of the systems?
poke around in there like an array?
Hmm ok, hadnt thought of that, not 100% sure of the structure yet
it has methods like "GetComponentForEntity" and stuff right?
you want to get your hands on the EntityManager
World.Active.EntityManager
depends also on how many simulation worlds you intend to have
make a dummy system that does no jobs
but allows main thread to poke around with entities hehe
Incould then seperatw my systems into different worlds? (solar systems not ecs systems)
that could be thousands of worlds tho... Can a system work across all the worlds?
hehe fair enough
Hmm, ok so seems that I can simply add the CopyTransformFromGameObject manually or just ignore the GameObjectEntity will not work, error warning. The only thing now is that I have doubled rendering cause mono renders and hybrid renders. But I guess I could just shut Mono off in some script or ignore it for now.
Time to upgrade and refactor a few systems ๐
why not make a pair of objects, one representing the ECS state and one representing the Mono state?
mono state does not need rendering
but does needs stuff like audio and particles
or in the convert to entity code, can you remove the non-mono components?
Ah, seems like hybrid doesn't care if the Mesh Renderer is disabled or not, so that works : )
oh cool nice
disable entity side components then I guess
are you using convert and inject?
That's the plan yeah
right
@golden heron lemme share an idea with you see what your thoughts are
Imagine 1000 entities exist, that would typically be given the same behaviour tree
you've worked be BTs before I guess?
I know the idea
its a flowchart representation, forks in the path based in conditions, basically.
yes, with one 'active' node at a time
the tree's execution lands on a node that says hey I'm active
then depending on implemention either it pick up from there next frame or re-traverses the entire tree
4 instance of the same tree
how could you get this working such that....
a system process all instances of red node
nah their paths diverge so it's not really parallel
duplication of node types means they won't work as components, unless as some kind of buffer situation
I think it's all just trying to force it into something that's not a good match ๐
I'm trying to imagine a world where each node is an entity now, with an 'active' tag of some sort
each node type has a system to process that type
it picks up all instances of its node that are active
and there is some kind of loop that runs through these systems until trees say they are resolved
doesn't really help if the component data is not useful cause it's not attahced to the entities that need them though
so that's my ramble thinking out loud lol
I think I would probably put the implementation of the nodes into 'pure function' statics and have the system and jobs use those. As for the logic around that, not sure. Haven't worked with behavior tress much.
I guess a system that runs before everything else and traverses the tree (again, might have logic in statics if it makes things easier to read and reason about) and somehow marks the entities for which which behavior-system/job to use?
I'm kinda immagineing a system that executes a loop where each node type runs
so each node of the same type is running in a parallel job
tehy can live on the entity they are affecting if each node has its 'instances' stores in dynamic buffers
Heck, maybe something like this: (Obviously very pseudocode)
class BTSystem{
//jobs defined in their own files since there'll be a lot of them
foreach(BTentity){
//BT logic
if(noMoreNodes){
MakeJobForNode(currentNode);
}
}
}
some kind of tagging or component change would need to run to indicate which node is active, so systems don't run nodes on a entity that aren't active...
and this structural change would have to happen after each loop so the EntityQueries would be effective
it feels within the realm of possibility lol
no idea if it would be a 'good' thing though lol, there would be a lot of system executions, but the behaviour trees would be doing the nice linear data lookup we love
there would aslo be a lot of archetype moving
but only for HOPEFULLY some kind of tag situation
If my understanding is correct, then having a component CurrentBTNode which just holds an enum of int (public enum BtState : int {}) and just checking that first thing in every job/system is pretty cheap and possibly preferred to other way
and there would be a node result component that every system writes to
but you want the system to do an entityquery using archetypes
not having to check the value of a compoentny on every entity right?
alternatively, use an ISharedComponentData?
Yeah, in general, but which one is cheaper between one int comparison vs constant changing of components?
the int changing is the faster 'write' , the component change is the faster 'Identify which entities to process'
hmm
must do a profile I think
just wanna sound out the concept first heh
I guess it also depends on the implementation of the BT, specifically how often you (on average) change state. Because I'm 100% sure the int method is faster than swapping components
it is at first, but is slower on the QUERY the system perform to identify which entities to process for 'Node Type A'
each method has a faster and a slower stage than the other method
unity also mentioned they want to optimise so tag components are cheap
in that diagram, there are 8 node types
you want 7 systems to NOT find the entity, and 1 to find it
per loop
you want [entities count] to be processed per loop, not [entities count * node count]
I think it's also helpful to consider that adding a component IS like an entity being in a different state/ having different behaviour - all problems seem to come down to how you represent the graph ๐ - the tree concept is I guess a way of visualising the combinations and flows of states
yes
Hmm, what's the cost of having a system find an entity, though?
As long as systemCount*nodeCount*intCompareCost < (systemCount-1)*findSystemCost, then the int method is faster. And of course, the result may change as they work on things and improve perf of tags
systems finding entities based on archetypes, it doesn't need to loop through entities
finding entities based on component data, it does
findSystemCost here includes the changing of archetypes and all that
yes, which would happen once per loop
my super broad approach from my experience so far is if you have many things changing per-frame, use an int/bool/similar... if you have something entering a different behaviour for x-frames/seconds then use components
there a [node count] searches per loop, and only 1 change
If you know you will change the archetype every frame, then I'm 100% sure the changing is more expensive than just doing the int comparison instead
the culling done in the search by the archtype is also huge, you want to find all the entities where that one node type is active. It scales much better the more nodes you have
Either way, to profile is the way to find out
it's not about frames, it's about ratio or archetype shift via tags, to searches by entityQuery
@tawdry tree is correct.. but I also think anything that adheres to the idea of being state-based is unlikely to be changing every frame
it's likely to be changing archtetpyes MULTIPLE TIMES every frame in fact, I'm aware
but it's about the ratio
Multiple times? That sounds nasty
in the system I'm imagining, let's say there are 50 node types
you run those 50 systems, in a loop, until the tree resolves (how expensive is running a system with only a few processed entities?)
each loop, you want only ONE of those systems to process the entity
the one that operates on the active node type
the other 49 should do quick culls and move on
That might be interesting for you:
https://gametorrahod.com/tag-component/
so changing that archetype after the 50 complete, you save culling * 49
As seems to be typical with ECS it seems like this is rapidly approaching what kind of data you actually want to manipulate to consider if 50 systems is the right approach
So you track state by changing archetype repeatedly?
oh yes I read this article
yes
yeah, I was thinking aloud for a while to see if it's possible to data orient a behaviour tree, but there is probably no clean way lol
you could also limit loops per frame so the tree takes some frames to resolve, and also, trees spend MOST of their time in a 'running' state on individual nodes, when this is the case, there is no change in archetype
it would scale better when there are smaller trees with fewer node types, across many entities
each 'tree' could have a master system that only loops through the nodes that exist in that particular tree
keep the loop as small as possible
hmmmm
too many costs to measure, like running a system that doensn't fine many entities, several times
that article is why I believe the tag approach is likely better
@mystic mountain use the conversion interface on a monobehaviour with convert and inject, and add CopyTransformFromGameobject by code(also will need to add translation, rotation, localtoworld)
If anyone is interested, my movement system from earlier now has a stress test...
This shows 10,000 simple ship models being rendered and updated every frame. All ships are moving with randomly changing directions, updated relatively frequ...
how many
Very basic, random directions driven by a sort of simple random-number controller. All done in ecs :)
10,000 in that one
I dont have a very fast pc tho... hehe
cpu or gpu bound?
what happens when you use cubes?
also you def got low batch count?
Well, i did cubes as well... there are four vids there in my list
I didnt check actually, kinda a bit of a rush as gotta go to work soon... how to check batch count?
in game view open stats
batch count should be low, saved by batching should be high
show me your stats window
It did a million invisible objects at about 9-10fps
just a mo unity is running badly
i just... asked too much of it hehe
you using standard shader for those objects?
the ship model is probably in the 30-40 vertice range as well
wow super tiny ๐
So even with the ship, not too heavy
hehe this is a tiny freebie came as a joke part of a set, but, it fills out some of my use cases quite nicely hehe
this was my early test
http://download1.rolyd.com/Other/2019-04-28_03-20-41.mp4
Ok... I think im gonna need to let my pc catch up with itself hehe
I gotta get me a better pc hehe
Altho, in all honesty, i just multiplied the workload that was already making it wary by 1000, and, it didnt sxplode. so, bonus! hehe
Not sure hehe
Im using the files as rigid templates atm, and tentatively too hehe
What method did you use to calculate collisions of bullets in your example?
unity.physics
which is the bottleneck in my project
the broadphase takes ages lol
Hehe yeah... I could give you a technique which would work beautifully for that example
If thats your bottleneck
Its simple as hell.
gimme a sec tho, then ill explain
you know what makes an aabb special compared to a collider?
what? (btw unity.physics broadphase uses aabb)
how many meshes in that test @minor sapphire ?
if I remember correctly, it was 8k ships and 4k bullets
interesting - looks like quite a lot more
without physics I could push more like 50k lol
oh yea, lots more
with what kind of fps?
The idea i was intending to describe is to use an aabb for collisions, but rather than using unities version, simply doing it by using comparing
physics comes in and kills it all though haha
but, if they are already using aabbs...
i havent tried their yet, as i mentioned, i assumed jt was colliders
well, I dunno how well they implemented yet
it's only physics preview 2 and the guy said colliders needed a lot more love lol
fyi benchmark-number-wise, my tween library on an i5 will constantly animate 200-400k cubes scale & position @ 60fps - it varies based on how many cubes are actually visible... I can tween about 1m cubes if not rendering anything ๐
Well, if you can get a central repository to read a component from each object to an array, you can simply compare the numbers.
on i5 nice
with 1m cubes about 9ms is the actual tweening
wait... maybe not quite right.. meh.. very rough numbers
oh man you need more cores for ECS ๐
lemme put together a build and you can run a test.... you don't have to but gimme a few mins
yeah sure why not
I'm on an i5 too
a reasonably old one
I really want an 8 core i9 lol
with hyperthreading ๐
When i actually get all the code done ill lay out for a much better spec pc for my server, but i gotta make it worth it first hehe
My pc was mega cheap tho, getting like 10 gigs of ram was about the only thjng that lets me play with unity without pulling my hair out heh
Ok I've set the camera all the way out - so basically worst possible performance - numbers may be closer to about half of what I stated above running with both the scale and moving looping for each cube... anyhow: https://drive.google.com/file/d/1NoG9mnKg5Cf7x-vGtbAOjMk_luRAKcTa/view?usp=sharing
Google Drive is a free way to keep your files backed up and easy to reach from any phone, tablet, or computer. Start with 15GB of Google storage โ free.
share publicly?
250k @ 23.5fps
๐ ta
If you want to check how much that's to do with the meshes/gpu, you can run this one (which is v unimpressive as there's nothing to visually see haha) - https://drive.google.com/file/d/1-cLjOgeMkwWGtrs7vKsfOOByko6v7II6/view?usp=sharing
so satisfying ๐
I should mention that it's possible to get better raw performance than my demo... maybe as much as double if you only wanted to do that exact thing. I had to sacrifice a bit of performance for a full tween library - basically cache coherency .... still.. I'm feeling pretty good about it - you can nest sequences, tween all axes independently with their own ease at the same time and easily add native support for any float etc in your project
(https://www.youtube.com/watch?v=_Uu-Fu6pXME for anyone curious, or willing to give feedback, on the UI)
Is there a way to get more combinations of the Entities.ForEach? ๐
Need <Entity, class, class, ICompoentData, IComponentData> x)
I think that might call for switching to chunk iteration
tangent but is the base componentsystem class for all the combinations of ForEach generated by hand or by some script?
Is there any big difference by using ForEach vs chunk iteration (for hybrid stuff like this, without jobs that is)?
With chunk interation you can have more complex queries due to entiteyQueryDesc. And you can potentially process faster if you could skip whole chunks for some reason.
Is Dequeue'ing from a NativeQueue considered Read, Write, or both? In context of a job
I'm assuming both since you are removing from queue
Since there isnt a nativequeue.concurrent for dequeuing
I assumed it was, but I wanted to double check before throwing out the idea. Because writing concurrently to the queue is fine
I am trying to logically setup my SystemGroups - does anything seem out of order? I am still trying to wrap my head around doing an ECS game loop rather than "things just happen"
public class NetworkSystemGroup : ComponentSystemGroup { }
// Gather all network messages and apply them to the right spot
// Such as Input Gathering from each player
[UpdateAfter(typeof(NetworkSystemGroup))]
public class InputSystemGroup : ComponentSystemGroup { }
// apply all input received to the needed components
[UpdateAfter(typeof(InputSystemGroup))]
public class MovementSystemGroup : ComponentSystemGroup { }
// Update rotations system then update movement system
[UpdateAfter(typeof(MovementSystemGroup))]
public class HitSystemGroup : ComponentSystemGroup { }
// Raycasts, projectiles, etc and then do logic for hits such as reduce life times to 0
[UpdateAfter(typeof(HitSystemGroup))]
public class LifeSystemGroup : ComponentSystemGroup { }
// lifetime reduction system and then destroy system
Not really a "I need help post" but any advice per order would be nice
i dont know if its worth it to make specific groups for all the sub systems like movement life hit etc
Well it builds dependency, I feel like it would be bad to create a raycast between where the projectile was and where it is now before moving it to its new position. That would create a frame-lag for collision
So by creating the groups I don't have to really worry about a mess of update orders as the mechanics/system amounts increase
well just throwing it out there, i chained things pretty hard early on but with specific systems rather than groups(not sure if groups existed then), and ended up running into issues but maybe its not an issue with broader grouping
id rather have the system sort out my dependencies automatically and then if theres a specific instance where im not having the correct result, intervene ๐
I gotcha, thats how my project was until today. I created groups and then within the group, the systems are ordered relative to eachother. I feel like it localizes it pretty well and scopes to either low level or high level. But mainly I was curious about my group order. Like Network messages should be before Input and etc
Well when I say dependencies, I don't mean job dependencies. As a few of my systems have multiple jobs - I am referring to the projectile example. They should be moved before checking for a collision
While [UpdateAfter(T)] or [UpdateBefore(T)] work, it seems like it could get messy as the project grows without grouping
I'd suggest it only gets as messy as you let it. If your systems run sequentially but only five systems are in place it should be fine :)
can an ecs job yield or anything similar, so it can take a few frames to process the job?
Just for interest. Seems you work on a bit bigger projects already. What is your system count so far. I just want to get a feeling if I go with my ideas to granually or not.
Mine is pretty small - I will most likely only have 15 systems in the next couple days. Slowly expanding to make sure everything is done write before scoping out
upgrading to entities preview 31 made one of my systems stop work and I can't see anything the change log says I should be doing...
Serialized entities file format version has changed, Sub Scenes entity caches will require rebuilding.
What exactly does this mean? What is a sub scene entity cache?
Hmm I'll try upgrading again and see what happens
definitely something that changed from 30 to 31
the OnUpdate isn't called anymore...
in this one particular system
I have resolved the issue, but it may be a bug.
https://forum.unity.com/threads/upgrading-from-30-to-31-system-no-longer-executes.672349/
are you meant to use UpdateAfter and UpdateBefore a lot to order things, or is the point that unity will figure out dependency chains automatically and order things for you...
Pretty sure it should find out dependencies for you, and that you should avoid overusing UpdateAfter and UpdateBefore. I know that you might have to .Complete() on a job to
make sure that it is actually done, though I'm not sure how that relates to this.
@minor sapphire I'm pretty sure you shouldn't be creating an Entity via new.. also you will likely be causing your chunks to be invalid if you do it within a job like that - you should probably be using PostUpdate or a command buffer
Thanks @tawdry tree. @amber flicker im actually just creating an entity struct to use in an == comparison down the line. The reason I do it like that is because it said I can't store an Entity value itself in a shared component.
So I store the id and version directly instead lol
@crystal zephyr was that a question to me? My system count is still low - most of my own questions come from conceiving potential things i can do, i havent started most of them yet, i have a basic "ai" system, at it assesses distance to destination, and upon arrival, assigns a new destination in the form of a random positiin, and then their is the mover system, and the spawner system, i had a rotation system too, but its not needed - my use case is back ground simulations the player never sees.
Can anyone help with attempting to put in a delay, enabling a chunking system to process only a small portion of entities per frame?
I'd rather avoid just using bigass chunks tho, that defeats the point of ecs.
in case anyone wants to comment an idea/answer :)
Also, is there some way to see the size of the chunks being processed by a chunk system?
I know you can tell it what size chunks to aim for, but i wanna see what its doing naturally first :)
the entity debugger lets you see chunk size and allocation
@golden heron your post might be better off in the ECS forum. https://forum.unity.com/forums/entity-component-system-and-c-job-system.147/
i did try to look for an ecs setup heeh
like, a forum area
i have decided to try... something
my thought on your post is somehow using IJobChunk
yeah
and passing in your int
but I don't know how it will deal with entities moving around archetypes and stuff
im using an int which defines a value as a percent of how many ships to process, plus, the condition of a timer that must exceed 3 seconds
I mean you could have a component that says "last time processed", every entity would be processed but they would early quit, but that's not ideal
so, if the timer < 3 it passes and increments, or, if the percent of processed ships has passed a certain amount, it then passes regardless of timer value, and, it only counts a ship as processed if it has been instructed to move
then this all mostly happns in the ai system (as mentioned, not really ai, but thats where the ai will be)
and in the moverdata there is a bool marked "update this frame"
is it going to be ai in code? if/else?
atm thats the plan
anyways, the mover system is the only thing that can reset a timer on a ship, so, if the ship doesnt move, the timer cannot get reset, but it also only looks at the bool set in the ai manager system to define whether its gonna act.
the idea of processing a subset of entities per frame seems useful in many cases
something I considered also
Unfortunately, this means the entire set of jobs is now running identically, its just "flipping pages" past the entities i have defined, it doesnt actually remove a single iteration.
Im thinking of using one of the checks in the mover system - to define what ships it adds to its chunks - to check to see if the bool has changed, altho, i would like to find a way to do that, but also check its value...
OnUpdate runs on the main thread, so I wonder if you could use the concept of coroutines
it should be faster, but if this aint a jury-rigged solution nothing is hehe
how so?
get an entity list, then pass to action()s to coroutine? each action processes a percentage?
I think it would then take too much away from the burst compiler.
i need to iterate over every entity to check its timers, at least in one system
oh i see... still, i would like to keep to one type of jobbing, co-routines and similar have proven unpredictable in their cpu usage for me
especially ienumerators hhehe
Still, i figure in the worst case, the jury rigged solution will be avoiding a calculation of distance in oldschool math, a calculation of a normalised vector, and the addition of 2 vectors twice, as well as the application of a transform value, in favour of one case of addition and one of value setting. so either way, itll be a useful bonus, and later when the required calculations become more complex, itll become far more noticeable i think
FYI CommandBuffer.DestroyEntity seems to be capable of leading to a null ref exception. Started happening with preview 31.
bug report submitted
I'm downgrading back to 30, 31 is a bit terrible lol
although it does have a nice fix to the start up stutter
Question...What would be proper practice to scale a prefab? Currently, my handler function runs in the entity proxy, before it gets converted and added to the manager.
I'd like to do it in the prefab but...the attached script never runs since it doesn't wake or start
Well you could just scale the prefab by way of the old transform component, or use Scale component or NonUniformScale, but your script not working is a different story
Oh, sorry, I should've mentioned that it does work when I scale with the old transform. I was just wondering about practices.
The Scale component doesn't work yet ๐ฉ
im confused by your setup ๐ what are you using, the conversion workflow or old gameobjectentity?
conversion
entity => proxy => system? Per the ECS samples repo
Translate and Rotate work when being used in a Job and updated in the system.
But Scale throws a def error
whats the error?
Any examples of a working Scale implementation? I'm pretty annoyed about scaling before the conversion lol.
A component with type:Scale has not been added to the entity.
Which is true...it doesn't...but per the docs, it does?
Also tried scaling then passing a matrix4x4, no goes there either.
Maybe it has to be a ISharedComponentData
just add a scale component in your conversion script?
Hmm ok well before that....where does this Translation component derive from
CommandBuffer.SetComponent(index, instance, new Translation { Value = position });
I figured if Translation/Rotation was a default property, so was Scale?
But also, the IDE doesn't throw a type error when I am passing in the Scale float. I get the error at runtime when the scene plays.
So type wise...it's valid lol.
i might be wrong but i think the system assumes a scale of 1 if there isnt a scale component and one isnt added if the prefab scale is 1,1,1
so in your conversion script just do dstManager.AddComponentData(entity, new Scale()); or NonUniformScale
the conversion system automatically adds rotation and translation
OK there it is....it accepted NonUniformScale
Oh, adding Scale threw the same error fyi
maybe it was already added? if you dont add the nonuniformscale does a scale component show up on the debugger?
It shows up in the first chunk?
I have 2 chunks, its active in the first then throws up
but the entity in question shows up?
It shows up...in the debugger, yes.
Something doesn't seem to working properly for Scale I think? NonUniformScale is the defaulted component and not Scale. So I don't have to explicitly add NUS.
ok if i make a capsule and add convert to entity no scale or nonuniformscale is added by default if I dont change the scale of it from 1, nonuniform is added if I change it to a uniform size of 2
just checked and I dont think I ever use Scale, only NonUniformScale
hmmm 1 comma isn't enough for that message lol
if its 1, then nonuniform is added?
if its 2, scale is added?
no - old transform scale of 1,1,1 - neither scale gets added for ecs(only Rotation and Translation) with just a ConvertToEntity script and nothing more
if the scale of the old transform is added, then a NonUniformScale gets added along with Rotation and Translation, regardless if the scale is uniform or not.
I guess they assume most people wont use Scale over NonUniformScale so they only made the conversion system use the latter, but I would have to assume for certain use cases Scale would be preferrable?
Lol just 1 `
Sweet thanks for the tip
Transforming in the system was a little more performant as well
sup team o/
yo
does the burst compiler apply to jobs irrespective of ECS?
@minor sapphire yes
only requirement is that it's used in jobs right now
people have used it without ECS for a long time already
for example Unity's own ML-Agents new inference engine uses jobs and burst but not ecs
same with for example 3rd party asset Vegetation Studio Pro
I personally wonder the most how they are going to deal with the burst compilation for non-jobs code in the future
i thought it could be used outside of jobs
I can't imagine people putting all code in jobs and you need burst for determinism in the future
well, right now you can hack it to work outside of jobs
but it's not officially supported in any way right now
oh
so, I'm guessing they need to make it work outside of jobs before they launch the determinism thing
like, on official api
oh wow, someone actually did this https://github.com/ErikMoczi/packages.unity.com
that's the thing I asked Unity about (if they would mind if I did something like that) but they never responded
that's linked repo is pretty outdated already tho
hmmmm, on the burst thing
"Enable Burst Compilation: When this is checked, burst will compile jobs and burst custom delegates that are tagged with the attribute"
there used to be at least Burst.BurstDelegateCompiler.CompileDelegate in past
but when I google it, first search result points to docs page that doesn't exist anymore
any way to iterate over a NativeMultiHashMap?
Ah, I suppose GetKeyArray would do it
whats a good source for good recent pure ecs guides?
@dull copper you should update your pinned message with the @latest and @latest/index.html?subfolder=/ links kat talked about in #archived-hdrp a ways back
@solar spire I updated the links for manuals, still trying to figure how to get that syntax to work on API docs
updated the rest, thanks for the headsup ๐
4.5k ships, ~ 1.5k bullets. nearest enemy search is my bottleneck as far as I can see.
but it sure is pretty to watching them in slow mo lol
In case anyone wants to benchmark for me ๐ (space bar is slow mo)
http://download1.rolyd.com/Other/Space Battle Build.zip
off to sleep good luck ECSing friends
awesome stuff
Whats the best way to go about destroying entities?
i think creating/destroying is fastest done in batch on the main thread with the entitymanager but I just use command buffers
Yeah, pass in a NativeArray<Entity>
@minor sapphire I'm getting 40~55 FPS on my computer, if you were interested.
(AMD Ryzen 5 1600 6-core, Nvidia GeForce GTX 970, CPU bottlenecked)
@minor sapphire demo looks great, average 115 for a 8700k and 1070
@minor sapphire is that a system you'd be happy to share the code for?
Pretty sure shiny said it was more or less derping around to experiment, so I got the impression they'd be okay with making a Git repo or something. Of course, it's not my decision to make, but since they're not on...
Yep, i'll see what he says, im just interested in seeing some code to learn from.
I've got a cool ai scheduler setup going atm he might be interested in :)
would enable you to widen the cpu bottleneck quite extensively.
Altho to be fair, the idea isnt too complex, he may already have done something similar hehe
@Me if you reply, mr shinyclef! hehe
(Also thanks for answers guys)
Hello guys, I'm totally new to the ECS and would like to ask how to initialize a level. So what I've learned so far:
- components
- systems
- archetypes
- generate entities via entityManager
But how would you initialize GameObjects (/Prefabs) that are already in your scene? Would you add a "init script" to them that creates their required logic and destroys itself when finished?
The player would be a good example
conversion workflow https://forum.unity.com/threads/new-subscene-converttoentity-workflows.638785/
@safe lintel this is for me, right =?
yes
thank you
Thanks guys. Interestingly scaled better on the core speed rather than the thread count.
I'm thinking of making something in the vein of a 2d 4x space sim ala x reunion or so. Not sure yet. Also it has a couple of paid assets in there so I can't make it public but I'd be ok to share privately @golden heron
I'm heading off to work so I'll be out for the next 10 hours though heh.
DM Me, @minor sapphire. Im already half way there ๐
I am trying to work my head around the transform system. So for a child, to get its world position, you use the LocalToWorld component on the child. While LocalToParent is the child's world position offset from the parent's world position, right?
Glad they have this doc though:
https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/transform_system.html
im glad they got rid of the ascii art diagrams for that
@minor sapphire
Ty :)
Hmm
So how do I dispose of a NativeArray (or something else that natively allocates) in a SharedComponentData?
Is there an event when a SharedComponentData is no longer associated with any entities?
- You can use native arrays in IComonentData?
- A system will need to dispose. You can use ISystemComponentData to keep track or what's getting destroyed. it's explained in the Manual.
- No, but you can apparently use it in ISharedComponentData
- Okay.
- (at least that's the only way I can think of ๐)
Ah okay
If anyone has an ideas, I'd like to hear it.
Ahhh this is the frustrating thing about coming from C++... other languages are like "Hey we got this awesome idea to solve the memory leak issue" and it's always like three times more complicated than a simple destructor... ... ...
Even C#'s like "Hey, look at dispose" and it's like "Yeah. I do look at the Dispose pattern. I see three-or-four cases that are not entirely obvious which I should destroy what in."
Sorry for the rant lol
maybe always keep one entity that has a special or singleton ComponentData and if that is the only entity with the ISharedComponentData that exists, dispose?
Anyone got a multiple worlds Setup with a simulation world and a render/presentation world?
Hmm ill post on forum..
does anyone know if it's possible to use a JobComponentSystem to get a GameObject's script? Something like this ->
someClassScript = GameObject.Find(SomeGameObject).GetComponent<SomeScript>
the system itself runs on the main thread, I would imagine it's possible
but not from a job
don't see why it wouldn't work
hmmm
okay
i'm trying to get the script in OnCreateManager() method, but I get a NullReferenceException error even though the script is on an existing game object
I'll try using a ComponentSystem
If I try the above I get a null return for the gameoject
Trying to get an entity array to read from in my chunks job, any ideas?
The actual issue, is wanting to use a commandbuffer in the chunk system to add and remove components from entitys in the chunk
but i need an entity reference and a comm buffer, both seem unhappy in there, any ideas how to go about it ?
@unreal tundra is your object one which is unique? Or one of many?
it's unique
Then can you use a singleton pattern to send the reference in without a search?
Reference the singleton from a main thread job, maybe?
As you mentioned, with a componentsystem
Then the line is better for cpu as well.
I'm sorry, what would be a main thread in this case
ok, just a mo then ill explain
In simple terms, data is looked at by systems, and, dependent on how much data spread across however many entities and so on, it defines what jobs and how ,any are sent to the job system.
The basic bonus of ecs is using multiple cores, and, unity's oldschool methods would all have been on "the main thread". The main thread is special as it has better access to memory without allocation errors caused by two threads trying to modify data simultaneously. All the jobs are either "main thread", where you have more control, and better access, or another thread in the job system which will suffer limits to its memory access for the sake of thread safe code.
However, if all your code runs on main thread, your multiple core pc/device is wasting its other cores.
The part which defines whether jobs are main thread or a background jobs thread is which choice of system type you inherit from. ComponentSystem is purely main thread, whilst most of the others are not.
That being said, if you send a billion jobs to the background thread, and one job to the main thread, the main thread will also seem to be processing background tasks. This isnt the case, what actually happens is that the main thread then pushes the jobs to finish, and begins to finish them using the main processor, but its still not actually in the main thread.
Does that make sense, @unreal tundra
?
yes, that was a great explanation!
My pleasure :) let me know if anything might warrant further explanation :)