#archived-dots

1 messages ยท Page 82 of 1

stiff skiff
#

its running on the main thread

pliant pike
#

that's at the start of the program, the framerate settles down to about 120fps

stiff skiff
#

Ah oke, I might be confused then since it ran in the simulation system group

pliant pike
#

I should probably schedule the job a bit later and see what happens

stiff skiff
#

As for your earlier question, yeah would love to see that code

#

always interested on how others use jobs

pliant pike
#

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;
                        }
                    }
                }
            }
           
        }
    }   ```
analog tangle
#

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'

dull copper
#

@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

minor sapphire
#

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 ๐Ÿ˜„

stiff skiff
#

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..

pliant pike
#

cant you then convert the nativerarray to a nativelist?

stiff skiff
#

No, though that's not the issue

mint iron
#

that method looks nasty, runs like 4 jobs

rain vault
#

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.

stiff skiff
#

Why would name lengths matter? The more something describes its content, the better

rain vault
#

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

stiff skiff
#

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

pliant pike
#

yeah I would rather call something supermarioxposition to be honest thats more readable than x to me, x could mean anything

stiff skiff
#

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)

rain vault
#

x really couldn't mean much else

#

you are familiar with the cardinal directions, right?

pliant pike
#

north east south west?

rain vault
#

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

pliant pike
#

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

rain vault
#

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

pliant pike
#

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

pliant pike
#

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

minor sapphire
#

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

rain vault
#

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

stiff skiff
#

If I were to read it now, it feels like sourceBlittableEntities would be a list of entities, which it is not

mint iron
#

@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.

stiff skiff
#

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

mint iron
#

i might have a play with it tomorrow.

stiff skiff
#

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

winter depot
#

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?

vestal hatch
#

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

Game Development Envato Tuts+

In this tutorial I will explain vector field pathfinding and its advantages over more traditional pathfinding algorithms, such as Dijkstra's. A basic understanding of both Dijkstra's algorithm and...

tawdry tree
#

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

winter depot
#

Thanks guys

mint iron
#

@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.

analog tangle
#

@dull copper Cool. Good to know.

winter depot
#

@mint iron Thank you

minor sapphire
#

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.

untold night
#

that seems like it should be impossible

minor sapphire
#

I guess I just assumed similarities with HashSet that I'm used to from standard/managed C# land

pastel hemlock
#

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.

faint scarab
#

Anyone know how to recreate entitymanger after recompiled?

dull copper
#

@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

safe lintel
#

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

safe lintel
#

Anyone using latest entities with 19.1 or 19.2 and getting black materials when gpu instancing is enabled on objects in subscenes?

pastel hemlock
#

I tried adding a few things from the example and nothing has seemed to change on the entity besides having the components.

idle glen
#

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

pliant pike
#

sure, isnt it just transferring a value, turning a switch from 0 to 1

tawdry tree
#

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

hollow sorrel
#

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?

pliant pike
#

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

hollow sorrel
#

yea but i mean

#

what's a use case for it

pliant pike
#

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

hollow sorrel
#

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

pliant pike
#

so even more reason to use it surely

hollow sorrel
#

ECB?

pliant pike
#

well unless theres some other method, Entity manager doesn't work that's the only way I've seen

hollow sorrel
#

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.
pliant pike
#

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

hollow sorrel
#

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

pliant pike
#

but that's what the above code is doing? the code above isn't using a PostUpdateCommand

hollow sorrel
#

you're using a entitycommandbuffer there

pliant pike
#

but what else would you use?

hollow sorrel
#

add it through the entitymanager directly

pliant pike
#

I tried that, you cant pass entitymanager into a job because its a reference value

hollow sorrel
#

that's what i said ๐Ÿ˜…

#

my question is about main thread ForEach iteration not jobs

pliant pike
#

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?

hollow sorrel
#

i assume ForEach lambda functions specifically refers to the ForEach lambda that you use inside a non-job ComponentSystem to iterate on main thread

pliant pike
#

Entities.Foreach are what work in a main thread component system though

hollow sorrel
#

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?

pliant pike
#

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

hollow sorrel
#

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

pliant pike
#

but thats what they are for

hollow sorrel
#

yeah but point is they made them unnecessary on main thread

pliant pike
#

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

hollow sorrel
#

yes it definitely does not

#

and that is part of the reason why it has nothing to do with the change i referenced

pliant pike
#

fair enough if you figure it out, I'd love to know

faint scarab
#

Do anyone know how can i recreate entity manger after recompiled?

mint iron
#

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.

vagrant surge
#

@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

pliant pike
#

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

vagrant surge
#

@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

pliant pike
#

well i mean adding and removing is surely a more complicated cpu intensive process than just queueing a command

vagrant surge
#

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

pliant pike
#

and anyway you can see that the whole AssignEmployeesJobComponent ends before the workers and it then starts the next Job

opaque aurora
#

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

hollow sorrel
#

ahhh that makes sense, thanks @vagrant surge

lime belfry
#

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(); 
    }
tawdry tree
#

What error does it give?

lime belfry
#

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```
mint iron
#

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.

