#archived-dots
1 messages ยท Page 82 of 1
that's at the start of the program, the framerate settles down to about 120fps
Ah oke, I might be confused then since it ran in the simulation system group
I should probably schedule the job a bit later and see what happens
As for your earlier question, yeah would love to see that code
always interested on how others use jobs
sure
[RequireComponentTag(typeof(Business))]
[BurstCompile(CompileSynchronously = true)]
struct AssignEmployeesJob : IJobForEachWithEntity_EBC<EmployeeEntitysArray, EmployeeEntityInfo>
{
//[DeallocateOnJobCompletion]
public NativeArray<PersonEntityInfo> personworkplaceref;
//[DeallocateOnJobCompletion]
public NativeArray<Entity> dudes;
public void Execute(Entity currentbusiness, int index, DynamicBuffer<EmployeeEntitysArray> currentbuffer, ref EmployeeEntityInfo currenbusemployees)
{
if (currentbuffer.Length < currenbusemployees.NumberofEmployees)
{
for (int i = 0; i < currenbusemployees.NumberofEmployees; i++)
{
for (int m = 0; m < dudes.Length; m++)
{
var currentdude = personworkplaceref[m];
if (currentdude.WorkPlaceEntityRef == Entity.Null)
{
currentdude.WorkPlaceEntityRef = currentbusiness;
personworkplaceref[m] = currentdude;
currentbuffer.Add(dudes[m]);
break;
}
}
}
}
}
} ```
Okay I keep getting Hybrid renderer compile errors in 2019.3. Is it still broken?
ex: The type or namespace name 'HDPipeline' does not exist in the namespace 'UnityEngine.Experimental.Rendering'
@analog tangle it's still broken
it's also more than namespace change
but that's one of the things the need to be fixed
I find this method in unity's code to be quite interesting.
public void AddComponentFromMainThread(NativeList<EntityBatchInChunk> entityBatchList, ComponentType type, int existingSharedComponentIndex)
{
using (var sourceBlittableEntityBatchList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var destinationBlittableEntityBatchList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var sourceManagedEntityBatchList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var destinationManagedEntityBatchList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var packBlittableEntityBatchList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var packManagedEntityBatchList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var sourceCountEntityBatchList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var moveChunkList = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
{
// [... stuff...]
}
}
You get the impression from the docs that it's better to use a temp allocator for short lived native stuff. But then you see this ๐
I wonder why its a list instead of an array
I've been trying to fix up the CreateArchetypeChunkArray to be off the main thread when using a filter all morning
And I just cant xD because its using a NativeArray as return type, instead of the NativeList..
cant you then convert the nativerarray to a nativelist?
No, though that's not the issue
that method looks nasty, runs like 4 jobs
i feel like the variable names are way too long and EntityBatchList could just be shortened to List
or just make each thing plural: sourceBlittableEntities, destinationManagedEntities, etc.
Why would name lengths matter? The more something describes its content, the better
it totally matters
your names should be as descriptive as possible, yeah
but they should be as descriptive, but as as short as possible
let's assume your character has a name "Super Mario", you wouldn't call its x position: SuperMarioXPosition would you?
you would just use x
short, descriptive, easy
if i had to debug anyones code who gave me a literal essay with their variable names, i'd just tell them they're on their own
because it is a killer to readability
I think thats a bit of an odd example
You'd have something called position , which has an x and y variable
if you had another script that needs to use the position of a player, or maybe a target
you'd call it targetPosition or playerPosition and not use position
yeah I would rather call something supermarioxposition to be honest thats more readable than x to me, x could mean anything
The goal is that through properly named variables, types, and functions; A reader knows what your code does, without the use of comments. (Though there is always an exception for more complex areas)
x really couldn't mean much else
you are familiar with the cardinal directions, right?
north east south west?
wait no i got the name wrong
cartesian
point is, if you know anything about the xyz directions, you know that x is an x position
if you want a target position, you'd have xTarget
x is also commonly used for displacement
so there is absolutely not reason why x would be ambiguous
I don't know that involves more knowledge when you could just get that direct from the variable
plus that doesn't always work when you have complex types
how much additional information are you going to get from supermarioposition when: 1) you know x is already a position because it is a ordinate, 2) you already know it's super mario's x position because the variable is either in a class called SuperMario, or you used an instance method of a SuperMario object to get that x position, i.e. var x = New SuperMario().X;
you're right, but having complex types should give you an even higher incentive to name your variable concisely because you want to avoid confusing
extraordinarily long variable names cause confusion
only have information you know 100% describes what that variable does
you don't need the extra fluff just because you think it might "help tell the user that this is, in fact, the x position of a super mario object, just incase you didn't know that even though i got the value from the object named super mario, using the instance method called X."
it's just not neccessary
yeah I do just name them and try shortening a bit
it does confuse me though when people name variables after the type like this EndSimulationEntityCommandBufferSystem m_endsimulationentitycommandbuffersystem
what's the best way to stop jobs from running when they are created?
I'm guessing using the OnCreate() method? using an external job or other outside method would be unreliable
x could be rotation, or scale
I would never sacrifice description for length
xPos would be a huge improvement
shortening entityBatchList to list would not be something I would be in favour of
please observe how many lists are in the that scope...
deciding that one of them should get the name list is not a great idea lol
that... wasn't my point
public void AddComponentFromMainThread(NativeList<EntityBatchInChunk> entityBatchList, ComponentType type, int existingSharedComponentIndex)
{
using (var sourceBlittableEntities = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var destinationBlittableEntities = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var sourceManagedEntities = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var destinationManagedEntities = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var packBlittableEntities = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var packManagedEntities = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var sourceCountEntities = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
using (var moveChunks = new NativeList<EntityBatchInChunk>(Allocator.Persistent))
{
// [... stuff...]
}
}```
even if it's marginely smaller, it's still a lot better than having EntityBatchList on the end of every single one
which is redundant and disgusting
If I were to read it now, it feels like sourceBlittableEntities would be a list of entities, which it is not
@stiff skiff i'm curious, what is your motivation for messing with CreateArchetypeChunkArray ? you're trying to get it off the main thread?
As to your question earlier on overhead, from what i've measured in the past, i think youre going to be int he region of .0100-.0500 ms per job without work. The base minimum is .0040 ms for a run() on my desktop machine. But i've seen as low as .0009 ms in the case when you immediately run() the same job again and have a custom setup. Which is about 3x slower than a standard c# property access. So there's a threshold of how much work needs to be done to make it worthwhile. I haven't recently measured the ECS jobs, but i suspect they're significantly more costly than working in pure burst/jobs.
Yeah trying to make it not block the main thread
The non-filtered one doesnt block. But with a filter it blocks for most of the heavy work
i might have a play with it tomorrow.
this was todays experiement. https://gist.github.com/jeffvella/972a59db7a1234f3098787df84e48eb3
The issue I've found is allocating the NativeArray for the final result
without a filter, this can be done at the start, but for the filtered one, it is down in between 2 jobs
And I've been unable to move this to a better place
Hey folks, I have been converting my 2D project to ECS over the past few weeks, and I am wanting to make the leap from A* pathfinding to a good ECS approach for navigation. So far I have been looking over the project in this post: https://forum.unity.com/threads/100-000-entities-traversing-navmesh.534526/
I am really impressed with the quality and performance seen, but I have some concerns with compatibility since this was last updated over a year ago at this point. Does anyone have a good place to point me for ECS navigation approach, or do we think this is still viable?
i'm looking at using goal based pathfinding for my 2D project. I'm still not sure how parallelizable it is though.https://gamedevelopment.tutsplus.com/tutorials/understanding-goal-based-vector-field-pathfinding--gamedev-9007
Anything which has previously worked in ECS should still work, though work may be needed to get it up to date with the latest APIs
Thanks guys
@vestal hatch that vector field solution looks pretty interesting. @winter depot Might want to look at a normal 3D burst job A* https://github.com/jeffvella/UnityAStarNavigation. Or here's the basic solution for NavMeshQuery https://forum.unity.com/threads/how-to-use-navmeshquery-get-path-points.646861/#post-4351057 which you could adapt for a simple version using the Navmesh without going full on ECS.
@dull copper Cool. Good to know.
@mint iron Thank you
oh god, have I misunderstood NativeMultiHashMaps entirely? They allow duplicate keys?
I guess I better check my usage to see if that's a bad thing in any places.
that seems like it should be impossible
Look at this post:
https://forum.unity.com/threads/whats-the-best-way-to-get-the-nativemultihashmaps-unique-key-array-for-jobs.711185/
It seems like it must be intended behaviour
I guess I just assumed similarities with HashSet that I'm used to from standard/managed C# land
Anyone have a simple example of using full ECS and unity dots physics?
I've got ECS to work fine. I just can't seem to get the body to move by velocity.
Anyone know how to recreate entitymanger after recompiled?
@pastel hemlock you can download here https://github.com/Unity-Technologies/EntityComponentSystemSamples
@faint scarab that repo doesn't have example of what tomgie asked
he's asking about using Unity Physics with full ECS, not through conversion system
all physics examples on that repo are using gameobject conversions
There are examples of making physics components via code. Whether it's on a monobehaviour or through a system I don't really see the distinction if it gets converted into a pure ecs representation
Anyone using latest entities with 19.1 or 19.2 and getting black materials when gpu instancing is enabled on objects in subscenes?
I tried adding a few things from the example and nothing has seemed to change on the entity besides having the components.
So Im not sure if I am going against the spirit of ecs but is there a good way to build something like an energy transfer system? So say something like how wire works? A source entity that transfers energy to a wire?
I don't have any issues getting the data structure working but I can't seem to figure out how to actually model the transfer system itself
sure, isnt it just transferring a value, turning a switch from 0 to 1
The simplest way would be to essentially make a 'network' of everything connected by wire (update only when needed) and then set a value as you need. For example, pulling a lever could set it to 1, or you could have power generation/consumption and something which adds it all and decides what to do. A lot of it is design; how do you want it to work? if you want transfer to take time and have resistance and such that complicates things.
Not sure if I properly conveyed my thoughts, but tl;dr you can (probably) simplify it to one network with one state (0/1, power level, etc), which is essentially the sum of everything on the grid. And consumers use that value.
Way past bedtime and I have a mild headache (probably form staying awake too long), so I could probably explain better but now bed kthxbye
so i saw you can add/remove components during iteration now, but wouldn't it still be better to do it with ECB?
or rather, when is it better to do it during iteration?
I think you still use the ECB to do it
it just doesn't wait I think, I tried it anyway and it seems to work
I dont think theres any reason to use another method to be honest
I think it was about roughly 3ms to add components to about 2000 entities, burst doesn't currently work with it but when/if it does that will go way down even further
like vblanco said, it's a pretty big and hard to implement feature so i doubt they'd do it for no reason
maybe @vagrant surge can shed some light
so even more reason to use it surely
ECB?
well unless theres some other method, Entity manager doesn't work that's the only way I've seen
oh then we're talking about different things
i was referring to this in the new entities update
Allow structural changes to entities (add/remove components, add/destroy entities, etc.) while inside of `ForEach` lambda functions. This negates the need for using `PostUpdateCommands` inside of ForEach.
yeah i know
struct AssignUnemployedCompJob : IJobForEachWithEntity<PersonEntityInfo>
{
public EntityCommandBuffer.Concurrent commandsBuffer;
public void Execute(Entity currentent, int index, [ReadOnly] ref PersonEntityInfo currentcomp)
{
if(currentcomp.WorkPlaceEntityRef == Entity.Null)
{
commandsBuffer.AddComponent<Unemployed>(index, currentent);
}
}
}```
that's what I used to add the component, unless I'm mistaken and that's not working how I think it is
yea nothing changed for jobs i think
for main thread ForEach iteration you'd use PostUpdateCommands to add/remove components
but now they made it so you don't need to use that anymore you can do it directly i think
but that's what the above code is doing? the code above isn't using a PostUpdateCommand
you're using a entitycommandbuffer there
but what else would you use?
add it through the entitymanager directly
I tried that, you cant pass entitymanager into a job because its a reference value
that's what i said ๐
my question is about main thread ForEach iteration not jobs
Allow structural changes to entities (add/remove components, add/destroy entities, etc.) while inside of `ForEach` lambda functions. This negates the need for using `PostUpdateCommands` inside of ForEach.
that's about jobs though?
i assume ForEach lambda functions specifically refers to the ForEach lambda that you use inside a non-job ComponentSystem to iterate on main thread
Entities.Foreach are what work in a main thread component system though
yea that's the one
previously you had to do PostUpdateCommands.SetComponent etc, i assume because changing arrays while also iterating them is dangerous
but seems they now figured something out for that
my question is does this actually 'negate' PostUpdateCommands like the changelog suggests? i imagine there would still be some difference?
or can we just ignore PostUpdateCommands now?
Foreach Lambda's aren't exclusive to non jobs, anyway I think my code above is doing what they are stating its not using postupdatecommands
but you wouldn't use PostUpdateCommands in jobs anyhow
you'd use a different ECB and PostUpdateCommands is just a ECB from what i gather
and you're still using a ECB
yeah but point is they made them unnecessary on main thread
well I'm happy to be corrected if I'm wrong but that code I used above does not take place on the main thread
yes it definitely does not
and that is part of the reason why it has nothing to do with the change i referenced
fair enough if you figure it out, I'd love to know
Do anyone know how can i recreate entity manger after recompiled?
but that code I used above does not take place on the main thread
The ECB commands can be used from another thread, but it effectively just shoves your command in a queue. Most of the actual the work involved happens later when its processed on the main thread.
@hollow sorrel the idea is that such a thing would NOT use command buffer or post update commands
just add the entity "inline" while iterating
I don't understand this then, if addcomponent in the ECB is just queueing the command then where in the main thread is it
its supposedly taking quicker to add the actual component in the main thread than it does to queue the command which seems kind of insane to me
@pliant pike its not insane
at all
my crappy ECS i made in C++ (unity style) can add/remove components while iterating, but it will break real easily if you arent careful
unity seems they have done it properly
i think the new one works by adding/removing the component "instantly"
no deferred like ECB is, where it will add it later
this is much faster because it has far better memory/caching properties
well i mean adding and removing is surely a more complicated cpu intensive process than just queueing a command
its about the memory caching
both add/remove component are "archetype move" operations
it needs to clone the entity into a different memory chunk
if you do an archetype move while you are iterating a chunk, you already have that chunk in memory
and only need to load the target chunk
and if you are adding the same component to multiple entities in the same chunk, then you also haev the target chunk loaded in cache
ECB is much more random than that, so the cache loading isnt as good
plus the overhead of threadsafe queue push
and anyway you can see that the whole AssignEmployeesJobComponent ends before the workers and it then starts the next Job
is there a way to stall the Convert method from IConvertGameObjectToEntity interface so I can initialize some variables first
ah nevermind i guess i just add convertToEntity script later
ahhh that makes sense, thanks @vagrant surge
hi all, anyone know why this simple code is now causing errors in my entity debugger window?
{
EntityManager entityManager = World.Active.EntityManager;
Entity entity = entityManager.CreateEntity();
}
What error does it give?
linq system contains no elements error
and pushing more gui clips than you are popping
strange, pretty sure it never used to before update
System.Linq.Enumerable.Last[TSource] (System.Collections.Generic.IEnumerable`1[T] source) (at <b7efe7e6e548497fac3c4a6049a0a4b6>:0)
Unity.Entities.Editor.EntityQueryGUIControl.UpdateSize (System.Single newWidth) (at Library/PackageCache/com.unity.entities@0.1.0-preview/Unity.Entities.Editor/Common```
quicker to add the actual component in the main thread than it does to queue the command
Using EntityManager directly should currently be faster overall because if you look at the code for ECB, its just using the exact same EntityManager methods you would have used, and its being called in a standard system Update method. But you also have added the overhead of scheduling the job, queueing the commands, possibly allocating, then looping through them all again and copying more stuff around.
I do think though, that even if its slower, it can be cleaner. And eventually it will be faster once they have fixed the ComponentDataStore to be able to make structural changes in burst. Then the ECB can really fly and if your code is already using it, you're probably ahead of the game.
yeah thanks, I was just confused with how it worked and what I was seeing
I'm getting a weird error I've declared this variable readonly I think csharp currdudeswages = GetComponentDataFromEntity<MoneyEntityInfo>(true) and yet I'm still getting the warning CalculateBusinessWages.Data.currdudeswages is not declared [ReadOnly] in a IJobParallelFor job. The container does not support parallel writing. Please use a more suitable container type.
well you are still trying to write to it even if you've marked it ready only
currdudeswages = x; is writing to currdudeswages
maybe post some more context. What type is currdudeswages? what are you trying to do?
but that's to get it into the job
i see, still more context would help
I'm not even doing anything in the job currently just testing public ComponentDataFromEntity<MoneyEntityInfo> currdudeswages; that's where its going to inside the job
I guess I have to declare that readonly too
I've declared it readonly inside the job but now I'm getting the error The writable NativeArray CalculateBusinessWages.Iterator is the same NativeArray as CalculateBusinessWages.Data.currdudeswages, two NativeArrays may not be the same (aliasing).
I'm guessing its because I already have a foreach that's iterating through the moneyentityinfo component
is there not a way of excluding some entities in the ComponentDataFromEntity
i have two sets of entities using the same component but in different ways
just use the componentdatafromentity as you can already get the entity via the job
but then you need to write to it
how do I do that, componentdatafromentity doesn't work
this is the job code ```csharp
[RequireComponentTag(typeof(Business))]
struct CalculateBusinessWages : IJobForEach_BC<EmployeeEntitysArray, MoneyEntityInfo>
{
public int Globalwags;
[ReadOnly]
public ComponentDataFromEntity<MoneyEntityInfo> currdudeswages;
public void Execute(DynamicBuffer<EmployeeEntitysArray> currentemployee, ref MoneyEntityInfo currBuswages)
{
//currentbuswags.Wages = currentemployeenum.NumberofEmployees * Globalwags;
}
}```
I need to get the moneyentityinfo componentdata from the entity inside the dynamicbuffer of each entity
well remove moneyentityinfo from the job part, and then use [NativeDisableParallelForRestriction] instead of readonly and also
dont set read only to true when you pass it into the job
and then use IJobForEachWithEntity_B<EmployeeEntitysArray>
but I need the moneyentityinfo to write to on the main job that's the main goal, search through buffers entitys find their wages, then total and write that to the business wages
so -
currdudeswages = GetComponentDataFromEntity<MoneyEntityInfo>()
[RequireComponentTag(typeof(Business))]
struct CalculateBusinessWages : IJobForEachWithEntity_B<EmployeeEntitysArray>
{
public int Globalwags;
[NativeDisableParallelForRestriction]
public ComponentDataFromEntity<MoneyEntityInfo> currdudeswages;
public void Execute(Entity entity, int JobIndex, DynamicBuffer<EmployeeEntitysArray> currentemployee)
{
if(currdudeswages.Exists(entity)
{
var wagesData = currdudeswages[entity];
//stuff
currdudeswages[entity] = wagesData;
}
//currentbuswags.Wages = currentemployeenum.NumberofEmployees * Globalwags;
}
}
that's great thanks, I was just thinking Ijobforeachentity
Hey guys,
learning ECS and everything seems to be pretty clear except one thing - world building using pure ECS
How do you build scenes in Unity editor when entities become visible only during runtime ?
Do you have to use Hybrid ECS for projects that need Unity editor to build worlds and pure ECS is reserved for 100% procedurally generated games ?
and a small question regarding the ECS samples repo - what's the latest proper way of installing sample projects ? I haven't used Unity in a while, and vaguely remember using asset store to import sample projects, but seems like it was changed since then. Do i just clone it and open them with Unity?
I've got a question.
If at one point my system will set a struct for a component that will be equal to what it was before, will it mark the entire chunk as changed for SetFilterChange?
It even marks it already if you attempt to write something, mean whenever you request the components without read-only a change will be detected.
@frigid badge Regarding the samples from unity, I clone the repository and leave it in its own project and look things up there.
@frigid badge For building the "static" parts of a world you want to use the conversion workflow and maybe even the subscenes.
Thank you, materials i found were missing those keywords, immediately found a bunch of manuals after searching for those terms
Before I spend hours being a maths idiot, I think I'll ask first...
Anyone know how, using new mathematics, to set an objects local y rotation?
quaternion newRot = existingRotQuaternion.SetLocalYRotation <-- that just about sums up what I'd like to do, but I hate quaternions... lol
@minor sapphire afaik for now you gotta do the maths but here it is: //// roll (x-axis) float sinr_cosp = +2.0f * (q.w * q.x + q.y * q.z); float cosr_cosp = +1.0f - 2.0f * (q.x * q.x + q.y * q.y); float roll = math.atan2(sinr_cosp, cosr_cosp); //// pitch (y-axis) float sinp = +2.0f * (q.w * q.y - q.z * q.x); //// use 90 degrees if out of range float pitch = math.abs(sinp) >= 1f ? math.PI * 0.5f * math.sign(sinp) : math.asin(sinp); //// 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 yaw = math.atan2(siny_cosp, cosy_cosp);
do you want to add a rotation amount onto the existing/current one? or just set it?
have a look at quaternion rot = quaternion.AxisAngle(Vector3.up, math.radians(degreesAngle));
AxisAngle looks like it will give me a quaternion by rotating one axis from identity by an angle
there are also quaternion.RotateX(.. methods so you can e.g. set a quaternion to an identity then rotate to a specific value
from the current value by an angle
interesting, I need to consider the options...
but looks like dinner now, I'll be back a bit later ๐
enjoy ๐
ty
Hi! I know this isnt strictly ECS, but is there no way to Debug an IJobParallelForTransform?
I cant figure out how to schedule it so that I can attach debugger, or use debug.log. IJobExtensions has something called Run(), but it doesnt seem to support IJobParallelForTransform
(The scheduling takes place in a regular ol' monobehaviour)
@tidal plume You can use debug log inside a job I think, so long as you disable burst?
@minor sapphire there are also the rotationeuler components
๐ฎ I have not heard of such things lol I better check
oh interestiinngg
the transform system is much more in depth than I realised
not sure if this is the right channel but i'll ask anyway. I have been using projectors to display circles around these essentially chess pieces in my game, but I now want to change the size of these circles in game and making the projector larger makes it pixelated. is there another solution for this people usually do?
It's not the right channel. Maybe general code. Haven't worked with projectors. Texture size/resolution?
Could be one of the art channels...
Anyone ever change "Order in Layer", on the Sorting Group component, from within a timeline?
I'm on 2018.3
@verbal flint this would belong in #๐ปโcode-beginner I think. Not in this channel
oh, there's new hybrid package
well, now it finally works with latest 2019.3 alpha and it's HDRP out of the box ๐
@dull copper they improving hybrid ecs stuff?
@vagrant surge this mainly fixes the errors on latest 2019.3 alpha
## [Hybrid Renderer 0.1.1-preview] - 2019-08-06
### Fixes
* Adding a disabled tag component, now correctly disables the light.
### Changes
* Updated dependencies for this package.```
@vagrant surge at this point, I wouldn't expect to see major changes on DOTS for next month or so
that is their main event after GDC this year
and in past, Unity has liked to keep something hidden for DOTS for these events
they allways do some DOTS related cool thing on them
so lets see what they will show
maybe a new demo
they are working on a DOTS based game AFAIK
but I dunno if it's far along for them to show it yet
I dunno if it'll be like full game but bigger than fps sample
ikr
as for tech demos, they are working for sequel for the heretic demo shown at GDC
but that's unlikely to utilize DOTS much
what i dont like about unity demos
is how incredibly unstable they are
and hacked together
isn't that like every tech demo ever made?
well, look how long it took them to polish those demos
and so do all of their samples/test projects
I'm sure they were nothing like that when initially shown
well yeah, but the first public version is pretty stable and they keep them working well on newer engine versions
kite demo is still quite hacky
kite demo is the hackyest
but for example ShooterGame is MILES ahead of FPS sample from unity
the hackyness of the FPS sample is insane
the newer raytraced ones arent published
you can get the runtime for the star wars one, but not the project
they've kinda showcased others demos for many years
I could see legal issues on distributing the SW assets
so, wouldn't expect to see the source project
the troll demo is likely
the one with the princess on the lake
but they dont have those features in public unreal yet
so gonna take a while
well ilm xlab made star wars demo i think, doubt they would even want to release any asset/sources
i hope they have a better roadmap talk at this unite ๐ฌ
what i wonder. If unity is really doing a new game on the ECS stuff
are they using the conversion workflow?
probably :p
because Joachim said they'll make the conversion workflow thing in final release too
if you use Unity's DOTS physics package today, Unity enforces the conversion setup heavily
they don't even support if you use it on full dots setup atm, even tho it will work
so I guess we finally get the full dots setup in 2022 like the roadmap showed ๐ค
booo! i just want to hear more tbh, dont mind if plans change but i want blog updates or something, like a fly on the wall type eavesdropping ๐
I have a question about pathfinding, hopefully someone is around for a quick answer. Essentially I am getting closer to figuring out what needs to be done to convert my A* pathfinding to pure ECS, but I have seen some solutions done different ways, although some of the solutions are 6 months or older. I was wondering what the current best standard likely is... In my particular case I am working with a 2d grid project, and I would prefer not to use conversion to make NavMesh compatible, to then use that as a reference in the ECS system. The two approaches I am seeing are either making each node an Entity, or create a buffer entity with all of the nodes in that one entity. My hope is to get this into a jobsystem with burst and not have to use GameObject's at all. I have most components in my game working in pure ECS, but pathfinding is the one thing that has had me stumped. Thank you in advance to anyone who takes the time to reply
I have already seen a large amount of resources with information on other people running A* in ECS, but unfortunately most are using 3D with NavMesh doing the heavy lifting. I want to maybe create a hashmap or a sharedcomponent to hold my data and avoid conversions
This seems to be the best resource I have found so far https://forum.unity.com/threads/pathfinding-ecs.542882/ along with https://forum.unity.com/threads/ecs-grid2d-pathfinding-example-and-feedback-on-how-to-improve.591523/#post-3961198
I'm having a bit of trouble with how to handle pathfinding! I'm trying to make a game with minions that do tasks like build and fight. I'm having...
i think you might be best off posing this question to the forums, so more eyes can give feedback on this scenario
@winter depot maybe this guy's blog posts help:
https://coffeebraingames.wordpress.com/2019/04/14/how-fast-could-burst-compiled-a-be/
https://coffeebraingames.wordpress.com/2019/05/19/from-160-to-300-a-requests-per-frame/
@hollow sorrel Thanks man, I actually checked that out earlier and because its just showing a small snippet and based on what he's saying it sounds like he is using a hybrid system with the grid on game objects, as well as a in ECS data and just keeping them synchronized. I will look over it in more depth to see if that's accurate or not. Maybe I do just need to settle for hybrid
I have question about parent child relationship. I have been doing destroy parent entity then child entities destroy together without any system. It work like gameobject parent-child relationship. Do anyone know how can i figure out it?
if you use the LinkedEntityGroup, when you destroy an entity that contains that buffer, all entities in that buffer should be also destroyed
Its that use like icomponentdata? I never see before ibufferelementdata. How i use it?
I try to add component to parent entity use code is "world.active.entitymanager.addcomponentdata(paraententity, new linkedentitygroup{}); but it is not working for me
primer for dynamic buffers https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/dynamic_buffers.html?q=dynamic buff
Hey there, I'm trying to make it so that when a player dies in the FPS sample, their collider box is deactivated so that others don't bump into it after death
but it appears that I can't figure out how to achieve this
Since hitCollisionOwner.collisionEnabled = false; does nothing
I've tracked it down, I think, to the Update() in the "HandleDamage" class inside "CharacterModuleServer".
The entire thing is here: https://pastebin.com/eMwJnnnj but I believe I'd need to make a change at the bottom of the method here specifically:
// What about taking actual damage in this area? Should I test this? Nah...
if (isDamaged && !isHealing) // If healing skip this, so it won't appear as taking damage while healing
{
var damageImpulse = impulseVec.magnitude;
var damageDir = damageImpulse > 0 ? impulseVec.normalized : damageVec.normalized;
charPredictedState.damageTick = m_world.worldTime.tick;
charPredictedState.damageDirection = damageDir;
charPredictedState.damageImpulse = damageImpulse;
if (healthState.fallDamage)
healthState.fallDamageTick = m_world.worldTime.tick;
// If fall damage, damageFall will have same tick as damage tick
EntityManager.SetComponentData(entity, charPredictedState);
if (healthState.health <= 0)
{
var ragdollState = EntityManager.GetComponentObject<RagdollState>(entity);
ragdollState.ragdollActive = true;
ragdollState.impulse = impulseVec;
hitCollisionOwner.collisionEnabled = false;
}
}```
As you can see, I've already turned collision off but no dice
are you sure that the struct that is the hitCollisionOwner is actually a ref and the data is applied back to the entity? I'd assume it isnt and you need to actually set the data
Question is, if it's not a ref, how would I do that?
As you can see here, when the player dies, a ragdoll is spawned (lower right corner)
And active
And so I assume that when this is done
var ragdollState = EntityManager.GetComponentObject<RagdollState>(entity);
ragdollState.ragdollActive = true;
ragdollState.impulse = impulseVec;```
It's referential magic not value
GetComponentObject can return a class, but the issue you say is in the HitCollisionOwner, which is passed in at the top there and we can't see if its a struct (or if its fine to pass it without ref because its containing a pointer)
@winter depot you wouldnt use the ECS itself for pathfinding, more like the burst/job stuff. For a 2d grid, you probably want to "copy" your grid data into native arrays, and use them from a job. you can then create a parallel-for job that calculates all of the pending pathfind requests at once
@mint iron It's a class, not a struct (I found out)
And I have made this...."solution"
var players = GameObject.FindObjectsOfType<GameObject>().Where(x => x.GetComponent<CharacterController>());
var deadPlayer = players.First(x => x.GetComponent<HitCollision>().owner.Equals(hitCollisionOwner));
deadPlayer.GetComponent<CharacterController>().height = 0;
deadPlayer.GetComponent<CharacterController>().radius = 0;
From what I read on the bus home (so on my phone, skipping all code, and not too deeply), the Coffee Brain Games blogs should at least give the general idea of a way to do it. Like... pattern/framework level, 'use these principles and mechanisms' at least.
Some translation would be needed, of course.
@vagrant surge thank you for the response. I understand what you mean, and I guess I must be misunderstanding the capabilities of ECS at this point. My goal was a pure ecs solution, not just hybrid or do the heavy lifting in jobs then sync with game objects. If I have all my targeting, damage, animation, core content of my project in pure ecs it feels kind of bad to just have empty Game object transforms just for pathfinding purposes
@winter depot its very important to understand that not everything needs to be put on the ECS
I do believe the solution they gave had all the pathfinding in pure DOTS (mostly burst jobs)
you can have something like a PathFollow component, or PathRequest component, that fits well. But the pathfind algorithm itself shouldnt be done on the ECS itself, but on some custom data structures/arrays and burst/jobs
a lot of pathfind systems like to have the nodes as individually allocated things, but that doesnt work well on burst
you generally just want to have a simple array of PathNode , and each pathnode connects to others through their index in the PathNode array
works like a charm (and its extremelly fast)
Right. I think I get that part of the ordeal, it just as I said, think I may have misunderstood the limitations. I fell in love with the ECS approach, and wanted to make it fit everywhere. Here is my post for forums https://forum.unity.com/threads/planning-a-2d-grid-pure-ecs-job-burst-pathfinding.724211/#post-4835492
The blog posts built those arrays from gameobjects, but only when a tile changed, so quite rarely, and then cached and used them until they needed to be rebuilt.
@tawdry tree yeah, itโs sounding more and more like I need to use a hybrid approach
It doesn't need to have any gameobjects
keep in mind one thing with the ECS itself. Grabbing data from arbitrary entities has a cost
its not that much, but is bigger than indexing an array
Well I guess in their scenario it was confusing because they needed to convert, but you are saying itโs viable without
They had to use gameobjects, as their game was already heavily OOP
Thatโs why I wanted to use a buffer for the nodes, instead of 500entities+
In other words, they were locked in. You are not.
@winter depot the main thing is that you would have some kind of PathfindManager or whatever, and that holds arrays with the path node data. You then have some burst job where you just input those arrays + a "request", and returns a path
I see other places unity members saying use dynamic array instead, and hold data as persistent. And others saying native hashmap as the way to go
@winter depot use both
the hashmap is to access nodes by name
and the array is what its actually used for the implementation
gonna show you how i did this (on C++, unreal, but its literally the exact same concept)
So the hashmap is to replace the need for โparentโ struct referencing that canโt be done in structure
As I see it, the general procedure would be:
-Form your level with ECS, as you would without pathfinding, but keeping the rest of this in mind
-Use a job to generate a pathfinding map from the level data entities. This should be probably able to run across multiple frames, unless it's absolutely critical to have the pathmap 100% up to date all the time, and only run at the start and when your map changes.
-At this point you can use jobs, probably together with ECS, to pathfind.
Obviously I'm leaving out all the dirty details, but in principle you should be able to do this in pure ECS
yup, exactly that
in my unreal engine version (i use it for some 3d pathfinding implementation), i do exactly that
when the game starts, each of the "game objects" that represent a path "insert" themselves into the PathManager, and then self-delete
from then, i use the path manager to find paths, and all the pathnode data is stored in compact arrays
because that pathnode data is 100% read only, i can use multithread to find path
not like i need it anyway, the system did 1000 pathfinds per milisecond on the maps where i use it
struct FDungeonPathNode {
float Radius;
FVector Location;
//neighbours
int Attachments[6];
EPathSphereType Type;
ADGN_DungeonModule * Module;
};
struct FDungeonPath {
TArray<uint32> Path;
float FullDistance;
};
class DGN_API UDGN_DungeonPathSystem : public UObject
{
TArray<FDungeonPathNode> PathNodes;
//returns an ordered list of nodes for the path
bool FindPath(FDungeonPath & outPath,uint32 start, uint32 end);
}
so Attachments is just the int value in the array, or hash map?
int index in the array
okay
Dungeon Path also returns an array of indices
this could be int16, and save memory
the Module pointer is for some game logic, points to the room where the node is
Okay, I think I understand what you mean. I still have a question about the node data, should I be generating at the start, then adding obstacles / updating unwalkable as the build happens, then modify just as things change in the map? Or should I be using a quadrant system to build a hashmap constantly updating with the content?
if you are editing the nodes, then just keep their index around and update the array when needed
btw, if you are dealing with a grid, the NodeData array would just be a 2d array and the index is just grid ID
if you add and remove pathnodes dinamically.... that makes it much harder
Fixed size? Then it should be a 1D array (flattened 2D array)
then just access the array directly and set the flag you want
so if its 5x5, instead of having [0,0] [1,0] [2,0]..etc just have 0-24
[[1,2],
[3,4]]
becomes
[1,2,3,4]
and still use the same indices
lets say you need to store the name of some nodes
then just add a hashmap somewhere
Careful of overengineering, tho
where key is array index, and val is name
i used this for AI
i had the need of calculate the distance to "every" node in the map
so i just return an array that uses the same node indices
so if NodeA is number 3, you can use that 3 on both the NodeData array and the NodeDistances array that i just returned from the function
N:N or 1:N?
@shy garnet ?
nah, don't worry, I said nothing
What do I need name for is that our pointer? Like so I can reference that [3,0] is actually node[3] and not have to think about it?
@winter depot if you want, do it
in my system im just using ints
but making it be a "struct" that has an int inside (for type safety) is actually a good idea
Okay
mostly so you dont do stupid shit like accessing node 3 or similar, without really wanting to
Right
So in this example, I am not using entity to hold the data. I am just creating an array of structs, that hold the position, radius, location, flags, reference info, and whatever else I need, then I am just updating that array as needed, right?
yup
in such a thing, you can still have the pathnode in the ECS
maybe Pathnode component
that holds the index to the array
the main thing is that you really dont want to be accessing the ECS database to pathfind
I have been using burst with IJobForEachWithEntity with burst mainly to get stuff done in this project. I guess I assumed that was the most efficient way of using the burst system. I need to read up a little more on that.
you can do for-eachs on burst that just iterate a normal array
for a pathfind system, you want to either have it "instant", so you just have a free-floating FindPath function and use it from random places in your code
or have a PathRequest component, and do a IJobForEach on PathRequest to find all the paths at once
Without waiting for job completion
Okay yeah
I think my thought was to try to add a path component that I would add to my entities to determine wether they need a path or not, and have them going through a IJobForEach
When a change happens I would remove all of those and it would run again
yeah thats perfect
I think I have a pretty clear understanding at this point, I am going to try to list things out, and if I have any further concerns I will post and hopefully won't eat up much more of anyone's time. When I am done I will put together something written or an example of the working code on that forum post to help people like me in the future.
thanks @vagrant surge @tawdry tree
No probs.
Oh, and as one of those blogposts say, it should be fine to start with a non-jobified system and jovify it if you need to (or want to bother). Similarly, you don't need burst for everything, but should at least keep it in mind for things that might benefit from it. Premature optimization and all that - if it's more work than it's worth, then don't optimize.
if I do two separate IJobForEachWithEntitys with the same component types, will indexes for the entities they iterate through be the same?
As in, can I trust that index 1 in one IJobForEachWithEntity will be for the same entity as the other IJobForEachWithEntity?
Do you chain them? otherwise, I don't think so
@winter depot I wouldnt use a component for request a path as you mention above
Why is that?
Just so I understand correctly. You want to add a component to indicate the entity needs a path, like a request
And after the path is found, the component is removed?
Yes, that is my thought currently. Again, I am trying to map things out because I am pretty new to this subject
The issue with temporary components like these, is that they will cause your entity to change archetype and copied
Twice, since the component is added and then removed
Due to this, after path finding is done, the archetypes with this request component are empty. And its chunks discarded
If you do this with entities that contain object components, this will cause garbage.
I understand that, but the alternative would be then to have iterations through all entities that have the ability to pathfind, with a flag to cycle the ones that do not need a path out. Is that not a larger overhead than just occasionally adding a component while removing another?
You could also use something slightly less ecs
Like a list that you add entity ids to for requesting
Your sysem then uses a job to collect the required data from those entities, and uses them for pathfinding
So are you saying a buffer component that holds the entites that I need to iterate through? I feel like that would be more in the direction of moving away from multi-threading
I am still pretty rough on using burst and jobs without entities. I really will need to read up on more examples where its done before I can comprehend what you mean
I have been using component system in places where I am not using burst with PostUpdate to perform, in other places I am still using IJobForEach just without burst
You can still use all that
I understand I won't be modifying entities, so I guess thats the confusing part. I have only worked with them this far, holding my hand and guiding me to saftey ๐
Well I have used that pretty heavily already, but I just didn't know things like that could be done elsewhere with burst ? If I am understanding you correctly, you propose that I have a native array full of my node struct. Then I have a native array with Entities needing paths. I have a system using burst that iterates through that native array, then calls the FindPath or whatever method I call it to create the path, hand it to that entity, and remove it from that array?
As opposed to my original example I was giving the entity a component and then using IJobForEach to automatically do the iteration for me
Something like that
You can still use a parallel job
You pass it the list of entity ids that want a path
And schedule it for that amount as well
Okay yeah, that's the part I need to look into. Other parallel jobs outside of IJobForEach.
Ill help out once im behind a pc with keyboard ๐ about 30 min or so
Referring to pathfinding and components, you could just have a bool on a PathFindAgent component or something, to avoid archetype changes. Would need to manually iterate and filter on that, though. That said, assuming they don't request new paths all too often, it might not be that expensive. I suspect the pathfinding itself might be a bigger perf hog than the archetype changes...
Right, I think you are correct in that. I guess I am always weary about iterating through things that don't need to be iterated through. I try to imagine a real life scenario where there are people in line and they get to the front of the line and say "I don't need anything", then go to the back of the line. I would rather be in a situation always where your only waiting in line if you need something. Leads back to the premature optimization thing, but overall I just am trying to learn the right way of doing things
@vale stream in such a thing, you are removing the PathReuest component from entire chunks at a time
so you could have NeedsPath + PathFollow components
NeedsPath gets removed after path is found, and because its an empty component, you can "morph" the entire chunk without doing archetype moves
Cool I found a computer
@tawdry tree The archetype changes have some side effects that reduce performance permanently as well
you can change the archetpye of an entire block at a time, and its much faster
Though that only happens if you have multiple temporary components
for a pathfind system, you would use that
@vagrant surge I think you meant someone else? ๐
tho adding the component will do archetype move :/
@vale stream ah shite, meant @stiff skiff
Coincidentally I'm also working with pathfinding, so Im still finding all of this helpful ๐
I'm not sure how the chunk archetype change works if there is already a non-full chunk of that archetype
It will reduce the amount of copies though, you are correct
But the general rule of thumb for performance in ECS, is don't change the archetypes
yaeh, i guess having a system/singleton and just pushing the entity Ids there would be the best
@stiff skiff yeah, sometimes i get tripped on that because the ECS models i use on c++ (EnTT) has extremelly fast add/remove on components, so its spammable
We've found out the issues of temporary components the hard way ๐
@winter depot you could create a "request" entity
empty entity with just "PathRequest" component
I mean for most of the ECS I have been working with I have been adding and removing temp components. I really didn't think this was a big deal haha
in unity model, creating and destroying entities is very cheap
temp components less cheap
in fact, creating/destroying entities (small ones) is a LOT faster than modifying bigger entities
An entity with a request component, containing the id of the entity that wants the path would work
But I doubt its faster then adding it to a NativeList
Like my targeting system I have a HasTarget, and a Targeter. If it doesn't have a HasTarget and it has a Targeter, it runs through the system that gets targets, that system applies the HasTarget again.
So does the chunk for the request component
adding the request as an entity could be done from within a command buffer
The NativeList can be thread safe too ๐
But yea, multiple ways to achieve this. I'm unsure what would be faster without testing it
it does depend on the level of tryharding you want to display
I want to just tryhard enough to not give up
๐
If I hit a wall that I am feeling helpless then I will tone it down
btw, on the topic. Creating small entities to act as "messages" beetween systems is a very good thing
i had a damage system that worked like this. It would create an entity with damage information components, and that goes through another system that processes it
the best part is that it is "very" data driven
In this example. instead of a global nativearray somewhere we have little request entities holding ID's and pathing information of the Entities needing the path, or one entity that holds a buffer with all of that. Then that boy does the heavy lifing?
you can create a Sword entity that has an "apply on hit" component or similar
and that apply on hit has DamageAmount + FireElement, and other shanenigans
@winter depot yeah, Tiny entities that only have PathRequest component (holds start, end, and requester)
once processed you nuke em
Yeah, currently I have all of that in one entity essentially. In a ComponentSystem I loop through all the ones that have target for melee, and they simply hit their targets than drop "HasTarget" if a target dies or is out of range.
For projectile its a little more complex. I have projectile entities that hold that information
They only exist for split seconds while they are moving to their target
So i think the projectile portion is like what you are describing @vagrant surge
well, but projectiles persist for a few frames
an "event entity" like the damage thing or pathfind thing will not last 1 frame
its created and near-inmediately deleted
Yeah, I understand.
I am making sure I am following you guys on the garbage thing though
its more about fragmented chunkjs
if you move stuff randomly, you will end up with chunks at half-size and similar
lets say you have 4 chunks of Enemies
and change half randomly
now you have 8 chunks
If I have an entity holding a large amount of data, its part of this archetype. If I add this NeedPath component, then add a HasPath, and remove NeedPath, its building garbage and modifying this original entity which is not so good
all of them at half fill
yeah, its best to avoid component changes on unity ecs model. Creating small entities is preferred
dont think that you are limited to 1 entity per "game object"
there is nothing wrong on having a second entity that points to "parent"
There is a bit more to worry about there though when it comes to disposing entities though yeah? Unless they are nested
That bit sounds like it may be a little more premature optimization than what I need I think. At the moment I want to see an improvement but I don't want to overwhelm myself and then get lost again
at the very bottom of this page it says that you can use the index to reference the same entity across Jobs
https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/entity_iteration_job.html
Is this index valid until the entity in that index is destroyed?
That index is just referring to the index in that job right?
So if you are writing to an array you know which entity you are talking about
I mean that's what I thought at least. Independent of the entities "Index".
"You can also use the index to reference the same entities across Jobs within the same system. For example, if you need to process a set of entities in multiple passes [...]"
within the same system is key here, and it assumes you don't change archetypes or anything in the system.
So like if you have entity #712 in world. That has nothing to do with the entity index you have in your job.
okay, so it's kind of valid until the end of a systems OnUpdate, as long as no changes to the archetypes are made?
ECS models i use on c++ (EnTT) has extremelly fast add/remove on components, so its spammable So many people are in the same boat, pretty much every ECS I've seen just has some form of on/off for components but nothing actually moves, and everything is pre-allocated. In those systems 'Add/Remove' is just for tracking because they're always there. I get why Unity did it this way, but its a huge adjustment, even for people who are already familiar with ECS. Its like the one tool you relied on and built your systems around, you can't really use.
@mint iron not in something like Entt
there are 3 "mayor" way of building an ECS
first-gen ECS (the dumb kind) are literally 1 array per component type, and a bitmask
in those, add/remove comp is literally setting a bit
second gen (Entt and Entitas) use cached lists
both of them store your components in something similar to a Map where key = entityID, and val = component
just flat, not a hashmap
and for queries, it caches them. So if you have a Position + Rot query, it has an array of all entities with Pos + Rot
unity has the whole archetype buswiness
Interesting. Entitas (at least the CSharp version) does do what i described, its just it also has the layer of grouping/filtering like you explained on top of that to make iterating more efficient, and add/remove of components is slower because of the grouping.
it does slow down add/remove
thats very true
when entitas (or entt if you use groups) adds a component, it will add the entity ID to all the relevant stored groups
same when remove
the fun fact is that the performance scaling of unity ECS add/remove and entitas add/remove is completely different
in entitas, the more systems you have, the slower it gets to add/remove components
in unity, you can have a million systems, and nothing would happen
unity depends on how many components you have on that archetype, as gotta move them
Jesus @vagrant surge you are a treasure trove of knowledge
ive been resarching this stuff a LOT, and also made my own C++ version of unity approach
awesome. i've rewritten entitas a few times in different ways to get rid of the code generation because i hated it so much.
So in this example if I were to have found my path... I would give my entity a HasPath component. This component would hold a buffer which is just a [int] for all the nodes, which it gets the transform from them? Or will it hold the transforms themselves?
I would assume that if I use a buffer and have the nodes themselves I could potentially only need to check on change if the change impacts a node in that entities buffer list
Instead of removing all paths, just the ones that need to be recalculated
@mint iron What do you use for code gen?
Sorry if its a bit offtopic for this channel ๐
Unity's ECS model for C++ sounds nice
I assume it has less issues then the C# one?
Due to not having to deal with the runtime/gc
Hey guys,
getting into Unity and ECS and got a little problem with command buffer inside a job. I instantiate an entity from a prefab (with Instantiate), set builtin Translation component with SetComponent and then try to set my own component in the same manner. It compiles but throws an exception at runtime, without any helpful message. basically the only meaningful part is "ArgumentException: A component with type:MyType has not been added to the entity."
Do i need to have some sort of boilerplate/scaffolding/adapters on the prefab I use that adds support for my own components ? Right now it only has some built-in monobehaviors like mesh and translation.
You seem to be missing the AddComponent<Translation>(entity) or creating an archetype
I highly recommend looking at a few of this guys ECS tutorials. They aren't perfect but they got me to be able to wrap my head around at least some of this stuff. https://unitycodemonkey.com/
yep, thanks, AddComponent<MyType> before calling SetComponent made the issue go away
I have watched and read some tutorials, it's just most of them had things that are now marked as deprecated in Unity
so kinda have to navigate what is still working and what I should disregard
Yeah, much of this changes rapidly. His content is very new, and although a few things have changed, unity will at least give you the warning on what to change needs to be made to resolve it before it depreciates. Its worth investing a few hours in (Just the ECS videos)
do I have to set a NativeMultiHashMap's Capacity every time I make one?
@stiff skiff i tried the default codegen that comes on the app store (except also the latest version), figuring out the others seemed like even more of a nightmare. This is what i ended up with: https://github.com/jeffvella/EntitasGenerics
the codegen is so you buy the good codegen plugin XD
๐
Ohh you made one of the pathfinders that I spent some time looking at. Good man
hopefully you didnt look too close the code is a bit messy ๐
I didn't, I was actually overwhelmed and frustrated that it was using NavMesh like everyone else so I went on my own hunt lol
it only uses the navmesh to set flags on which nodes are walkable, after that it never touches it
Oh really? I may need to take a deeper look then
yep, its just using a native array with 3d indexing
Good stuff, hopefully I can convert it to 2d and use parts as an example
do I have to set a NativeMultiHashMap's Capacity every time I make one?
@vagrant surge oooh you willing to share that c++ ecs approach? I was having trouble recreating the entitymanager and archtype management in my clone of it
plain simple ecs is easy to make, but they put a lot of interesting stuff in the way chunks and archtypes work internally
oh there was update to entities as well
(not just hybrid)
dunno how I missed that
## [Entities 0.1.1-preview] - 2019-08-06
### New Features
* EntityManager.SetSharedComponentData(EntityQuery query, T componentData) has been added which lets you efficiently swap a shared component data for a whole query. (Without moving any component data)
### Upgrade guide
* The deprecated `OnCreateManager` and `OnDestroyManager` are now compilation errors in the `NET_DOTS` profile as overrides can not be detected reliably (without reflection).
To avoid the confusion of "why is that not being called", especially when there is no warning issued, this will now be a compilation error. Use `OnCreate` and `OnDestroy` instead. ```
### Changes
* Updated default version of burst to `1.1.2`
### Fixes
* Fixed potential memory corruption when calling RemoveComponent on a batch of entities that didn't have the component.
* Fixed an issue where an assert about chunk layout compatibility could be triggered when adding a shared component via EntityManager.AddSharedComponentData<T>(EntityQuery entityQuery, T componentData).
* Fixed an issue where Entities without any Components would cause UI errors in the Chunk Info view
* Fixed EntityManager.AddComponent(NativeArray<Entity> entities, ComponentType componentType) so that it handles duplicate entities in the input NativeArray. Duplicate entities are discarded and the component is added only once. Prior to this fix, an assert would be triggered when checking for chunk layout compatibility.
* Fixed invalid update path for `ComponentType.Create`. Auto-update is available in Unity `2019.3` and was removed for previous versions where it would fail (the fallback implementation will work as before).```
@low tangle https://github.com/vblanco20-1/decs
im missing shared components, chunk components, and system state components. So basically only basics
deletion while iterating is.... wonky. Works in some places but not all
ComponentList PosOnly = ComponentList::build_component_list<Position>();
V_ECS.IterateBlocks(PosOnly, [&](ArchetypeBlock & block) {
auto ap = block.get_component_array_mutable<Position>();
for (int i = 0; i < block.last; i++)
{
p++;
ap.Get(i).x = (float)uniform_dist1(rng1);
ap.Get(i).y = (float)p;
}
});
it does block-iteration
its also very fast
has anyone seen the 'Develop' button in PackageManager? i used it a few weeks ago and now it seems to have disappeared. Is there a trick to get it to show up or was its presence maybe something internal that slipped into a build.
@dull copper did you see the latest Tiny version?
they are removing the DOTS-only editor, and just doing conversion workflow
they definitely can't just can it
Acton seems to like it
because you have your edit hierarchies and shit, and then convert into hyperoptimal runtime
yeah, I've noticed :/
was so hyped about ecs editor
I guess we get that status update in like 6 weeks
same
i think they are overloaded with the tiny edtor
or just dont like the "2 editors" thing
what i wonder, is why, still do they NOT DO what Entitas does
for hybrid modes
man thats weird, wonder if it just gonna be like dots editing in the far future of years away or that there wont ever be dots editing, only conversion?
Well, a proper editor is basically required for a good workflow, so I assume it will come at some point, but I'm getting the impression that they want a stable feature- and API-set and make a pure DOTS editor, so who knows when that might be.
looking at mr Mike 'God of Caches' Acton, the whole conversion workflow is likely to be the main thing
use a hierarchical representation on the editor, and then everything gets baked into optimal runtime with mkerged objects and stuffs
the thread where they explain this stuff makes it a little clearer "The DOTS Editor hasn't been ditched, just put on hold -- it's still where we want to get to. "
DOTS will be production ready far before a DOTS editor is ready. I wouldn't let waiting on the editor stop you from getting into ECS.
I don't suppose someone know's how I wait for the commandbuffer to finish in the main thread, it seems like the next job is starting before its finished and I need it wait for it to do its thing
If they are in separate classes then I use [UpdateAfter(typeof(ExampleType))] above the class?
no there in the same jobcomponent system, there kind of connected so it would be best to have them together
I need something like handle.complete() but for the commandbuffer
@vagrant surge thank you so much!
ExampleJobOne exampleJobOne = new ExampleJobOne { whatever values};
JobHandle jobHandle = exampleJobOne.Schedule(this, inputDeps);
ExampleJobTwo exampleJobTwo = new ExampleJobTwo { entitycommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent()};
jobHandle = exampleJobTwo .Schedule(this, jobHandle);
endSimulationEntityCommandBufferSystem.AddJobHandleForProducer(jobHandle);
return jobHandle;
yeah thanks for that Enraged that's pretty close to what I've got but the command buffer is in the first job
And you are trying to add components before the second job?
yep
I haven't tried, but I feel like it would be problematic because its a different Achetype chunk then the array you may have build earlier? I am no expert though
I think I would sperate it like I first mentioned in that case personally, but I may be incorrect.
you can see in the profiler
EndSimulationEntityCommandBufferSystem, I need to wait for that to finish before starting that second job
maybe there isn't a way to do it without using a second JobComponent though
The way I have a similar example working is the IJobForEach is in a ComponentSystem with Jobhandle.Complete() on update, then the UpdateAfter is running in a JobComponentSystem.
yeah thats probably the best way of doing it, if the first job runs then the UpdateAfter always means the second jobcomponent runs as well doesn't it?
im trying to do collision detection and resolution as two jobs
currently I have a collision detection job running in parallel and populating a concurrent NativeQueue with colliding pairs
What's the best way to run through the NQueue with a parallel job?
Or should I use something else than a NativeQueue?
@vale stream You can't pull from the queue in parallel jobs i think?
@vale stream you could look into using a list and ToDeferredArray() in the second job for processing. https://forum.unity.com/threads/request-allow-parallel-writing-to-nativelist-when-writeonly-is-used-or-add-concurrent.522783/#post-3431853
I'm spawning objects through my scriptable object which is plugged into my gun script.
what i want to optimize is the setting of the velocity to the value inside a scriptable object
I'm calling this wierd mess of stuff
the pellet script
public override void Shoot(Vector2 origin, Vector2 velocity) {
var o = Instantiate (prefab, origin, Quaternion.identity).GetComponent<Projectilebody>();
o.lifetime = bulletLifetime.Float;
o.transform.localScale *= scale;
o.GetComponent<Rigidbody2D>().velocity = velocity;
}
which is being referenced by
public class PelletGun : sGun
{ Vector2 aimt;
public override void Shoot(Transform origin, Vector2 aimx, float powere) {
for (int i = 0; i < (int)(BulletCount.Float*powere); i++)
{
float powex = direction != null ? direction.Float : 1;
Vector2 ops = new Vector2((powex * aimx.x) + origin.position.x, (powex *aimx.y) + origin.position.y);
Vector2 velocity = aimx * powere * bulletspeed.Float;
projectile.Shoot(ops, velocity);
}
}
bool ready = false;
}
which is being referenced by the gun
if (powere > 5) return;
if (Mathf.Abs(powere) > gun.BulletMinimumSpawnDistance.Float && ready) {
gun.Shoot(transform, aimt, powere);
ready = false;
}
a little messy but it works, however it slows my game down to spawn more than 200 projectiles at once
this video is a bad representation of the mechanic slowdown
you can probably guess how bad it really is
like 2 frames per second after 2 seconds of firing the gun at 32 bullets per frame
That looks like gameobject-hybrid code to me, is that the case?
Instantiate (prefab, origin, Quaternion.identity).GetComponent<Projectilebody>()
You probably want to look at pooling your game objects so that you don't have to keep creating new ones, i suspect that's your biggest slowdown.
https://github.com/jeffvella/AsteraX/blob/master/Assets/Scripts/Utilities/ObjectPool.cs
https://github.com/jeffvella/AsteraX/blob/master/Assets/Scripts/Managers/BulletManager.cs
I think I've got a question.
I've defined an UpdateGroup for some of my Systems that has [DisableAutoCreation] on it, meaning that the group and its systems will not be initialized in the player loop automatically
Instead, the group is initialized and updated by hand, like this. DoProcess(), which makes the entire group run again, is called from the OnPreCull method on a camera
And sure enough, here it is, my system runs fine where it needs to be
However, I don't get one thing.
The core loop continues to execute after doing the update method, which is a great thing. However, I will need the group to be fully completed at one point to pull some data from the OOP domain.
TL;DR - How do I force the completion of the entire group?
i'm not sure but i think you'd need to get access to a combined job handle from each of the systems inside. It doesn't look like there is a JobHandle exposed from the ComponentSystemGroup, so unless there is a helper Utility somewhere around i haven't seen then you'd have to manually have your systems make their final job handles accessible, or submit their handle to somewhere (like a system ordered to the end of the group) to be combined/completed.
What about making a system thats explicitly at the end, that calls Complete in the inputdeps jobhandle?
Ah nvm, that wont help
was afk. Afaik doing that won't help because a completely empty system that is tasked with just calling jobHandle.Complete() will actually have an empty handle passed to its OnUpdate() method since Unity's ECS doesn't think that it depends on one of the systems in the group
And, I dunno, having to pass the jobhandle to somewhere else and just calling complete on it at one point sounds a bit hacky. It'll surely work, but it seems a tiny bit redundant.
In any case, thanks for the replies so far.
@fringe sinew There is an EntityManager.CompleteAllJobs() that might work?
Though its not idea if you have jobs outside of that group that are allowed to keep going
I think it might work. The group is still a part of that same world and it has the same entity manager
Hmm... seems like it doesn't really work. I must be misunderstanding something.
Yep, I indeed was doing something wrong. I tried to get an empty EntityManager at one point so that's why it didn't work. Still, yet again, it forces all of the jobs to complete, so maybe storing all the job handles outside ECS' internals would be a better approach.
Thanks for the replies.
You're using multiple ecs worlds?
No
pass the jobhandle to somewhere else and just calling complete on it at one point sounds a bit hacky. Its pretty much what all the Physics jobs are doing. Also same thing with commandbuffer systems having to register themselves with the barrier end.
@tawdry tree gameobject-hybrid? I'm using scriptable objects to store data and functionality.
Not to be confused with storing all the data and functionality on the same scriptable object.
@mint iron potentially. I'll figure out a way of creating a pooling system without relying on Singleton references
Maybe that'll be good?
I'd like some advice on how I should design collision detection and resolution with jobs. The biggest problem Im having is that I dont know how many collisions there will be until I run collision detection, so I it seems like my own choice for concurrent writing is a queue?
Also since I dont know the number of collisions beforehand, I wont know how much I'll need to run for collision resolution as well.
Should I have them as two systems? With collision detection being a system that creates a collection of collisions, and collision resolution as another system that updates after detection and knows the size of the collision collection?
@upbeat mulch You're using classes, so I assume you use gameobjects with monobehaviours on them - thus, you're using (at most) hybrid ECS affecting gameobjects. For that matter, are you actually using ECS?
Becuase if you don't this isn't the right place for that.
Also, how you've set things up greatly affects how we can help you - for one, monobehaviour-based code isn't going to get great perf compared to entity-based ECS.
I'm using scriptable objects tbh
Those are just data storage, though, and have nothing to do with ECS
@vale stream Most high-perf physics usually do several passes, which is a good idea. First, find out which things are close enough to potentially collide (rough pass), then find out which one actually do collide, and then from that resolve the effects said collisions have. The first job can be very simple (heuristic-only), and lets you limit the 'size' of the second job, and so forth.
I'm in no way an expert on this, though.
I followed a brackeys tutorial on ecs and the code he was using to control and create entities was not in the ecs. There must have been changed and I don't understand how to set ecs up
What unity version do you have? Have you installed the ECS package?
Unity 2019.2.0f1
I installed entities, jobs and burst. I think I did but I have no idea
So you have the setup, at least ๐
When it comes to learning the whole DOTS stack (jobs, ECS, burst) it might be a good idea to start with just ECS. Plain systems, no jobs, no burst, everything on the main thread. Then you could go from there.
The first steps, then, would be to convert gameobjects to entities, so that you can use systems on them, and then make systems to at least move the bullets.
A reasonable first target might be to have non-ECS code to control the player, but to make the bullets entities.
I would suggest making a new project to play around in and try to wrap your head around ECS without pesky things such as existing code and preconceived notions, then you could use what you learn from that in your existing project.
Official ECS samples: https://github.com/Unity-Technologies/EntityComponentSystemSamples
This a good, farily in-depth tutorial: https://www.youtube.com/watch?v=ILfUuBLfzGI
It's kinda tricky to help you if you don't have specific issues you need help with, but hopefully some of that will be useful?
Also, is this the Brackeys tutorial you were speaking about?
https://www.youtube.com/watch?v=_U9wRgQyy6s
This project as a whole is a change from my usual coding style.
And yes that brackeys tutorial.
Oops
As nothing is actually connected to each other slipping in some ecs would be no problem at all
I think anyways
Thanks I'll try these
The general suggested work flow right now is to build your levels and objects with monobehaviours and use the conversion workflow to convert them to entities you can ECS on - any time you have a monobehaviour that actually does something, you're solidly on the gameobject/monobehaviour side of things.
Would it be possible to have entity physics like a rigidbody but for entities?
People have been talking about physics here, and I think there is a package for that, but I don't know the specifics.
Quick googling, looks like the Unity Physics package supports ECS:
https://docs.unity3d.com/Packages/com.unity.physics@0.0/manual/index.html
That also has a manual on how to get started and such. As mentioned, i haven't used it, though others have, so try it out and come back if you get stuck on anything.
@tawdry tree ty for the advice. Is there any way that one can make sure that one job completes before the other, besides using the jobHandle.Complete() function? I guess I'd have to make sure it finishes completely before I can know the size for the second job.
I dont think I'd be able to simply schedule them one after the other, since I wouldnt know the size of the second job at schedule time?
Use one jobhandle while you schedule the previous one. This is called chaining
var jobHandle1 = SomeJob.Schedule(inputDeps, [...]);
var jobHandle2 = SomeOtherJob.Schedule(jobHandle1, [...]);
You can also just overwrite the same job handle, you don't particularly need to make a new one. Also, chaining is more performant than using .Complete()
yes but I think the problem is not knowing the size for the second job at the time of scheduling?
What kind of jobs do you use? Are they in a system?
And how are they linked? The first one somehow essentially returns something which tells you how big the next one will be? Could you show the code?
Im still working and planning it all out, and learning at the same time. But I think I just realized that I might not have this problem, and I'll have to try writing it again to see.
The first job runs in parallel and populates a queue (since I need to write in parallel and only queues and multihashmaps seems to be able to do this with variable sizes)
Then the second job, which I just realized might solve this problem, would be a single non-parallel job that runs through the queue to populate a list of lists
Then the third job would run in parallel with each thread of the job tacking one of the sublists
The second job in between is new to my plan and actually solves the variable size problem, I think
So the first could be whatever, possibly something on entities or a plain IJobParallelFor, and the third would be IJobParalellFor? Sounds like #2 might not need to be a job, if you think it's simple enough and isn't going to run parallel. Then you could jobify it later if you think it's worth it
since job 3 depends on job 1, would having the second part as job and scheduling all three together as a chain be a good idea?
so I dont have to call Complete()?
If you can manage it all chained, then that sounds like a good idea.
Sounds like you wanna do IJobParalellFor->IJob->IJobParalellFor then
I'll give it a try! ty for the help, I'm quite excited to get this working ๐
I know that feeling ๐
I know that this question was here many times but what the traditional way in unity ECS today to go with DIP principle? I mean that the simpliest way I think is to use delegates and events, but what with ECS? The only way I see is to use global list which contains delegates and store an index in component.
if anyone's interested in working with some exceptionally unsafe things, here's something I've been working on to help - https://github.com/jeffvella/UnityECSOffsets
@frosty siren dependency injection and callbacks goes 100% against the spirit and programming model of the ECS
Is it wrong I want the EntityCommandBuffer.Playback to have a ExclusiveEntityTransaction parameter overload? 
if anyone's curious you can get an EndSimulationEntityCommandBufferSystem to run in the middle of a JobComponentSystem, between jobs, you just call update() on it and it seems to work.
Why exactly would you need to do that? ๐ค
because the first job adds components to entiity's and the second job needs the list of updated entitys
@pliant pike did you see you can now add components to entities while iterating in a for-each?
yeah but it still only happens in the main thread after the update of the JobCompSys
I know but either way the second job has to wait
@frosty siren to claryfy on the DI and delegates on ECS model
DI is completely unnecesary. If you want to replace a system, just replace it. Systems will be quite atomic to each other, so if you want to change behaviors or "override", you can just replace a system that deals with components A-B-C with another system that also deals with A-B-C but in a different way
Delegates are frowned upon because they remove the entire point of ECS, which is a linear execution of systems. For event-type stuff, a common approach is to create new entities that have the "event payload" as components, and they get processed by some other systems later
Calabi what exactly are you trying to achieve, the scenario. I saw the post be became lost upon your final doodle
That last doodle... had a lot of breaking points for me. Biggest one is "Complete()" being called
If you are goign to use the JobComponentSystem, use the dependency handling 
I think its mostly achieved heres the thread in the unity forums if curious https://forum.unity.com/threads/create-commandbuffer-sync-point-in-jobcomponentsystem.725570/#post-4844984
I know the code is a bit of a mess
So. If the entities exist and you are just wanting a list of entities who had a component added... just pass a NativeQueue and enqueue the entities that added
This way
1: The Buffer doesnt need to all of the sudden come out of its original cycle run and stop the world to playback
2: You can have all the entities of variable length at your disposal
but the second job doesn't just need the entity's that have the component added it needs the whole list
The whole list?
well all business type entity's
This is why I wanted you to explain your scenario, as in your post you have made it very vague and very mysterious without giving your end goal
You attempted to abstract it out, resulting in a lot more confusion. Give a scenario ๐
yeah sorry I guess code in isolation is hard to read, I can't read anyone else's code
Let's start with the "whole list"
So you want the list of entities changing
What part is missing if we just provide that
basically the idea is the first job checks if the business has enough funds for the wages, if it does it deducts them, if not it applies the insolvent componenttag
second job goes through all people entity's and first checks if their business is insolvent if not then it adds the wages
And this business with "insolvent" what is the result now with it?
no result currently it just doesn't deduct but it will be used for more things down the line
So. Just for a quick thought, my first idea would to be reverse the order of the jobs. Any businesses non-insolvent, pay the workers. Once this job is done the next job scheduled would check all businesses
This way you would have the correct time flow for data and the information would be updated based on how you needed it
so
payHandle = pay.Schedule(inputDeps);
fundHandle = FundCheck.Schedule(payhandle);
buffer.addProducer(fundHandle);
return fundHandle;
or something like that
ok yeah, that might work I'll try that, thanks 
Just don't call complete, update from a commandbuffer / entity creator system inside the update call
those kill me a little inside each time
Complete is a total stop of main thread until the job is done, which means the rest of the system waits on you. Whereas you could just schedule it to go and daisy chain the jobs
I do need to call complete at the end to disable the job though
of the entire jobsysystem, unless theirs another way
What do you think the return you are providing is?
if(inputDeps.IsCompleted)
{
this.Enabled = false;
}```
like that, otherwise it just keeps looping around
yeah... those lines are wrong 
Unless
you wanted it to stop after one go...?
Calling complete is still a no
yeah I do I have it activates by spacebar press currently
Ah then in that case just have it run
but instead at the start, check the input for space
if true go on
if not return inputdeps
I'm using another jobcomp for the input
For instance
protected override JobHandle OnUpdate(JobHandle inputDeps) {
HandleRegister();
if (!_otherManager.ExclusiveEntityTransactionDependency.IsCompleted)
return inputDeps;
_otherManager.EndExclusiveEntityTransaction();
MoveEntities();
return ScheduleBuild(QueueData(), inputDeps);
}
with refs to the other jobcomps just for simplicity and less confusion
This just sounds like a system that is diverting away from Data Driven Design
well its just for testing purposes and am currently learning
Fair. ๐
Just know. Calling complete() usually something has gone wrong
when working with a JobComponentSystem
DOTS is cool because I can build all systems in isolation, then figure how and where they go later
Yep
Decoupled systems is DDD
In your case scenario, you could just augment the previously mentioned path:
yeah I'm still not sure how I properly get a system to run once
if(!InputHandle) return inputDeps;
payHandle = pay.Schedule(inputDeps);
fundHandle = FundCheck.Schedule(payhandle);
buffer.addProducer(fundHandle);
return fundHandle;
That would only schedule those two jobs if your input is true
Otherwise it would just return the existing deps which is totally fine to do
so I would pass the spacebar input to that job instead of keeping a reference to the job in another system
Ok. 1: Why would another system have reference to your job?
2: You don't pass the input (unless you really want to) to the job. this is in the UpdateMethod
You don't even need to store a ref of the job either
if (Input.GetKeyUp("space"))
{
deductwagesfromsysref = World.GetExistingSystem<DeductandApplyWages>();
deductwagesfromsysref.Enabled = true;```
like that
Uh ... nooooo
Don't use Enabled for this
Something like this in your JobComponentSystem
protected override JobHandle OnUpdate(JobHandle inputDeps) {
if (!Input.GetKeyDown(KeyCode.Space))
return inputDeps;
var payHandle = new PayThePeopleJob().Schedule(inputDeps);
var deductHandle= new DeductJob().Schedule(payHandle);
return deductHandle;
}
Dont use GetSystem in update
Much like you wouldnt get component or the like in a monobehavior
Also. In this regard, you don't really want this system to control others based on input
yeah I know it was only temp because the creation and ordering of the systems isn't correct so that it didn't work in an OnCreate or similar method
GetOrCreate<System> in onCreate works fine, regardless of ordering
To help store a reference, but this seems very much like knowledge attempted from the old monobehavior style
which is something you need to train yourself out of
Remember, each system is incharge of its components.
Not other systems
You CAN build systems to manage and maintain other systems, but your scenario particularly is not one of those things
The more decoupled things are, the better off you will be in DOTS
yeah I haven got into the systemorder grouping aspect yet
You shouldnt even need to get into that unless you can ensure your ordering is better than the systems
If you are building entities manually then you'd need to look into it for sure
but if you are just using a command buffer (especially one that exists) then you shouldn't need to
yeah thanks for the info
Alright, I have quite a problem
The error code is self-explanatory
InvalidOperationException: The previously scheduled job FlareEntity_BaseProcessSystem:processJob reads from the NativeArray processJob.Data.flareEntityGroupDataFromEntity. You are trying to schedule a new job FlareEntityGroup_BaseProcessSystem:processJob, which writes to the same NativeArray (via processJob.Data.groupType). To guarantee safety, you must include FlareEntity_BaseProcessSystem:processJob as a dependency of the newly scheduled job.
The question is: how do I acquire that dependency? InputDependencies doesn't contain it. Do I need to just store it somewhere externally when scheduling the previous job?
you have to do it manually jobhandle job1 = job1.schedule(this, inputDeps), job2.schedule(this, job1)
something like that
hello, i'm new on DOTS, and i just wanna know which feature can be use on production (build for summiting store)
i know Burst is not available for production
but when will it be available and is there any feature also can not be use for production too?
So I'm sure this is probably a common question as there's little documentation at the moment - but my question is around business logic. I'm just getting into ECS/DOTS and trying to essentially rebuild a pet project of mine. It's a procedurally generated 4x style project, with hex cells.
Previously, I had a "WorldController" spawning a bunch of chunk gameobjects, and this worked OK - but looking to recreate this with an ECS mindset I'm unsure exactly what part of the DOTS stack should be responsible for handling this business logic?
Assume for simplicity's sake that each cell is a unique entity. When the game starts, should a HexSystem be responsible for finding out the position of the camera, and also creating entities that are in-view - or should this logic be passed off to something outside of ECS?
I'd assume defining an area for cells to spawn in and pointing the camera that way would be a better solution, but yep, the other way around would work too. You can have a system that would manage cells constantly, or just a run-once system.
I also have an ECS question - does it have support for Raycasts ? Can i perform them inside a System's job ?
@frigid badge yes you can use Unity Physics and Raycast in Jobs, check the physics examples on github https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/UnityPhysicsSamples
great, thank you
Im trying to learn how to use parallel jobs on lists from this example https://forum.unity.com/threads/request-allow-parallel-writing-to-nativelist-when-writeonly-is-used-or-add-concurrent.522783/#post-3431853
Why am I getting this error saying the parameter needs to be a multihashmap?
I'm new to Unity and ECS, so maybe I'm wrong, but i suspect is has to do with job declarations inside ECS Systems working differently from general Unity jobs
in particular, they probably have different signatures in their Schedule method
that post is a year old, might be good to dive into the tests for the current package and see if things are different
thanks for the suggetions, where can I find these tests?
"ProjectName"\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities.Tests but theres also other places like com.unity.collections@0.1.1-preview\Unity.Collections.Tests
thank you!
@vale stream first glance the first param of schedule should be the size no?
I figured it out, the problem was I had IJobParallelFor instead of IJobParallelForDefer
You vould actually have used parallel for ;-)
I think deferred is for if you dont know the size of the list prior to scheduling
But can at times be slower due to this
this was just a test, in the real code I dont know the size ๐
Cool cool
ty for the suggestions tho ๐
I've spun some things out of my project, will add more features and tests later:
hello, i'm new on DOTS, and i just wanna know which feature can be use on production (build for summiting store)
i know Burst is not available for production
but when will it be available and is there any feature also can not be use for production too?
can anyone give me some advice please
So, everything is still in preview. You are welcome to use things in production but know that they can change anything at any time
However, I think they are relatively stable now and unlikely to introduce highly breaking changes
thank you @solar ridge , because i just want to move to ECS on producting some hyper casual game
i hope it fit with our target
Just know that the warning of preview is in place
so if they change or break something you are incharge of fixing ๐
Been playing around with making reactive systems; this is a usage example from what i have so far https://gist.github.com/jeffvella/a4ceba3bc24d786897aa1afd8960dc96
Its almost nice enough syntax; been struggling to get the burst jobs to work nicely with generic arguments.
@mint iron Does the GetEntityQuery with 2 desc's work for you?
Last time I tried it, it gave unexpected results
^ multiple desc's have always worked fine for me
the one thing I find mildly annoying/unclear is that 'Any' means 'at least one of'
@stiff skiff yeah it seems to be working, both queries have only an Any clause, which is probably a straight-forward variation to merge.
I tried it with a None, and the result always contained just 1 component, it was very odd
I'm following this tutorial
https://www.youtube.com/watch?v=ILfUuBLfzGI
I'm getting stuck at the rendering section because vs code says "The type or namespace name 'Rendering' does not exist in the namespace 'Unity' (are you missing an assembly reference?) "
which part of the video?
You'll need the Hybrid renderer package.
It used to come with the Entities package but then got spun out into it's own package
Anyone around who is knowledgeable in Pathfinding as well as ECS willing to take a look at my example project and answer a quick question for me? I would post the code, but its kind of situational and I would rather not flood the channel with a huge wall of text.
@winter depot how is it going
My man! can I post my github here or should I private message
no pms
I just wrapped up what I think is a viable solution, but am having a few issues where I think the pathfinding is ignoring blocked nodes. I am not sure why its happening, and I am not sure I am using IJobChunk correctly
Here is an example of me generating random blocked nodes, then 50 searches at once. I looks like most are following the the blocked nodes, but others just do what the want
just to confirm, your grid is entities?
No, the grid is a single entity with a dynamic buffer at the moment
May switch to a static native array later
whats the Cell component then
Thats the buffer
one thing i would recomend, is to not use hashmap
for the open list
but doesnt matter much
i dont see many issues on a quick glance
I also have an issue where if I resize the grid smaller and try to search for an individual path the index is incorrect. I have never worked with the chunk before so I think I am doing math incorrect somewhere
May be because I am already initializing with the 100x100 or something
Oh the open set is NativeMinHeap
With ECS - I'm generating a large hex-grid map where each hex is an entity - I completely understand that batching these into larger chunks is more optimised - but I'm wondering if there are any additional optimisations I can do to say "this entity will never move, so you can just forget it". Also - will just having these hex meshes in the game be optimised with Unity's culling, or is that an additional optimisation I'd have to make as well?
Is it possible that this is causing the issue at the end I am adding the start and it sometimes seems its not correct? current = stash.CameFrom[this.GetIndex(stash.Start)]; from = this.GetPosition(stash.Grid, current); stash.Waypoints.Add(from);
not sure
I don't think I was having issues before when I was using IJobParallelFor, but I rebuilt because I think this is better performance? I think my math is wrong on the total index count. Before I was using workers * size, now I am using chunk.count * size. Do you think that could have something to do with it?
I also see there are some problems in profiler.. am I supposed to split up chunks manually if its a larger job, or does unity handle that automatically? I feel like maybe most are running on this one thread when I try 50+ at once?
Hey guys! I'm having a hard time figuring out if its possible and how to access component data from outside an ECS system? Any guidance would be appreciated!
You need to get the component data via EntityManager
So let's say you have a MonoBehaviour
public class SomeMonoClass : MonoBehaviour
{
void Start()
{
var data = World.Active.EntityManager.GetComponentData<T>(some_entity);
}
}
You can also construct some sort of query from the EntityManager and then fetch the data using that query too
Alright, and this will fetch at runtime?
We are trying to create our CharacterController on the new Physics system and this is one of the things we were having issues with
I think I solved most of the issues I was having thanks again vblanco
Is it beneficial to pool entities ? Or should I just destroy and construct new ones ?
I know it's a big deal for GameObjects, is this a thing with entities too ?
i don't think you need to worry about pooling too much because creating entities is super fast, particularly in bulk and on primed/known archetypes. I'm sure there are some special cases where you've loaded an entity heavily with buffers and complicated components that would take some time to re-create/initialize, but even in that case you can use the conversion workflow which results in a prefab that is a fully setup version that is quick to instantiate (its just copying data with very little processing).
Anyone happen upon any examples of NativeStream?
there is the tests file https://gist.github.com/jeffvella/993ce20056d83f4b74e80a4e45b9d689 although its kind of hard to figure out how it works :S
also there's this quote from joachim Physics still uses BlockStream which is the same code. Just moved to Unity.Collections, cleaned up, renamed. Physics hasn't been upgraded to use NativeStream yet.
Yeah that was a reply to my comment XD
The tests show a perfect world environment. IE I know the size of the inputs going in
Kind of curious how one would go about scheduling an unknown read size
Defer requires a list or native array. I have yet to get a int* to work well
yeah its interesting, i had a quick look through the way they're using BlockStream in physics but it seems they've cleaned it up quite a bit for NativeStream
Where are you seeing this exactly? Physics package or github?
physics package source
com.unity.physics@0.1.0-preview\Unity.Physics\Base\Containers\BlockStream.cs
here's an example of how they're creating them in Solver.cs
https://gist.github.com/jeffvella/949532dd662ff586f8ad8724ab14b83b
its interesting that they use a job (BlockStream.ScheduleConstruct) to allocate/clear in burst. I wouldn't have thought that turns out faster after job overheads
I have a basic stupid question is it possible to get a component or an entity without using some kind of foreach or entityquery?
Yep, there's a bunch of methods for that on EntityManager. GetComponentData<T>(). I'm not sure if u can get an entity directly without a query or iterating, except if its a singleton then use GetSingletonEntity<T>())
yeah I looked at that but I think you need the actual entity
what are you trying to do, maybe i can help.
I'm just trying to figure out how to use a single entity component for player input
like an PlayerInputComponent thats a bool that I use to interact with other jobs
you could use a singleton from a convertToEntity and have the other systems that need it use the GetSingleton methods, thats what i did
is that update to unity.collections already out, or soon to be? @mint iron
but I heard singletons are bad mkay!!
singletons are just a tool :^)
dont abuse the tool and it doesn't matter what everyone says
no yeah I'm joking I will look into that thanks xzjv
@low tangle last collections was August 6, v0.1.1, it has NativeStream in it if that's what u were after?
@pliant pike Yeah its fine in this case i think if there's only ever going to be one entity for that purpose per world. The risk is that at some point you want to have multiple players and therefore multiple input components and you'll be forced to rework it.
Oh sweet I already have it then lol
Thank you, not able to check right now since I'm in bed
๐
I've seen some people putting input on every one of their game objects, just duplicating the data. I guess so that they can easily have access to it in an IJobForEach. But that seems little odd, then you have to update the input in 10,000 places with the same info, and writes aren't free.
o_O
Yeah but brute Force isn't a bad way to go with ecs, but 10k screams bad separation
I think I have like 6 entities total that get a job running over them. Not for speed, but for simplicity
Er, 6 entities with input components on them
makes sense. saves you having to look up the singleton all the time, pass it into jobs which adds extra code. Sometimes simplicity is best.
yeah that's what i thought
The thing I really dislike is for non job systems, the Singleton query keeps the system 'awake'
I mean technically I could use a single jobcomponent kind of as a singleton
Yeah? What are you thinking
use the EntityManager.GetExistingSystem etc and you can get all the variables etc from that
Job that reads the one entity and pastes into a native array?
Hm
Then the chain afterwards can read from that first array containing the query
just today i switched to new scene to play with some VFX and my damn component systems started whining about singletons not existing ๐ฆ had to go through and put HasSingleton checks everywhere. grr.
Hey I could even brute Force lookup my player entity that way...
I could prechache the inputentity in that one jobcomponent make it public
Yeah but I try to avoid systems working off other systems
And minimal caching of data in a system
It's nice when all the data that matters is in the ecs world only
I know but its just for testing and getting everything running to start with
Might have figured out a pattern I can apply to data lookup and make it way more sane
Yeah I gotcha
I make compermises on systems all the time
It's nice to go back and redo all the logic once you know the right way to dod it
yeah like I'm just relying on input because its an easy way to start things currently but for later on I want to make it more event based when I figure that out
in case it helps, here's the basic idea of what im doing for input: https://gist.github.com/jeffvella/21a24a99c216de05eeada72a37ae8202
The InputArchetypeBuilder script just goes on a prefab or whatever in the scene, stores the settings. Im trying to group related settings together so i have an InputSettings entity with multiple input related components etc.
is it bad practice to have a single system spawn new entities and also update them ? Should I split it in two separate systems ?
I dont think it's a bad practice
if you're doing it with the entity command buffer, you can update those spawned entities -
Entity e = CmdBuffer.CreateEntity();
CmdBuffer.SetComponent(e, T someData);
Otherwise, if its a ComponentSystem, you can likely use a ForEach or PostCommandUpdate
I have two jobs on one system, one for spawning, one for updating
and i had to decorate the system with UpdateAlways because of that
Since it operates on different sets of entities (none and those it updates) I see no particular reason to keep them together, an doing so also goes against the single responsibility principle, if you care about that.
If you had to use that decorator then that's another strike against
Single you already have two jobs it should be trivial to split it, too.
yep, the need for decorator to make it work made me think it's not a good way to write the system
In the end it's down to you, though. Which is easier to program? Is that worth other costs (perf? maintain? debug?)
Personally I would say to split it up, it sounds like you have two different things being done, and that means two systems in ECS
yeah, I'll just split it
Ah, i thought you meant you wanted to exclusively update the spawned entities
it updates exclusively the spawned entities, yes
Even then you should probably either keep track of them or, ya' know, just tag them.
^ yea, that's certainly another way
so far they don't need tagging, as they have a rather unique component
there is no real need to try to split everything into tiny chunks
just do what feels good to code, really, unless you are doing more performance critical systems where the parallelism works better if you have smaller systems
If others are interested here's MIke Acton's most recent talk I found ๐ค
https://www.youtube.com/watch?v=u8B3j8rqYMw
Dive into what data-oriented engineering means, how it radically impacts software engineering efforts and will drive us toward a future where our users get m...
@mint iron thanks for that example
mildly entertaining to see audience reactions interspersed throughout the talk, whose not convinced, whos following intently, who appears not to understand
is there now a reason to use PostUpdateCommands over EntityManager for mainthread component adding/removing?
a single sync point and possible batching
So if I wanted to store a hashmap of positions to tiles for example, where would I put that hashmap at? On an entity? On an entity doesn't sound right to me
On a system maybe?
@vestal hatch if its persistent then probably an entity, an entity can be anything, its just basically an address for the component data that you want
When allocating NativeHashMaps when I know exactly how many things will be in it, in the constructor should I put the exact number of things in capacity or should I make sure it has some percentage load factor?
specifically int3 keys with a known number of entries that will be added to it
I assume that's handled in the implementation? idk
Hi all. I'm setting up a project with ECS and need a bit of a pointer.
I want to understand better how to group and reference components by their entityID: I generate entities with translation components, and use the translation.Value to assign them to a grid coordinate (for localising them in a coarse step). I suppose I'll need a component for each grid coordinate which contains a native collection of some type that points to the entityIDs of these translations.
Later, I want to access all of the translation components referenced in each grid. I don't know how to do this.
I've been going through the samples - but there's a huuuge gap between the rotating cubes and the boids in terms of complexity - and unity videos (including by Mike Acton where he does a deep dive into the boids), but I'm struggling to get my head around this.
Would anyone be able to give me some pointers for resources to learn the intermediate level stuff, please? I'm already okay with generating entities with archetypes and rendering these, processing custom input data and translating that into player actions, but the stuff between that and the more complex scenarios is missing at the minute for me :(
Thanks in advance!
i'm not really following what you're trying to do with that grid, however one of the challenges is efficiently filtering and accessing the data.
For example lets say you have a grid 100x100x100, if you want to assign a newly instantiated entity to a position in that grid how can do you do it? you could have a GridPosition component on the entity (separate from its actual world position/translation). But then how can you ensure there's only one thing in each grid position? if you want to swap [25,65,9] with [29,89,100] how is that going to work without looping through a million grid positions? I haven't seen anyone come up with a good way to resolve these without some sort of external lookup outside of pure entities/component (although you can store it on an entity as a dynamic buffer).
For my use-case, I'm aiming to make the grid size large enough for a few hundreds or low thousands of entities' transform components to be inside each position. It's a sparse matrix, so that i can find neighbouring grid entity components to the player at run time, then go through each of the components referenced within that grid in a list of some type (NativeArray<int> where int is the entityID so I can somehow get the translation corresponding to that entity?).
I'm designing the grid size for my case so that it's at most 10x10x10 or so.
The step I'm most struggling with is how to store references and get them back out again.
You can just add the Entity from some sort of 'populate/initialize' system and put each Entity directly into the array. An entity Id is persistent so its safe to use them for references.
neighbouring grid entity components
hashmap with cell sized indexing like in boids
first job builds the mapping, second access by taking its position, changing to query, then reading the one or more in the hashmap for that cell
Thanks for answering. Like I said in my first post, I've been trying to understand the boids example, but struggling. I need something less complex to get my head around. The step from a single rotating cube to that boids example is absolutely massive
if you never change their positions you can build it once, and save the hashmap as persistent
yeah you have to get to the point of chaining jobs and building native hashmaps
plus implementing a hashmap for the position component that respects your cell size
just remember that outside of a hashmap setup, you should first try burst compiled brute force job scanning over your targets