pliant pike
#

yeah thanks, I was just confused with how it worked and what I was seeing

pliant pike
#

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.

vestal hatch
#

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?

pliant pike
#

but that's to get it into the job

vestal hatch
#

i see, still more context would help

pliant pike
#

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

safe lintel
#

just use the componentdatafromentity as you can already get the entity via the job

#

but then you need to write to it

pliant pike
#

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

safe lintel
#

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>

pliant pike
#

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

safe lintel
#

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;                        
        }
    }
pliant pike
#

that's great thanks, I was just thinking Ijobforeachentity

frigid badge
#

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?

fringe sinew
#

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?

stiff skiff
#

yes

#

There is no diffing , it just marks that you've written something

crystal zephyr
#

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.

frigid badge
#

Thank you, materials i found were missing those keywords, immediately found a bunch of manuals after searching for those terms

minor sapphire
#

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

amber flicker
#

@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);

mint iron
#

do you want to add a rotation amount onto the existing/current one? or just set it?

minor sapphire
#

just set it

#

ty @amber flicker I'm gonna take a look ๐Ÿ˜„

mint iron
#

have a look at quaternion rot = quaternion.AxisAngle(Vector3.up, math.radians(degreesAngle));

minor sapphire
#

AxisAngle looks like it will give me a quaternion by rotating one axis from identity by an angle

amber flicker
#

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

minor sapphire
#

interesting, I need to consider the options...

#

but looks like dinner now, I'll be back a bit later ๐Ÿ˜„

amber flicker
#

enjoy ๐Ÿ˜ƒ

minor sapphire
#

ty

tidal plume
#

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)

amber flicker
#

@tidal plume You can use debug log inside a job I think, so long as you disable burst?

tidal plume
#

Youre right

#

I had no idea, I must have misread everything. It works just fine

safe lintel
#

@minor sapphire there are also the rotationeuler components

minor sapphire
#

๐Ÿ˜ฎ I have not heard of such things lol I better check

#

oh interestiinngg

#

the transform system is much more in depth than I realised

fading moon
#

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?

minor sapphire
#

It's not the right channel. Maybe general code. Haven't worked with projectors. Texture size/resolution?

#

Could be one of the art channels...

verbal flint
#

Anyone ever change "Order in Layer", on the Sorting Group component, from within a timeline?
I'm on 2018.3

tidal plume
dull copper
#

oh, there's new hybrid package

#

well, now it finally works with latest 2019.3 alpha and it's HDRP out of the box ๐Ÿ˜ƒ

vagrant surge
#

@dull copper they improving hybrid ecs stuff?

dull copper
#

@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

vagrant surge
#

they allways do some DOTS related cool thing on them

#

so lets see what they will show

#

maybe a new demo

dull copper
#

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

vagrant surge
#

editor support when

#

still mad about it

dull copper
#

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

vagrant surge
#

what i dont like about unity demos

#

is how incredibly unstable they are

#

and hacked together

dull copper
#

isn't that like every tech demo ever made?

vagrant surge
#

look at unreal

#

you can download Infiltrator today, on latest unreal, and it wokrs

dull copper
#

well, look how long it took them to polish those demos

vagrant surge
#

and so do all of their samples/test projects

dull copper
#

I'm sure they were nothing like that when initially shown

vagrant surge
#

well yeah, but the first public version is pretty stable and they keep them working well on newer engine versions

dull copper
#

kite demo is still quite hacky

vagrant surge
#

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

dull copper
#

hmmm, was kite demo the last tech demo for UE4?

#

like, if we ignore smaller samples

vagrant surge
#

the newer raytraced ones arent published

#

you can get the runtime for the star wars one, but not the project

dull copper
#

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

vagrant surge
#

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

safe lintel
#

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 ๐Ÿ˜ฌ

vagrant surge
#

what i wonder. If unity is really doing a new game on the ECS stuff

#

are they using the conversion workflow?

dull copper
#

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 ๐Ÿค”

vagrant surge
#

roadmaps go wrong 9 / 10 times

#

2022 alpha

#

at best

safe lintel
#

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 ๐Ÿ˜ƒ

winter depot
#

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

#
safe lintel
#

i think you might be best off posing this question to the forums, so more eyes can give feedback on this scenario

winter depot
#

@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

faint scarab
#

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?

safe lintel
#

if you use the LinkedEntityGroup, when you destroy an entity that contains that buffer, all entities in that buffer should be also destroyed

faint scarab
#

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

tardy locust
#

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

low tangle
#

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

tardy locust
#

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

mint iron
#

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)

vagrant surge
#

@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

tardy locust
#

@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;
tawdry tree
#

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.

winter depot
#

@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

vagrant surge
#

@winter depot its very important to understand that not everything needs to be put on the ECS

tawdry tree
#

I do believe the solution they gave had all the pathfinding in pure DOTS (mostly burst jobs)

vagrant surge
#

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)

winter depot
#

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

tawdry tree
#

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.

winter depot
#

@tawdry tree yeah, itโ€™s sounding more and more like I need to use a hybrid approach

tawdry tree
#

It doesn't need to have any gameobjects

vagrant surge
#

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

winter depot
#

Well I guess in their scenario it was confusing because they needed to convert, but you are saying itโ€™s viable without

tawdry tree
#

They had to use gameobjects, as their game was already heavily OOP

winter depot
#

Thatโ€™s why I wanted to use a buffer for the nodes, instead of 500entities+

tawdry tree
#

In other words, they were locked in. You are not.

vagrant surge
#

@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

winter depot
#

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

vagrant surge
#

@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)

winter depot
#

So the hashmap is to replace the need for โ€œparentโ€ struct referencing that canโ€™t be done in structure

tawdry tree
#

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

vagrant surge
#

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);
}
winter depot
#

so Attachments is just the int value in the array, or hash map?

vagrant surge
#

int index in the array

winter depot
#

okay

vagrant surge
#

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

winter depot
#

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?

vagrant surge
#

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

winter depot
#

The map will never expand once generated

#

Only nodes will change flags

tawdry tree
#

Fixed size? Then it should be a 1D array (flattened 2D array)

vagrant surge
#

then just access the array directly and set the flag you want

winter depot
#

so if its 5x5, instead of having [0,0] [1,0] [2,0]..etc just have 0-24

vagrant surge
#

the biggest win with the array approach

#

i that you can add MORE arrays

tawdry tree
#

[[1,2],
[3,4]]
becomes
[1,2,3,4]

vagrant surge
#

and still use the same indices

#

lets say you need to store the name of some nodes

#

then just add a hashmap somewhere

tawdry tree
#

Careful of overengineering, tho

vagrant surge
#

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

shy garnet
#

N:N or 1:N?

vagrant surge
#

@shy garnet ?

shy garnet
#

nah, don't worry, I said nothing

winter depot
#

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?

vagrant surge
#

@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

winter depot
#

Okay

vagrant surge
#

mostly so you dont do stupid shit like accessing node 3 or similar, without really wanting to

winter depot
#

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?

vagrant surge
#

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

winter depot
#

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.

vagrant surge
#

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

winter depot
#

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

vagrant surge
#

yeah thats perfect

winter depot
#

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

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.

vale stream
#

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?

tawdry tree
#

Do you chain them? otherwise, I don't think so

stiff skiff
#

@winter depot I wouldnt use a component for request a path as you mention above

winter depot
#

Why is that?

stiff skiff
#

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?

winter depot
#

Yes, that is my thought currently. Again, I am trying to map things out because I am pretty new to this subject

stiff skiff
#

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.

winter depot
#

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?

stiff skiff
#

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

winter depot
#

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

stiff skiff
#

No component at all

#

Just a NativeList on your system that does pathfinding

winter depot
#

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

stiff skiff
#

You can still use all that

winter depot
#

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 ๐Ÿ˜„

stiff skiff
#

Use the ComponentDataFromEntity iteratora

#

Instead of the ComponentDataArrays

winter depot
#

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

stiff skiff
#

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

winter depot
#

Okay yeah, that's the part I need to look into. Other parallel jobs outside of IJobForEach.

stiff skiff
#

Ill help out once im behind a pc with keyboard ๐Ÿ˜ about 30 min or so

tawdry tree
#

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...

winter depot
#

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

vagrant surge
#

@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

stiff skiff
#

Cool I found a computer

#

@tawdry tree The archetype changes have some side effects that reduce performance permanently as well

vagrant surge
#

you can change the archetpye of an entire block at a time, and its much faster

stiff skiff
#

Though that only happens if you have multiple temporary components

vagrant surge
#

for a pathfind system, you would use that

vale stream
#

@vagrant surge I think you meant someone else? ๐Ÿ‘€

vagrant surge
#

tho adding the component will do archetype move :/

#

@vale stream ah shite, meant @stiff skiff

vale stream
#

Coincidentally I'm also working with pathfinding, so Im still finding all of this helpful ๐Ÿ˜…

stiff skiff
#

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

vagrant surge
#

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

stiff skiff
#

We've found out the issues of temporary components the hard way ๐Ÿ˜…

vagrant surge
#

@winter depot you could create a "request" entity

#

empty entity with just "PathRequest" component

winter depot
#

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

vagrant surge
#

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

stiff skiff
#

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

vagrant surge
#

the native list gotta be saved somewhere

#

and accessed from the other places

winter depot
#

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.

stiff skiff
#

So does the chunk for the request component

vagrant surge
#

adding the request as an entity could be done from within a command buffer

stiff skiff
#

The NativeList can be thread safe too ๐Ÿ˜‰

#

But yea, multiple ways to achieve this. I'm unsure what would be faster without testing it

vagrant surge
#

it does depend on the level of tryharding you want to display

winter depot
#

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

vagrant surge
#

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

winter depot
#

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?

vagrant surge
#

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

winter depot
#

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

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

winter depot
#

Yeah, I understand.

#

I am making sure I am following you guys on the garbage thing though

vagrant surge
#

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

winter depot
#

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

vagrant surge
#

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"

winter depot
#

There is a bit more to worry about there though when it comes to disposing entities though yeah? Unless they are nested

vagrant surge
#

well yeah

#

gotta check if they get orphaned

winter depot
#

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

vale stream
winter depot
#

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".

tawdry tree
#

"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.

winter depot
#

So like if you have entity #712 in world. That has nothing to do with the entity index you have in your job.

vale stream
#

okay, so it's kind of valid until the end of a systems OnUpdate, as long as no changes to the archetypes are made?

winter depot
#

Its just like your int in a for() loop

#

So yeah

mint iron
#

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.

vagrant surge
#

@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

mint iron
#

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.

vagrant surge
#

it does slow down add/remove

mint iron
#

thats very true

vagrant surge
#

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

winter depot
#

Jesus @vagrant surge you are a treasure trove of knowledge

vagrant surge
#

ive been resarching this stuff a LOT, and also made my own C++ version of unity approach

mint iron
#

awesome. i've rewritten entitas a few times in different ways to get rid of the code generation because i hated it so much.

winter depot
#

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

stiff skiff
#

@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

frigid badge
#

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.

winter depot
#

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/

frigid badge
#

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

winter depot
#

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)

frigid badge
#

yep, I noticed that the videos are pretty fresh

#

going to take a look

vale stream
#

do I have to set a NativeMultiHashMap's Capacity every time I make one?

mint iron
#

@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

vagrant surge
#

the codegen is so you buy the good codegen plugin XD

mint iron
#

๐Ÿ˜„

winter depot
#

Ohh you made one of the pathfinders that I spent some time looking at. Good man

mint iron
#

hopefully you didnt look too close the code is a bit messy ๐Ÿ˜„

winter depot
#

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

mint iron
#

it only uses the navmesh to set flags on which nodes are walkable, after that it never touches it

winter depot
#

Oh really? I may need to take a deeper look then

mint iron
#

yep, its just using a native array with 3d indexing

winter depot
#

Good stuff, hopefully I can convert it to 2d and use parts as an example

vale stream
#

do I have to set a NativeMultiHashMap's Capacity every time I make one?

low tangle
#

@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

dull copper
#

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).```
vagrant surge
#

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

mint iron
#

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.

vagrant surge
#

@dull copper did you see the latest Tiny version?

#

they are removing the DOTS-only editor, and just doing conversion workflow

dull copper
#

@vagrant surge whaaa

#

maybe they want to redo the dots editor

vagrant surge
#

i dunno

#

but they are going even more ham on the conversion workflow

dull copper
#

they definitely can't just can it

vagrant surge
#

Acton seems to like it

#

because you have your edit hierarchies and shit, and then convert into hyperoptimal runtime

dull copper
#

yeah, I've noticed :/

#

was so hyped about ecs editor

#

I guess we get that status update in like 6 weeks

vagrant surge
#

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

safe lintel
#

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?

tawdry tree
#

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.

vagrant surge
#

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

safe lintel
#

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. "

idle steppe
#

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.

pliant pike
#

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

winter depot
#

If they are in separate classes then I use [UpdateAfter(typeof(ExampleType))] above the class?

pliant pike
#

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

low tangle
#

@vagrant surge thank you so much!

winter depot
#

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;
pliant pike
#

yeah thanks for that Enraged that's pretty close to what I've got but the command buffer is in the first job

winter depot
#

And you are trying to add components before the second job?

pliant pike
#

yep

winter depot
#

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.

pliant pike
#

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

winter depot
#

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.

pliant pike
#

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?

vale stream
#

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?

trail burrow
#

@vale stream You can't pull from the queue in parallel jobs i think?

mint iron
upbeat mulch
#

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

tawdry tree
#

That looks like gameobject-hybrid code to me, is that the case?

mint iron
#

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

fringe sinew
#

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

#

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?

mint iron
#

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.

stiff skiff
#

What about making a system thats explicitly at the end, that calls Complete in the inputdeps jobhandle?

#

Ah nvm, that wont help

fringe sinew
#

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.

stiff skiff
#

@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

fringe sinew
#

I think it might work. The group is still a part of that same world and it has the same entity manager

#

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.

stiff skiff
#

You're using multiple ecs worlds?

fringe sinew
#

No

mint iron
#

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.

upbeat mulch
#

@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?

vale stream
#

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?

tawdry tree
#

@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.

upbeat mulch
#

I'm using scriptable objects tbh

tawdry tree
#

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.

upbeat mulch
#

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

tawdry tree
#

What unity version do you have? Have you installed the ECS package?

upbeat mulch
#

Unity 2019.2.0f1
I installed entities, jobs and burst. I think I did but I have no idea

tawdry tree
#

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?

upbeat mulch
#

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

tawdry tree
#

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.

upbeat mulch
#

Would it be possible to have entity physics like a rigidbody but for entities?

tawdry tree
#

People have been talking about physics here, and I think there is a package for that, but I don't know the specifics.

#

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.

vale stream
#

@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?

tawdry tree
#

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()

vale stream
#

yes but I think the problem is not knowing the size for the second job at the time of scheduling?

tawdry tree
#

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?

vale stream
#

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

tawdry tree
#

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

vale stream
#

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()?

tawdry tree
#

If you can manage it all chained, then that sounds like a good idea.
Sounds like you wanna do IJobParalellFor->IJob->IJobParalellFor then

vale stream
#

I'll give it a try! ty for the help, I'm quite excited to get this working ๐Ÿ˜„

tawdry tree
#

I know that feeling ๐Ÿ˜„

frosty siren
#

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.

mint iron
vagrant surge
#

@frosty siren dependency injection and callbacks goes 100% against the spirit and programming model of the ECS

solar ridge
#

Is it wrong I want the EntityCommandBuffer.Playback to have a ExclusiveEntityTransaction parameter overload? soarynDerp

pliant pike
#

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.

solar ridge
#

Why exactly would you need to do that? ๐Ÿค”

pliant pike
#

because the first job adds components to entiity's and the second job needs the list of updated entitys

vagrant surge
#

@pliant pike did you see you can now add components to entities while iterating in a for-each?

pliant pike
#

yeah but it still only happens in the main thread after the update of the JobCompSys

vagrant surge
#

wait really?

#

it isnt while iterating?

solar ridge
#

You are adding a new sync point though

#

All CommandBuffers run on main thread still

pliant pike
#

I know but either way the second job has to wait

vagrant surge
#

@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

solar ridge
#

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 soarynLOL

pliant pike
solar ridge
#

That was the post I was reading

#

Easiest way

pliant pike
#

I know the code is a bit of a mess

solar ridge
#

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

pliant pike
#

but the second job doesn't just need the entity's that have the component added it needs the whole list

solar ridge
#

The whole list?

pliant pike
#

well all business type entity's

solar ridge
#

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 ๐Ÿ˜›

pliant pike
#

yeah sorry I guess code in isolation is hard to read, I can't read anyone else's code

solar ridge
#

Let's start with the "whole list"

#

So you want the list of entities changing

#

What part is missing if we just provide that

pliant pike
#

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

solar ridge
#

And this business with "insolvent" what is the result now with it?

pliant pike
#

no result currently it just doesn't deduct but it will be used for more things down the line

solar ridge
#

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

pliant pike
#

ok yeah, that might work I'll try that, thanks leahT

solar ridge
#

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

pliant pike
#

I do need to call complete at the end to disable the job though

solar ridge
#

At the end...?

#

Of what?

pliant pike
#

of the entire jobsysystem, unless theirs another way

solar ridge
#

What do you think the return you are providing is?

pliant pike
#
       
        if(inputDeps.IsCompleted)
        {
            
            this.Enabled = false;
        }```
#

like that, otherwise it just keeps looping around

solar ridge
#

yeah... those lines are wrong soarynDerp

#

Unless

#

you wanted it to stop after one go...?

#

Calling complete is still a no

pliant pike
#

yeah I do I have it activates by spacebar press currently

solar ridge
#

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

pliant pike
#

I'm using another jobcomp for the input

solar ridge
#

For instance

protected override JobHandle OnUpdate(JobHandle inputDeps) {
    HandleRegister();

    if (!_otherManager.ExclusiveEntityTransactionDependency.IsCompleted)
        return inputDeps;
    _otherManager.EndExclusiveEntityTransaction();


    MoveEntities();

    return ScheduleBuild(QueueData(), inputDeps);
}
pliant pike
#

with refs to the other jobcomps just for simplicity and less confusion

solar ridge
#

This just sounds like a system that is diverting away from Data Driven Design

pliant pike
#

well its just for testing purposes and am currently learning

solar ridge
#

Fair. ๐Ÿ˜›

#

Just know. Calling complete() usually something has gone wrong

#

when working with a JobComponentSystem

pliant pike
#

DOTS is cool because I can build all systems in isolation, then figure how and where they go later

solar ridge
#

Yep

#

Decoupled systems is DDD

#

In your case scenario, you could just augment the previously mentioned path:

pliant pike
#

yeah I'm still not sure how I properly get a system to run once

solar ridge
#
   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

pliant pike
#

so I would pass the spacebar input to that job instead of keeping a reference to the job in another system

solar ridge
#

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

pliant pike
#
  if (Input.GetKeyUp("space"))
        {
            deductwagesfromsysref = World.GetExistingSystem<DeductandApplyWages>();
            deductwagesfromsysref.Enabled = true;```
#

like that

solar ridge
#

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

pliant pike
#

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

solar ridge
#

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

pliant pike
#

yeah I haven got into the systemorder grouping aspect yet

solar ridge
#

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

pliant pike
#

yeah thanks for the info

fringe sinew
#

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?

pliant pike
#

you have to do it manually jobhandle job1 = job1.schedule(this, inputDeps), job2.schedule(this, job1)

#

something like that

fringe sinew
#

Yep, just what I thought.

#

Thanks for the reply.

stark gust
#

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?

turbid sundial
#

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?

frigid badge
#

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 ?

mint iron
frigid badge
#

great, thank you

vale stream
frigid badge
#

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

safe lintel
#

that post is a year old, might be good to dive into the tests for the current package and see if things are different

vale stream
#

thanks for the suggetions, where can I find these tests?

safe lintel
#

"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

vale stream
#

thank you!

solar ridge
#

@vale stream first glance the first param of schedule should be the size no?

vale stream
#

I figured it out, the problem was I had IJobParallelFor instead of IJobParallelForDefer

solar ridge
#

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

vale stream
#

this was just a test, in the real code I dont know the size ๐Ÿ™ƒ

solar ridge
#

Cool cool

vale stream
#

ty for the suggestions tho ๐Ÿ‘

untold night
#

I've spun some things out of my project, will add more features and tests later:

https://github.com/periodyctom/Hydrogen.Maths

https://github.com/periodyctom/Hydrogen.Entities

lament orbit
#

I love this channel

#

๐Ÿ™

stark gust
#

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

solar ridge
#

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

stark gust
#

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

solar ridge
#

Just know that the warning of preview is in place

#

so if they change or break something you are incharge of fixing ๐Ÿ˜‰

mint iron
stiff skiff
#

@mint iron Does the GetEntityQuery with 2 desc's work for you?

#

Last time I tried it, it gave unexpected results

amber flicker
#

^ 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'

mint iron
#

@stiff skiff yeah it seems to be working, both queries have only an Any clause, which is probably a straight-forward variation to merge.

stiff skiff
#

I tried it with a None, and the result always contained just 1 component, it was very odd

upbeat mulch
#

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?) "

safe lintel
#

which part of the video?

untold night
#

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

winter depot
#

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.

vagrant surge
#

@winter depot how is it going

winter depot
#

My man! can I post my github here or should I private message

vagrant surge
#

no pms

winter depot
#

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

vagrant surge
#

just to confirm, your grid is entities?

winter depot
#

No, the grid is a single entity with a dynamic buffer at the moment

#

May switch to a static native array later

vagrant surge
#

whats the Cell component then

winter depot
#

Thats the buffer

vagrant surge
#

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

winter depot
#

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

turbid sundial
#

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?

winter depot
#

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);

vagrant surge
#

not sure

winter depot
#

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?

winter depot
#

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?

pale bramble
#

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!

coarse turtle
#

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

pale bramble
#

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

winter depot
#

I think I solved most of the issues I was having thanks again vblanco

frigid badge
#

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 ?

mint iron
#

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).

frigid badge
#

great

#

thank you

solar ridge
#

Anyone happen upon any examples of NativeStream?

mint iron
mint iron
#

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.

solar ridge
#

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

mint iron
#

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

solar ridge
#

Where are you seeing this exactly? Physics package or github?

mint iron
#

physics package source
com.unity.physics@0.1.0-preview\Unity.Physics\Base\Containers\BlockStream.cs

#

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

pliant pike
#

I have a basic stupid question is it possible to get a component or an entity without using some kind of foreach or entityquery?

mint iron
#

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>())

pliant pike
#

yeah I looked at that but I think you need the actual entity

mint iron
#

what are you trying to do, maybe i can help.

pliant pike
#

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

mint iron
#

you could use a singleton from a convertToEntity and have the other systems that need it use the GetSingleton methods, thats what i did

low tangle
#

is that update to unity.collections already out, or soon to be? @mint iron

pliant pike
#

but I heard singletons are bad mkay!!

low tangle
#

singletons are just a tool :^)

#

dont abuse the tool and it doesn't matter what everyone says

pliant pike
#

no yeah I'm joking I will look into that thanks xzjv

mint iron
#

@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.

low tangle
#

Oh sweet I already have it then lol

#

Thank you, not able to check right now since I'm in bed

mint iron
#

๐Ÿ˜„

#

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.

coarse turtle
#

o_O

low tangle
#

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

mint iron
#

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.

pliant pike
#

yeah that's what i thought

low tangle
#

The thing I really dislike is for non job systems, the Singleton query keeps the system 'awake'

pliant pike
#

I mean technically I could use a single jobcomponent kind of as a singleton

low tangle
#

Yeah? What are you thinking

pliant pike
#

use the EntityManager.GetExistingSystem etc and you can get all the variables etc from that

low tangle
#

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

mint iron
#

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.

low tangle
#

Hey I could even brute Force lookup my player entity that way...

pliant pike
#

I could prechache the inputentity in that one jobcomponent make it public

low tangle
#

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

pliant pike
#

I know but its just for testing and getting everything running to start with

low tangle
#

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

pliant pike
#

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

mint iron
#

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.

frigid badge
#

is it bad practice to have a single system spawn new entities and also update them ? Should I split it in two separate systems ?

coarse turtle
#

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

frigid badge
#

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

tawdry tree
#

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.

frigid badge
#

yep, the need for decorator to make it work made me think it's not a good way to write the system

tawdry tree
#

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

frigid badge
#

yeah, I'll just split it

coarse turtle
#

Ah, i thought you meant you wanted to exclusively update the spawned entities

frigid badge
#

it updates exclusively the spawned entities, yes

tawdry tree
#

Even then you should probably either keep track of them or, ya' know, just tag them.

coarse turtle
#

^ yea, that's certainly another way

frigid badge
#

so far they don't need tagging, as they have a rather unique component

vagrant surge
#

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

coarse turtle
pliant pike
#

@mint iron thanks for that example

safe lintel
#

mildly entertaining to see audience reactions interspersed throughout the talk, whose not convinced, whos following intently, who appears not to understand

safe lintel
#

is there now a reason to use PostUpdateCommands over EntityManager for mainthread component adding/removing?

stiff skiff
#

a single sync point and possible batching

vestal hatch
#

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?

pliant pike
#

@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

vestal hatch
#

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

wary anchor
#

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!

mint iron
#

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).

wary anchor
#

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.

mint iron
#

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.

low tangle
#

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

wary anchor
#

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

low tangle
#

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