#archived-dots

1 messages · Page 249 of 1

safe lintel
#

@rustic rain I have this ancient code from my project, that I dont use anymore but this is how I set that up for sprite rendering

            var spriteArray = m_SpriteQuery.ToComponentDataArray<SpriteRenderData>(Allocator.TempJob);
            //var spriteEntityArray = m_SpriteQuery.ToEntityArray(Allocator.TempJob);
            // We need slices
            for (var i = 0; i < spriteArray.Length; i += SliceCount)
            {
                matrixList.Clear();
                uvList.Clear();
                m_MaterialPropertyBlock.Clear();
                
                var sliceSize    = math.min(spriteArray.Length - i, SliceCount);
                for (var j = 0; j < sliceSize; j++)
                {
                    var sprite = spriteArray[i + j];
                    matrixList.Add(sprite.Matrix);
                    uvList.Add(sprite.Uv);
                }
                
                m_MaterialPropertyBlock.SetVectorArray(m_mainTexUv, uvList);

                Graphics.DrawMeshInstanced(
                    m_Mesh,
                    0,
                    m_Material,
                    matrixList,
                    m_MaterialPropertyBlock,
                    ShadowCastingMode.Off,
                    false
                );
            }
            spriteArray.Dispose();
rustic rain
#

what is SpriteRenderData?

deft stump
#

yuuup

#

I forgot lmao XD

safe lintel
#
    public struct SpriteRenderData : IComponentData
    {
        public Matrix4x4 Matrix;
        public Vector4 Uv;
    }
#

If i were to redo this that should be float4 and float4x4 now 🙂

rustic rain
#

hm

#

what is spriteArray in the first place?

#

Ok

#

It's array of individual components

#

oh I see

safe lintel
#

slicecount is 1023

rustic rain
#

I have my Material stored in shared component

#

it varies between entities

#

material is used to store data for shader and spritesheet itself

#

kind of global data per spritesheet

#

so I'm not sure how I can just loop through entities

#

and slice them without splitting them into chunks first

safe lintel
#

oh yeah, for that you need to iterate on the SharedComponent, get it in a similar way

rustic rain
#

which is what IBatchJob does perfectly

#

but how?

#

the only way I see is through IBatchJob

#

I just got a dirty idea in mind

#

what if I just

#

store all entities per batch lol

#

but then

#

that would be List of lists again

#

oooor

#

List of fixed lists

safe lintel
#

wait i have another system to do sprites but without animation

#

at some point I need to integrate the old stuff, so many things on the backburner

rustic rain
#

particleSharedRenderMeshes
What is this?

safe lintel
#

private List<SpriteRenderMesh> particleSharedRenderMeshes;

#

and sprite rendermesh is basically the same as rendermesh

rustic rain
#

so it's a collection of unique sharedcomponents?

safe lintel
#

just a reusable list

rustic rain
#

I'm interested in whether they are shared components

#

kek

#

cause rn it's the only thing I'm struggling to get outside of jobs

safe lintel
#

its shared public struct SpriteRenderMesh : ISharedComponentData, IEquatable<SpriteRenderMesh>

rustic rain
#

all right, that's good

#

let me go through that system again

#

hmm

safe lintel
#

the first loop of foreach actually is where the drawmeshinstanced happens

rustic rain
#

it's not instanced tho

#

oh

#

it's custom class

#

I see

safe lintel
#

i got this idea from joachim's gpu animation(3d) system

rustic rain
#

can I get all entities

#

that have this chosen chared component?

safe lintel
#

that might be a more succinct example of using drawmeshinstanced if you want to dive into it

rustic rain
#

I'v done indirect instanced before

#

no worries kek

#

it's dots that makes me struggle rn

safe lintel
#

but i mean of using it with dots, and getting the arrays of entities

#

from the guy who is cto of unity

#

his repo

rustic rain
#

I'll leave it for now, I need to make a simple rendering first, no need to go into more complex stuff

#

if I can't beat the easiest

#

so, is there a way to get all entities that have chosen shared component?

deft stump
#

what versions of packages do you have? I think the latest packages breaks compatability

rustic rain
#

it installs all dependencies itself

storm raptor
#

dots

#

Lol

deft stump
#

So

Entities : 0.17.0-preview.42
Jobs : 0.8.0-preview.23
Burst : 1.6.4
Collections : 0.15.0-preview.21
rustic rain
#

What are Unsafe Containers?

#

What do they allow compared to normal ones?

rustic rain
#

I think I'm starting to crack

#

how to do this

#
        Job.WithCode(() =>
        {
            var matrixHandle = GetComponentTypeHandle<LocalToWorld>(true);
            var animatorHandle = GetComponentTypeHandle<AnimatorSpritesheetComponent>(true);
            var spriteSheetHandle = GetSharedComponentTypeHandle<AnimatedSpritesheet>();
            var archetype = EntityManager.CreateArchetype(staticQuery);

            var chunks = query.CreateArchetypeChunkArray(Allocator.TempJob);
            for (int i = 0; i < chunks.Length; i++)
            {
                var batchInChunk = chunks[i];
                var ltw = batchInChunk.GetNativeArray(matrixHandle);
                var animators = batchInChunk.GetNativeArray(animatorHandle);
                var spriteSheet = batchInChunk.GetSharedComponentData(spriteSheetHandle, EntityManager);

                float[] indices = new float[animators.Length];
                Matrix4x4[] matrices = new Matrix4x4[animators.Length];
                for (int j = 0; j < animators.Length; j++)
                {
                    indices[j] = animators[j].currentIndex;
                    matrices[j] = ltw[j].Value;
                }
                MaterialPropertyBlock mtb = new MaterialPropertyBlock();
                mtb.SetFloatArray("_CutData", indices);

                Graphics.DrawMeshInstanced(mesh, 0, spriteSheet.material, matrices, animators.Length, mtb);
            }
            chunks.Dispose();

        }).WithoutBurst().Run();

All right, so far I got this
But I have no idea how to setup dependencies

#

since if I run it just like that

#

all those componentdata I access

#

gets invalidated

#

and it throws exceptions

safe lintel
#

        /// <summary>
        /// Todo later: figure out way to multithread this, assuming scheduling the drawmeshinstancedindirect can be figured out
        /// Job gathers particle buffers as native arrays, and adds them to a mega list. Jobs are separate to be able to observe performance
        /// cost in profiler, as well as leave door open to figuring out a better way to optimize the data transformations.
        /// </summary>
        [BurstCompile]
        struct GatherParticlesJob : IJob
        {
            public                             NativeList<Particle>              List;
            [ReadOnly]                  public BufferTypeHandle<DynamicParticle> ParticleBufferType;
            [DeallocateOnJobCompletion] public NativeArray<ArchetypeChunk>       Chunks;

            public void Execute()
            {
                for (int i = 0; i < Chunks.Length; i++)
                {
                    var chunk               = Chunks[i];
                    var particleBufferArray = chunk.GetBufferAccessor(ParticleBufferType);
                    for (var index = 0; index < particleBufferArray.Length; index++)
                    {
                        // Add reinterpreted to temp list
                        List.AddRange(particleBufferArray[index].AsNativeArray().Reinterpret_Temp<DynamicParticle,Particle>());
                    }
                }
            }
        }

i think this could be optimized

#

but also this is a bit specific to my own usage: particles are buffers on entities, as when I started this system I didnt want to touch EntityCommandBuffers when creating/destroying particles

rustic rain
#

nah, I only want to draw entities itself

#

so I think it's a bit simpler?

#

uugh

#

so you pass empty List to job and in job you fill it with data

safe lintel
#

pretty much

rustic rain
#

oh man, my brain is baked, but I want to try and finish it today lol

safe lintel
#

I still think the Job.Run might be a problem, i mean you are fairly close and its just one thing to rule out as far as potential problems

rustic rain
#

I tried without running at all

#

like

#

pure code in OnUpdate

#

I even put system in late update kek

#

[UpdateInGroup(typeof(PresentationSystemGroup))]

safe lintel
#

what was the error?

rustic rain
safe lintel
#

is that the error from Job.Run or just OnUpdate code?

rustic rain
#

both

#

it's same error

safe lintel
#

var archetype = EntityManager.CreateArchetype(staticQuery); try moving this outside of the job or to oncreate

rustic rain
#

wait a second

#

it's unused

#

huh

safe lintel
#

also I think you should just write it as:

OnUpdate() {
            var matrixHandle = GetComponentTypeHandle<LocalToWorld>(true);
            var animatorHandle = GetComponentTypeHandle<AnimatorSpritesheetComponent>(true);
            var spriteSheetHandle = GetSharedComponentTypeHandle<AnimatedSpritesheet>();
            var archetype = EntityManager.CreateArchetype(staticQuery);

            var chunks = query.CreateArchetypeChunkArray(Allocator.TempJob);
            for (int i = 0; i < chunks.Length; i++)
            {
                var batchInChunk = chunks[i];
                var ltw = batchInChunk.GetNativeArray(matrixHandle);
                var animators = batchInChunk.GetNativeArray(animatorHandle);
                var spriteSheet = batchInChunk.GetSharedComponentData(spriteSheetHandle, EntityManager);

                float[] indices = new float[animators.Length];
                Matrix4x4[] matrices = new Matrix4x4[animators.Length];
                for (int j = 0; j < animators.Length; j++)
                {
                    indices[j] = animators[j].currentIndex;
                    matrices[j] = ltw[j].Value;
                }
                MaterialPropertyBlock mtb = new MaterialPropertyBlock();
                mtb.SetFloatArray("_CutData", indices);

                Graphics.DrawMeshInstanced(mesh, 0, spriteSheet.material, matrices, animators.Length, mtb);
            }
            chunks.Dispose();
}

rustic rain
#

I'll comment it out for now

#

yep, progress

#

different error

#

at least now it tells what to do

#

I'm really uncertain how to create dependency

#

on smth that is not a job at all

#

oddly enough it does recognize archetype I use in system

safe lintel
#

I think it still is an issue where you are trying to use the job scheduler even with run, when it shouldn't be a job at all(in any case you cant use managed arrays with burst)

rustic rain
#

I'm fine with not using burst or jobs for rendering

#

since I can't pass native containers to draw call anyway

#

I do call it like you sent me btw

#

no job wrappers

#

just pure code in OnUpdate

safe lintel
#

ok how about

var renderMeshList = new List<RenderMesh>();
EntityManager.GetAllUniqueSharedComponentData(renderMeshList);
foreach (var renderMesh in renderMeshList)
{
    if(renderMesh.mesh==null)
        continue;
    query.SetSharedComponentFilter(renderMesh);
    var spriteAnimators = query.ToComponentDataArray<AnimatorSpritesheetComponent>(Allocator.TempJob);
    var localToWorlds   = query.ToComponentDataArray<LocalToWorld>(Allocator.TempJob);
    
    var indices  = new float[spriteAnimators.Length];
    var matrices = new Matrix4x4[spriteAnimators.Length];
    for (int j = 0; j < spriteAnimators.Length; j++)
    {
        indices[j]  = spriteAnimators[j].currentIndex;
        matrices[j] = localToWorlds[j].Value;
    }
    var mtb = new MaterialPropertyBlock();
    mtb.SetFloatArray("_CutData", indices);
    Graphics.DrawMeshInstanced(renderMesh.mesh, 0, renderMesh.material, matrices, spriteAnimators.Length, mtb);
}

#

note this doesnt address the 1023 limit for drawmeshinstanced

rustic rain
#

I cracked it

#

not entirely remember last thing I changed

#

xD

#

oh wait

#

now I do

#

[UpdateInGroup(typeof(PresentationSystemGroup), OrderLast = true)]

#

I order it to be the last

#

so it runs after HybridRenderer

#

which itself forces out all other jobs to complete

#

BUT

#

my instancing not working lol

#

it draws by individual calls

safe lintel
#

its always something 🙂

rustic rain
#

but not when I draw instanced

safe lintel
#

there is EntityManager.CompleteAllJobs but its a bit of a nuclear option and I wasnt sure if it was the chunk usage or something

rustic rain
#

Well CompleteALlJobs should happen at some point anyway

#

what is better moment

#

rather than drawing?

#

UNITY_DEFINE_INSTANCED_PROP(float, _CutData)
Do you happen to know

#

if I'm setting my data correctly?

#

mtb.SetFloatArray("_CutData", indices);

safe lintel
#

that part looks normal, id probably try to make a really simple test with a monobehaviour and render one sprite on its own(without dots, just draw meshinstanced just to be sure the shader works)

#

wait what about trying SetVectorArray? (edit forget this as you are indeed using a float array)

rustic rain
#
            for (int j = 0; j < animators.Length; j++)
            {
                indices[j] = animators[j].currentIndex;
                matrices[j] = ltw[j].Value;
                Graphics.DrawMesh(mesh, matrices[j], spriteSheet.material, 0);
            }
#

this works

#

like, I just put drawmesh call

#

inbetween

#

and it actually draws stuff

#

with same shader

winter depot
#

I just reread and watched all of the content in the https://learn.unity.com/course/dots-best-practices?uv=2020.1 course. ```I had already been working with dots for some time, but took a break due to frustrations with the idea of complexity vs scalability and how they can coexist. I kind of got most of my questions answered or at least clarified some things that I was foggy about before but just working through the motions.

My biggest question now is what is the official best practice on how to deal with the problem of heavy entities?
In the early parts of the course they are kind of adamant on using components themselves as tags for flags instead of using a component with a bool to early out of a system. Later they mention how each time you add/remove a component and a new archetype is created it lives forever as a chunk possibility, and the more variation of archetypes/chunks the less you are actually utilizing the cache friendly idea of ECS. At times they even say a better approach instead of frequent add/remove of components is to use a bool in a component as a flag.

Towards the end they briefly propose a solution is to break down your entities into sub entities and although they do not directly say how, I assume nesting where an entity points to another entity for say offensive info, and another entity for defensive info, etc. held inside of a component. If I am reading this correctly, that means that when actually dealing with these "parent" entities, we will need to use some sort of nested ComponentDataFromEntity reads right?

I feel like this is kind of the opposite direction of what they told us to do though, there just seems to be a lot of conflicting best practices in general. Does using the parent/child entities approach take up less overhead when it comes to reading the component data inside a loop than I am thinking?

Thanks for reading this wall of text, I just am hoping to finally get solid clarification.```

Unity Learn

If you’re working on a game (or other real-time simulation) that requires the most efficient CPU usage possible, then Unity’s Data Oriented Technology Stack (DOTS) is a great way to get the performance you need. However, to use DOTS successfully, you can’t simply grab the API documentation and dive straight in. Before you begin creating a projec...

safe lintel
#

Are you actually running into issues with the amount of data for your entities?

rustic rain
#

I draw about 5 entities now xD

#

but it's about learning stuff

#

besides

#

I love gpu instancing

winter depot
# safe lintel Are you actually running into issues with the amount of data for your entities?

I am concerned that as the project grows the variation of archetypes will grow considerably, and I am thinking I have been using components as tags too loosely. Its quite rare that I actually have the majority of archetypes being the same at any given time already. Between having components for things like AttackReady, Auras, MovementRequest, etc, I have insane variants. I assume maybe I should instead be creating entities and tagging them with references to the entities in question like in a DamageSytem instead of tagging the main entity itself, but then again I feel like its dirty because I am using more of the .EntityExists/ComponentDataFromEntity methods which I thought were reads that caused cache misses

rustic rain
#

all right, tried to do the same from mono - same thing

#

I guess smth wrong with shader?

safe lintel
#

@winter depot you can count the archetypes with something like

 var archetypes = new NativeList<EntityArchetype>(Allocator.TempJob);
 EntityManager.GetAllArchetypes(archetypes);
 Debug.Log(archetypes.Length);
 archetypes.Dispose();

I dont think theres an issue using exists/cdfe but I guess its fairly clear ideally you dont change components willy nilly, and they are doubling down on the enable/disable component state later on(some point prior to 1.0)

#

im currently at 600 for a simple fps personally, and trying to cut down my own use of component changes

winter depot
# safe lintel <@!307267386330054656> you can count the archetypes with something like ```cs ...

Yeah I was really really excited to see that they were working on the enable/disable component state. Thanks for taking the time to respond. I will check the amount at peak and get back to you shortly for your opinion. I guess I am just concerned in general because Mike was really adamantly against the notion that you shouldn't overoptimize early. I am just trying to not fall into that whole runs "good enough" approach early on, so later when it doesn't run so well its an entire refactor.

#

Also I am really hoping they get the package version synchronized soon, I can't stand that updating one package breaks all the others

coarse turtle
#

like sometimes grab more detailed profiling data in builds so you can make better decisions instead of a major refactor. And to also test on your target hardware as a usual routine

winter depot
#

Right, but when it comes to where should the data live on ECS that's where I am most worried about my future. If I am doing things fundamentally wrong early in that regard I won't just have to optimize a few loops in a few spots, I will need to break every major system apart and go through days of rebuild to get it back together with references pointing everywhere.

coarse turtle
#

well that's where I think tools help w/ this. Things like windbg helps with seeing memory addresses and how your data is laid out

#

but yea I definitely get what you're saying tho. tbh I started w/ more or less just overanalyzing small problems and seeing how I can make whatever small problem faster, but that's the approach that works for me 🤷
I didn't really care if they were fundamentally right/wrong

#

I do wanna say for this:

Towards the end they briefly propose a solution is to break down your entities into sub entities and although they do not directly say how, I assume nesting where an entity points to another entity for say offensive info, and another entity for defensive info, etc. held inside of a component. If I am reading this correctly, that means that when actually dealing with these "parent" entities, we will need to use some sort of nested ComponentDataFromEntity reads right?
The way I take "sub entities" is entities associated via a key (could be an index or some other value)

#

that's the approach that I use for my own project instead of nesting entities (I prefer flat hierarchies when I can in my own game since it's easier for me to debug with w/e existing toolsets dots editor gives)

winter depot
winter depot
coarse turtle
#

i have a struct Key : IComponentData { public uint Value }

#

i do have things in "fixed" size so I know I will never exceed a certain value

#

and then entities are mapped by Key

#

query things in parallel, write to index & prepare data for some gamelogic

#

and schedule it

winter depot
#

What does that gain you as opposed to using Entity and linking it directly? Also this is for purely static data then?

coarse turtle
#

no statics, just all entity data

#

i don't need to link an entity if i can just read/write things in parallel to a container with a unique index as a key

winter depot
#

I think maybe I am just confused, that feels less "ECS" to me because then systems aren't really running stateless right? It feels like sort of taking out some of the magic and just writing stricter code with jobs

devout prairie
# coarse turtle and then entities are mapped by `Key`

Is there any particular advantage to using a key rather than what Enraged suggested ( ie entity = myEntity inside the component ) ? I noticed 'nesting entities' mentioned above in the discussion.. my understanding is having an Entity field inside a component is essentially storing the entity 'id' not nesting or referencing - or am i wrong about that?

coarse turtle
#

i don't think there's any particular advantage tbh. 🤷 just made more sense to me to generate logic with unique indices over linking entities & public data

coarse turtle
devout prairie
winter depot
devout prairie
#

so i pretty much use components with Entity fields quite a lot.. for example in my RangeWeapon component it holds an 'Entity shootPos' field which i can then use as a key to grab the shootPos later

#

( probs cheaper to just store pos/rot of shootpos obviously but for now that's what i do 😛 )

coarse turtle
#

yea you're not wrong. The thing for me was that I needed to rely on open street map data. Linking entities together with open data is kind of a mess for that work I did. It'd mean querying and figuring out which entity I needed to sync together for data that came in asynchronously at varying points. To solve that, each entity was given a unique id. If another entity shared the same unique ID, then they were associated with each other.

devout prairie
winter depot
#

Ok @devout prairie I think that is exactly the sort of scenario I was describing based on what the documentation kind of leaned towards. I was more so thinking that ALL the offensive data min/max/range/attacktype/etc is included in one component field named Offensive or something that just stores an entity, which then has those components tied to that entity linked.

#

So I think I am understanding right, but like I said I was kind of worried about the amount of lookups I would have to do to actually get that data in the end, and was that worth the breakdown of the "heavy entity"

devout prairie
#

ah yeah so separate data entities essentially

coarse turtle
devout prairie
#

i do wonder what the consensus is on data heavy components, splitting them off onto separate entities, or even splitting the heavy components into separate components.. or even what is considered to be a heavy component.. for now, my core components all have a number of fields with different data types ( maybe 4-8 fields with ints/bools/float3's/whatever ) and i'm happy with it.. it's already complex enough building DOD/ECS systems in a complex game without adding additional layers of optimization complexity

winter depot
#

Yeah, that's exactly what I wanted to really learn when I started going over the content for "Best practices". I feel like they touch on so many things and sometimes extremely redundant or in depth, then just kind of make a quick pass at an actual practical use scenario of a best practice.

#

Complexity and Scalability are tightly coupled in my opinion

coarse turtle
#

oh for reference, in that project, we optimized our component sized

#

because we wanted to pack as many entities in a chunk

devout prairie
#

definitely interested in the idea of separate data entities though i have thought about this.. say an archetype/entity-array for just 'combat data' for each unit in the game, maybe a separate entity array for health data, etc.. but i'm not 100% if there's an advantage or not there

coarse turtle
#

but some entities were pretty large to the point we could only store a few hundred (maybe around 112 was the min iirc) into a single chunk

winter depot
#

This is the exact quote on how to solve the problem

#

This means the solution to the problem of heavy entities is to simply break them down into a larger number of lighter entities that can pack into chunks more efficiently. For example, if you divide your character’s components into different entities according to which SystemGroup processes them (for example, AI, pathfinding, physics, animation, rendering, etc.), those SystemGroups can iterate over chunks filled with components that contain only the data they need (for example, the chunks which the physics simulation access have room for more physics components because they aren’t also filled with AI state machine data).

devout prairie
winter depot
#

But as I said, my fear is that when I actually need to reference that data I am going down some nesting in a sense and I feel (maybe wrong) cache misses by doing this

coarse turtle
#

i think at max we only had to deal w/ 30,000 so we optimized for that

devout prairie
#

either way, just using dots/burst is going to be 100x faster i think

coarse turtle
#

but the median was about 12,000 entities

devout prairie
#

so i guess the returns on that level of optimization are only really relevant at quite large entity counts, because up to that point, you're already getting massive gains without really super-optimizing

#

i think this needs to be more clearly communicated and understood, because it's hard to know what's overkill optimization and what's 'more than enough' in ecs

#

and in what contexts

winter depot
#

I am not a forum post kind of guy, but I do think I need to go there for higher up clarity . I have a pretty lengthy set of notes that all have contradicting information from that best practices guide that I will try to lay out in a more concise manner and tag you when I post it so you can hopefully see the outcome.

coarse turtle
#

each chunk only had data relevant to what it needed for the heavy jobs

devout prairie
#

it's funny, ecs/dots has this dichotomy of being at the same time simpler/clearer and also more complex and difficult to reason out

winter depot
#

Major points summarized are they say avoid bools as tags/flags, instead use empty data components (future we get enable/disable state components), they also say do not have "heavy entities" because they cause too much fragmentation of chunks so you are causing cache misses. They also say avoid adding/removing components too often, if you find yourself doing this make bool flags instead. They then say avoid using the ComponentDataFromEntity too much, because it also can cause cache misses (need to find the direct wording they use in this one). They then say break down entities into more efficient chunks.

coarse turtle
#

yea ComponentDataFromEntity does random access

#

you might not be accessing an entity in the same chunk

winter depot
#

Right, which means there's a very fine balance where you have to choose a path, and neither path feel perfect.

#

It just feels like they teach this massive performance first idea. It really is great, and it can scale to insane proportions. So long as you limit complexity

coarse turtle
#

i will say im using ComponentDataFromEntity in my own physics systems cause im too lazy to optimize it 😛

devout prairie
coarse turtle
#

yea - that makes sense, im just too lazy

#

and it runs decently on a few thousand projectiles on a core i3-5th gen

devout prairie
#

i only ever really add/remove components/tags on init though ( ie if i have to do some setup on some entity ), basically i understand it's slower than using the bool/flag approach

winter depot
winter depot
#

The solution is we need those component enable/disable changes

devout prairie
#

For example i mentioned the 'Entity shootPos' field inside my RangeWeapon component.. so in my weapon firing system i'll first grab an EntityQuery and store all the shootPos Translations, then pass that into my main RangeWeapon loop and use RangeWeapon.shootPos as key to grab the Translation inside the loop

safe lintel
#

I think: if you have several hundred entities its not a big deal to throw a bool into a component to just do a soft disable, but if you are dealing with 100k+ or some insanely large number, then a component change makes more sense to not even run in a query, but its all dependent on your own project's needs

#

it still comes back to profiling often to ensure there arent hiccups

winter depot
#

Ideally though, you run an entity query that checks the component data itself for that flag so that the system doesn't run if none of them match the flag. Then all of the headaches I have I think would dissapear

safe lintel
#

im just talking about workarounds for now as we dont have enable/disable

winter depot
#

Yeah, I got ya. Thanks for the discussion guys, I think I will start breaking my entities into smaller entities based on what I gathered here.

safe lintel
#

but what is your project anyway? kind of has a huge bearing on just how much optimization is needed

winter depot
#

Its an RTS

safe lintel
#

I would only do that if you are running into an actual issue though? what constitutes a heavy entity for you?

devout prairie
#

How about using a flag component with Change filter, i wonder if that would be a good compromise..

coarse turtle
winter depot
#

Well, I mentioned earlier I think I am making the entities heavy because of how often I am adding removing components just to get a system to run once. For example, adding AttackReady component to any entity that has certain parameters that determine if it should be attacking. Then removing that component once an attack entity is created and all the data for that interaction is populated.

#

I do this with just about everything, whereas I could always be creating micro entities to just schedule something once. I then worry about the overhead of creating so many entities so frequently

safe lintel
winter depot
#

Yeah, this is amazing. They really need to update the documentation and learning materials to reflect this change coming

devout prairie
safe lintel
#

I dont view the adding/removing components to changing into separate entities to be solution to "heavy entities" necessarily. To me this is more an issue of state changing rather than a lot of data.
Like you could just keep a component that is queried in a system to see if that unit could attack. if you split this into another entity, its sort of tangential to the issue of adding/removing components.

devout prairie
#

essentially i think you're causing it to shuffle memory/arrays around constantly, rather than just, loop em all and check if they can attack this frame

safe lintel
#

in my mind, a heavy entity is one where you literally only have 3 entities per chunk

winter depot
#

I guess I will have to do some math to see how heavy my entities would actually get later on

devout prairie
#

additionally you are forcing the creation of more archetypes based on components being added/removed especially if that's happening a lot with a wide range of different tags

coarse turtle
winter depot
#

Like, for example I found doing Auras best if I use a buffer instead of many little aura components. This buffer could get pretty big since I want to hold all Aura data until they expire because of Aura levels of strength + duration reasons.

safe lintel
#

you can check this in the entity debugger, i sort of am nearing it for my weapon entities(7 per chunk if I am reading this correctly)

winter depot
#

Ok, I can clearly now see how badly having a fixed string is

safe lintel
winter depot
#

I think fixed strings are most of my heavy entities

#

I am going to switch how that's laid out, I guess blobs are the right direction

safe lintel
#

yeah can imagine they eat up a lot 🙂

winter depot
#

Thanks @safe lintel

devout prairie
safe lintel
#

this is just the first person player weapon stuff, no ragdoll stuff for the player

devout prairie
safe lintel
#

theres a spring system but its a ported version of the ufps spring system. my player weapon code started off from porting ufps to dots

devout prairie
#

ah right k

safe lintel
#

hm according to that thread I linked, joachim said 0.5 is already branched off

winter depot
winter depot
# safe lintel hm according to that thread I linked, joachim said 0.5 is already branched off

So in refactoring to the new bit flags, I assume they are going adjust the whole .WithNone, .WithAll, etc and they will add .WithEnabled/.WithDisabled or something like this. For the time being I guess this boilerplate should mostly just be commented out and rewritten for me and I just check the bool flag I am manually making. This sound like the solution most are going with in preparation?

deft stump
#

wait so enable/disable is otw in 0.5?

safe lintel
#

No @deft stump

deft stump
#

damn

#

my hope has been crushed again

safe lintel
#

tbh never even thought about it @winter depot

deft stump
#

trying to make my own conversion system.
Looking at the Entity Debugger, unity's own Convert To Entity just runs always?

coarse turtle
#

yea, but it's only for runtime conversion

river meteor
#

hey question for dots people in here

#

say i started up a URP project with dots, and just created a spawner that spammed capsules with physics bodies and physics shapes and nothing else. what would be the expected max # of capsules you'd expect to see before <60fps frame drops?

craggy orbit
#

i was able to get around 20k entities before any frame drops. i did have lots of additions on the CPU and GPU side though. you could probably get a lot more if you're not doing any complex work (sounds like you're not)

river meteor
#

i have 5k

#

and i'm down to 20fps with that

#

so i tried to figure out what i was doing wrong, i assume it's logically

#

but the person i was talking to lastnight was just like suggesting project configurations endlessly and i'm like i'm pretty sure it's not that lol

#

do you have an example of some boilerplate you'd use for a simple spawner? i'm sure i'm missing something simple

#

so here is my bullet prefab setup

#

old picture (i've since removed the capsule collider)

#

i've enabled gpu instancing on the material, i've enabled hybrid rendering v2 in the scriptping symbols

worn valley
#

Have you disabled all the safety stuff in the editor or run it in a non dev build?

rustic rain
#

Do you guys know whether there's any reason to use SRP?
Cause it appears SRP is incompatible with GPU instancing

half jay
#

Any tips what can cause this perf issue with physics on android? Any tips what should i check first?

north bay
half jay
half jay
#

one think that i can also add that in scene it was about 2000 static colliders without any rigidbody and also im not detecting their hitting

rustic rain
#

why do you think it's an issue in the first place?

#

maybe that's intended perfomance on your device

half jay
#

Im not sure just said some additional facts that may be will help

rustic rain
#

bruh, hybrid renderer sucks

#

I hope to see between URP and HDRP another one

#

ERP

#

kek

#

I can only imagine how perfomant it'd be, fully gpu instanced

river meteor
safe lintel
#

@river meteor as you are using ecb's you can schedule that with burst

river meteor
#

ecb?

safe lintel
#

just after the foreach, use _commandBufferSystem.AddJobHandleForProducer(spawnJobHandle);

#

entity command buffers

#

well you cant use UnityEngine.Random in that though

#

there is the Unity.Mathematics.Random for burst jobs

river meteor
#

oh ok. i did modify it to use Mathematics.Random I think

#

that's a good point though. i might have been previously screwing myself so it wouldn't run unless i put withoutburst

rustic rain
#

Is there a way to create authoring component that runs code inside of editor?

#

I want to make preview in scene view for my custom rendered sprites

karmic basin
#

Yes ? Nothing to do with DOTS though. Read the manual to learn more about editor scripting. Then people in #↕️┃editor-extensions would probably help

safe lintel
#

just use a monobehaviour @rustic rain

prisma anchor
#

I was trying to prototype my level with ProBuilder, but I can't get the player to collide unlike a regular primitive. Does ProBuilder work with Unity Physics?

stone osprey
#

Quick dumb question here...

Is it "okay" to cache entities ? Or should we query for them everytime we need a certain one ?

safe lintel
#

ive found most issues get resolved when you switch mesh colliders to physic shape equivalents, dunno whats happening behind the scenes but meshcollider to me is somewhat unreliable @prisma anchor

river meteor
#

EntitySpawnerSystem.cs(29,13): error DC0001: Entities.ForEach Lambda expression uses field '_random in a reference type'. Either assign the field to a local outside of the lambda expression and use that instead, or use .WithoutBurst() and .Run()

#

i'm not sure what this means. so i shouldn't get random values inside the lambda?

#

wouldn't the random values be the same for every object then?

prisma anchor
safe lintel
#

@river meteor can try

OnUpdate() {
var r = _random;
Entities.ForEach
}
river meteor
#

oh ok. what's the appropriate way to seed this version of random?

safe lintel
#

@prisma anchor and the appropriate mesh, and the mesh has read write enabled?

river meteor
#

wrong chat sorry lol

worn valley
#

Lol that has nothing to do with random. 😛

#

You need a randomizer that can be used in parallel. I think unity's new math library has something like that

#

You are trying to bring in a reference type to a strut which can't access that code during the job. Does that make sense?

river meteor
#

yes it makes sense

#

so i'm moving the references to _random outside of the lambda

#

but that means every entity is going to receive identical random values

#

that's what doesn't make sense

worn valley
#

You need to do the randomization inside the lambda which means you need to use math.random I THINK

prisma anchor
#

Rubber Ducky moment: I forgot to add Convert Entity....

worn valley
#

I forget how that works in burst

river meteor
#

you mean Unity.Mathematics.Random?

#

that's what i'm using

winter depot
#

I thought you stored random in a component on each entity that’s going to use it so the seeding works

#

However, the simplest way to generate good quality random numbers is simply to have one instance of Random per Entity, stored in a component. Jobs can use this instance to generate any random numbers which are required for data transformations on a particular entity, and the state will be unique and persist as long as its component exists.

karmic basin
rustic rain
#

How to exclude certain components from conversion completely?

#

is there such option?

#

I mean native components like renderer and etc

frosty siren
rustic rain
#

huh

#

btw

#

about your 2d renderer

#

is it based on built in or?

#

I'm really uncertain atm whether you can create gpu instanced shaders in SRP

unkempt abyss
#

(0,0): Burst error BC1064: Unsupported parameter `Unity.Mathematics.float3` `position` in function `(blah).Invoke(Unity.Mathematics.float3 position, float time, float vertexColor, void* payload)`: structs cannot be passed to or returned from external functions in burst. To fix this issue, use a reference or pointer.
just wanted to double check - I can't even pass a float3 through? so I should just pass in 3 floats seperately? 🤔

rustic rain
#

void* payload?

unkempt abyss
#

ignore that part 😄 that bits working as expected 🥲

rustic rain
#

what about return type?

#

allthough...

#

float3 is indeed a struct

unkempt abyss
#

good point, return type is float3 too

#

yeah just kinda thought it would handle float3 since it's all blittable and stuff 🤔

rustic rain
#

I wonder how to use pointer in this case

#

but reference would be way easier

unkempt abyss
#

bah yeah, return type is a problem 😦

rustic rain
#

just do ref

unkempt abyss
#

yeah think i'm gonna have to

rustic rain
#

Is there a way to keep resizable collection of entities prefabs?

#

so you can kinda keep serialized list in your game object singleton

#

and it will create same list but of entities

karmic basin
#

Dynamic buffer

river meteor
worn valley
rustic rain
#

Is there any need to keep blob asset store that is used during manual game object conversion? Or should dispose of it as soon as I got my entity?

rustic rain
#

is Dependency property after running Schedule on job in SystemBase contains job handle of that scheduled job?

#

I want to add my own system as dependency to other system

tepid abyss
#

Hey, is there a way to edit entities during play mode? all fields seem to read only in the inspector

rustic rain
#

sadly nope

north bay
#

But who knows when that will drop

rustic rain
#

in 2028

rustic rain
#

hmmm

#

any idea how to cause triggers

#

to run main thread code

#

from inside job?

#
        Dependency = Entities
            .WithReadOnly(interactables)
            .WithReadOnly(ground)
            .ForEach((ref DynamicBuffer<CollisionEvent> collisionBuffer, ref PlayerVelocity playerVelocity) =>
        {
            if (!collisionBuffer.IsEmpty)
            {
                var hit = collisionBuffer[0].colliderHit;
                if (interactables.HasComponent(hit.Entity))
                {
                    var data = interactables[hit.Entity];
                    playerVelocity.value.x += data.velocityBoost;
                    playerVelocity.value.y = 20f;
                    buffer.RemoveComponent<PhysicsColliderBlob>(hit.Entity);
                }
                else if (ground.HasComponent(hit.Entity))
                {
                    // Game should be over
                }

                collisionBuffer.Clear();
            }
        }).Schedule(collisionHandle);
#

in that commented area

#

I need to run

        shootCannonSystem.Reset();
        GameState gameState = new GameState
        {
            state = GameStatus.OnStart
        };
        SetSingleton(gameState);

such code

#

where Reset() is also interacting with EntityManager

#

I don't care at what point code will run, as long as it will run in current/next frame

#

But I need to avoid sync point

#

where I have to do Run()

#

I guess I could add another buffer for Events kek

#

feels a little bad tho

#

that I'll have to create system update that will query through every frame

#

just to know whether something is triggered

deft stump
rustic rain
#

so they want me to query through?

rustic rain
#

wait what

#

SetSingleton changes original entity?

#
        gameStateEntity = EntityManager.CreateEntity();
        GameState gameState = new GameState
        {
            state = GameStatus.OnStart
        };
        EntityManager.AddComponentData(gameStateEntity, gameState);

I have this code in OnCreate()

#

oh wait nvm

#

I referenced wrong entity

deft stump
rustic rain
#

I wonder how it works internally

#

does it actually checks queries every update

#

or

#

has some sort of event system during structural changes

deft stump
#

and then do work

deft stump
rustic rain
#

I mean

#

what is inside of all those structural changes

#

I'd guess they internally disable certain systems during structural changes

#

kinda like put bool on query

#

whether it's active or not

deft stump
#

???????
all it does is add / remove stuff to the internal database

rustic rain
#

if that's true then it's a waste

#

since queries are known whether they should run or not after structural cahnges

#

and I can't think of a way for empty query to run without another structural change

#

tbh, I think it does work like I think

#

since queries have property

#

IsEmpty

#

which is bool pointer

#

how to correctly get ComponentType of DynamicBuffer?
ComponentType.ReadWrite(typeof(DynamicBuffer<CollisionEvent>))

#

this gives me an error

#

nvm

#

you need to reference buffer element type

gusty comet
#

Does DynamicBuffer.Reinterpret<T> have any sort of safety mechanism? Like, if the input struct is

public struct Test1
{
  public Entity entity;
  public float2 location;
}

and the output type is

public struct Test1
{
  public float2 location;
  public Entity entity;
}

will an exception be thrown, or will the data be incorrectly casted silently?

rustic rain
#

nnnope

#

no checks

worn valley
#

Roll the dice.

rustic rain
#

GetComponentDataFromEntity<Translation>(true)
I assume reading it outside of job is unsafe?

rotund token
#

Yeah you'd need to complete the dependency first to be sure

#

Outside of a job you should just use entity manager

rustic rain
#

oooh

#

I forgot about using EM

#

kek

gusty comet
tepid abyss
#

Hey, I am moving a lot of entities towards a target, and I am trying to avoid them being overlapped, is there a way for me to access the Translation of other entities inside Entities.ForEach (of the same Archetype)?
(Or if anyone has an efficient way to avoid overlapping sprites in 2D without using the physics engine?)

worn valley
#

Are you changing the translation at the same time you are looking at it for each entity?

tepid abyss
#

No, I only change its velocity

worn valley
#

Cause you should be able to grab the translation component within the lambda

#

If you only want the same archetype you should use whatever Chunk for each is now using

#

Like check the chunk

tepid abyss
#

That way I could access other entities translations?

#

within the same foreach loop

worn valley
#

Yup. You should think about in the instance you are doing a forEach loop what is being read, what is being written and what is being both read and written

#

So if you are only reading things it is safe to read whatever

#

I believe you use the IN on the arguments in the lambda

#

that means it only reads and doesn't write

tepid abyss
#

Yeah okay I just read IJobChunk (Just started using DOTS), one thing is bothering me, I want to check for collisions and "push" away the entities from the collider, the IJobChunk iterate in chunks, what if one entity is colliding with another and they are in two different chunks?

worn valley
#

You can also get an array that is referenced by entity name

#

I did a lot before they added the lambdas so I can't tell you how t get that info

#

Then you want to use the getComponent by entity reference

#

It's slower because it's random access though but will still be pretty fast

#

Sorry I can't remember the function call off the top of my head. It's something like GetComponentDataFromEntity

tepid abyss
#

Yeah I tried using it but it kept throwing exceptions because I indexed into another chunk

worn valley
#

Oh weird that should be fine. Maybe something has changed.

#

In a previous job you could pull all the data you need into a native array

#

And then pass that into the next job

tepid abyss
#

Wait, I did something wrong on my end, I didn't specify ReadOnly on the entity list

#

Now it is working as intented! 😄

worn valley
#

There it is!

tepid abyss
#

thank you!

worn valley
#

Yay

#

I find ECS and DOTS is like 90% figuring out how to get the data you need

#

And not the actual code

tepid abyss
#

var enemyArray = GetEntityQuery(typeof(EnemyTag)).ToEntityArray(Allocator.TempJob);
needed to grab the enemy array and mark it as ReadOnly to iterate over it

#

Yeah, I am still new to this

worn valley
#

That isn't the function I remember but they may have changed it

tepid abyss
#

That's another one that I needed to use (There might be more that I still don't know of), but I did use the one you specify to get the Translation's

worn valley
#

Cool. I find the translations weird because they reference the LocalToWorld instead of being the actual current data. So sometimes you can get weirdness because local to world and translation is out of sync

#

I ended up dumping translation and rotation because you can get that info from LocalToWorld except it's a little more complex.

#

But you don't have to worry about translation not updating LocalToWorld at the same time

prisma anchor
#

Is there a good technique for one-off systems to be invoked? like spawn object or create X. Right now I create data with the system, and delete that entity

worn valley
#

You can use entities with components to do this. You create an entity and add a component that is something like "SpawnNewBoss" and a system that requires that component to operate. At the end of the frame destroy the component or entity you made and the system stops running

#

That's roughly how the DOTS net stuff works for messages

prisma anchor
#

so pretty much what i do now

worn valley
#

Simplest solution is sometimes right

prisma anchor
#

yea

worn valley
#

The only downside is you are creating sync points but you will be doing that anyways by creating new entities

#

And you can use an entity command buffer to create and destroy the entities later and in parallel

prisma anchor
#

ok thanks!

rustic rain
rustic rain
#

You guys

#

is there particles in dots?

#

I see so many mentions

#

but not any actual tutorials

#

oh nvm, i finally found unity manual

rustic rain
#

bruh, it's onlyy for Tiny

rustic rain
#

I guess in order to create my own particle system

#

I'd just need to create particle prefab

#

and authoring component that stores reference to it and settings (like, how long it lives, how many and etc...)?

still pewter
#

Hi everyone, I'm trying to make a 3D following system, like a homing missle. Simple enough in default Unity, but with Unity.Mathematics it's a bit trickier I find. I got it working in 2D but when it's 3D cross vectors and quaternions make my brain all jumbled and I'm afraid I'm making this way complicated than it actually is.
Has anyone gone before me? Any advice or tips or code?

rustic rain
#

it's all the same as normal unity 3d space

#

but

#

for some reason quaternions in dots are using different euler conversion

#

not even sure, but so far

#

all you need to figure out is your correct euler angle in code if you are converting between those and quaternions

#

otherwise it's all the same

#
            .ForEach((ref Rotation rotation, in LocalToWorld ltw) =>
            {
                //Modify holder's X rotation
                Quaternion rot = rotation.Value;
                float x = rot.eulerAngles.x - 15f * comp.deltaMouse.y * delta;
                //Angles are weird in dots, requires complex clamping
                x = (x > 200) ? math.clamp(x, 269.9f, 370f) : math.clamp(x, -10f, 90.1f);
                rotation.Value = Quaternion.Euler(x, 0, 0);

            }).ScheduleParallel();

here example of my mouse X axis clamping (up/down)

#

in classic unity I'd just do

#

Mathf.Clamp(transform.rotation.eulerAngles.x, -90f, 90f);

#

but in dots I need to do this nonsense kek

rustic rain
#

I use Quaternion's one

vagrant lotus
#

lower case quaternion have

rustic rain
#

ahem

#

it has conversion from euler

#

not to

vagrant lotus
#

oh

#

thats cause ambiguity when doing so

rustic rain
#

maybe, but so far it's the only way

#

unless you implement

#

to euler conversion yourself

vagrant lotus
#

ye

rustic rain
#

which I wasn't looking for

#

maybe you happen to know any other way to clamp only certain axis without conversion to euler? xD

#

actually the question I was looking for a long time

vagrant lotus
rustic rain
#

it's for mouse rotation

#

up and down

#

so you are clamped

vagrant lotus
#

quaternion.axisangle?

#

you can multiply 2 quaternion together

rustic rain
#

I know how to rotate smth with quaternions

#

but how you rotate clamped

#

so you don't rotate over certain angle

vagrant lotus
#

oh

rustic rain
#

basically so you won't be able to do somersault with mouse kek

rotund token
#

are you looking for a free look camera?

#

because yeah if you need to clamp, just convert back to euler

#
var localEulerAngles = mathex.ToEuler(rotation.Value);
var look = math.radians(input.LookRequireEnable()) * camera.LookSpeed;
var newRotationY = localEulerAngles.y + look.x;
var newRotationX = localEulerAngles.x - look.y;
newRotationX = math.clamp(newRotationX, math.radians(camera.XRotationMin), math.radians(camera.XRotationMax));
rotation.Value = quaternion.Euler(newRotationX, newRotationY, localEulerAngles.z);```
my code for clamping my free look rotation
vagrant lotus
#

mathex?

rotund token
#

oh thats probably from my core library

vagrant lotus
#

cool

rotund token
#

yeah looking at it

#

it's the ToEuler from the Unity.Physics package

vagrant lotus
#

still a valid dots only solution

#

👍

rustic rain
#

phyiscs?

#

huh

#

I don't get it

#

where do I get it

#

what is mathex?

rotund token
#

mathex is just a class in my core library

#

the ToEuler just had a comment i wrote

        /// <remarks> Taken from Unity.Physics. </remarks>
        /// <param name="q"> The quaternion. </param>
        /// <param name="order"> The winding order. </param>
        /// <returns> Euler angles in radians. </returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static float3 ToEuler(quaternion q, math.RotationOrder order = math.RotationOrder.Default)```
#

i just took this method from the Unity.Physics package

rustic rain
#

is that all?

rotund token
#

?

rustic rain
#
[MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static float3 ToEuler(quaternion q, math.RotationOrder order = math.RotationOrder.Default)
#

all you need to define?

rotund token
#

no

#

the method is huge

#

i can't post it here too long

vagrant lotus
rotund token
#

hence im saying if you want it, i literally just copied it from unity physics somewhere and you could find it there as well

rotund token
vagrant lotus
#

under which class?

#

(I might be blind)

rustic rain
#

could you just send file txt here? xD

#

I promise to repost it for future generations kek

vagrant lotus
#

kek

vagrant lotus
#

one of the last comments

rustic rain
#

When I'm doing this but without auto generate, is there a way to ensure my entity prefab will be converted only once?

#

So when I put my autohring mono on several GO

#

and add to them same GAmeObject as prefab

#

all of them will be same entity in the end

#

not multiple equal entities instead

rustic rain
#

if anyone wonders about question above: IDeclareReferencedPrefabs

#

Soooo

#

Do you guys know any better idea how to resolve trigger events on collisions?

#

rn I do this by quering through dynamic buffer with collision events elements

#

but in the end I clear buffer

#

so it only triggers once

#

and if I want to add another trigger related to collision

#

that would mean I need to expand my query

#

aaand the list can go on

#

Meanwhile I kind of want to avoid creating such God System

#

that takes 15 components to ref

#

hmmm

#

Can multiple same components be added to same entity?

rotund token
#

No

rustic rain
#

if I try to do that through buffer or entity manager I'll get error or?

#

I just want to avoid exceptions in this case

rustic rain
#
        var buffer = bufferSystem.CreateCommandBuffer().AsParallelWriter();
        Entities.WithAll<SpawnParticles>().ForEach((Entity entity, int entityInQueryIndex, in ParticleSystem particleSystem, in LocalToWorld ltw) =>
        {
            Random random = Random.CreateFromIndex((uint)entityInQueryIndex);
            for (int i = 0; i < particleSystem.numberToSpawn; i++)
            {

                Entity newParticle = buffer.Instantiate(entityInQueryIndex, particleSystem.particlePrefab);
                Particle comp = new Particle
                {
                    timeLeftToLive = random.NextFloat(particleSystem.minLifetime, particleSystem.maxLifetime),
                };
                buffer.SetComponent(entityInQueryIndex, newParticle, comp);
                Translation translation = new Translation
                {
                    Value = ltw.Position,
                };
                buffer.SetComponent(entityInQueryIndex, newParticle, translation);
            }
            buffer.RemoveComponent<SpawnParticles>(entityInQueryIndex, entity);
        }).ScheduleParallel();
        bufferSystem.AddJobHandleForProducer(Dependency);

Any idea what I'm doing wrong?

#

oh looks like I didn't add component to prefab

safe lintel
#

anyone find the rotationeulerXXX components dont update in the inspector?

rustic rain
#

there are no such components in base entities tho

safe lintel
#

by XXX I meant all the combinations of XYZ/ZYX/YXZ etc, and its in the transforms namespace

rustic rain
#

oh

#

Are there any system to update them then?

safe lintel
#

its part of the builtin transform system, euler types dont seem to update in the inspector though(also shows as a 4x4)

rustic rain
#

you can check used by systems

#

in inspector

safe lintel
#

I mean its actually working and rotating, but the values only report as 0, even when they are not 0

karmic basin
#

com.unity.dots.editor have these : class RotationEulerXYZInspector : Float4x4ValueInspector<RotationEulerXYZ> I guess they should be involved in the editor field drawing ? 🤷‍♂️

#

maybe you found a bug 😁

pliant pike
#

I find that components in general don't update in the inspector you have to click on and off them and then maybe after a while they might update

safe lintel
#

@karmic basin thanks, if you replace it with Float3ValueInspector it works. Also NonUniformScale is 4x4 as well 🤔

robust scaffold
#

ugh, reopened my ongoing dots project for the first time in months and god damn it nothing works. thats what I get for following 2022b...

#

time to get everything working again, pain

gusty comet
#

hello, I recently started studying dots and I had a question: everywhere it says that you need to call dispose on NativeArray, but if my Job uses NativeArray to get data from entities, do I also need to Dispose it?

public class MovementSystem : SystemBase
{
    struct MoveJob : IJobEntityBatch
    {
        public float DeltaTime;
        public ComponentTypeHandle<Translation> TranslationTypeHandle;
        [ReadOnly] public ComponentTypeHandle<Rotation> RotationTypeHandle;
        [ReadOnly] public ComponentTypeHandle<PlayerTag> TagTypeHandle;
        public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
        {
                NativeArray<Translation> translations = batchInChunk.GetNativeArray(TranslationTypeHandle);
                NativeArray<Rotation> rotations = batchInChunk.GetNativeArray(RotationTypeHandle);
                for (int i = 0; i < batchInChunk.Count; i++)
                {
                    translations[i] = new Translation { Value = translations[i].Value + (math.mul(rotations[i].Value, new float3(0, 0, 1)) * DeltaTime) };
                }
                translations.Dispose() //?
                rotations.Dispose() //?
        }
    }
}
robust scaffold
#

Manual deallocation of NativeArrays only need to be done for NA you create / allocate yourself,.

karmic basin
karmic basin
safe lintel
#

well localtoworld 4x4 works as expected, I expect its just where the actual data is float3 and its a 4x4 inspector it wasnt showing correctly

karmic basin
#

Ooooh then maybe they started as a 4x4 because of quaternions but they forgot to switch it for the euler representation ones, do you think ?

safe lintel
#

quite possible

#

@pliant pike I have experienced that in the past

robust scaffold
robust scaffold
#

As a side note actually, the built in entities inspector does occasionally crash my editor when I attempt to look at a world that updates asynchronously from main thread graphics due to use of exclusive entities transaction invalidating access to external entity manager. Very annoying.

#

I think it's due to overloading the log due to large amount of stack trace dumps every frame.

hollow jolt
#

what does it mean to assign it directly ?

#

ok i think i found it

pastel field
#

If DOTS Animation is inaccessible in Unity 2021.X (dependencies break so no AnimationCurveBlob) what is the solution today to use AnimationCurve in ECS?

tepid abyss
#

Hey, I am trying to create a custom shader graph for Hybrid Renderer V2, I followed multiple instructions to make sure I didn't mess up anything, the renderer output error:
A Hybrid Renderer V2 batch is using the shader "Shader Graphs/TestShader", but the shader is either not compatible with Hybrid Renderer V2, is missing the DOTS_INSTANCING_ON variant, or there is a problem with the DOTS_INSTANCING_ON variant.

I am using Sprite Unlit in the shader graph, don't know if that matters.

#

(Also, I deleted the ShaderCache and reopend Unity after declaring the HYBRID_V2 define)

#

The generated shader file doesn't seem to be containing the DOTS_INSTANCING_ON define so the error is correct, but why it didn't add it though

#

Oh, when I switch to Lit it does work, so the problem is with Sprite Un/Lit

#

And it also seems that URP Material Property Base Color doesn't work on Sprite Renderer, I looked at the code and they querying for Renderer, so it should have worked, but doesn't

tepid abyss
#

Okay, the URP Material thing is just because the Sprite Un/Lit use _Color and not _ColorBase, so I need to create a custom authoring script with the MaterialProperty attribute

#

I was wrong, its not just the property name, the whole system doesn't work with Sprite Un/Lit shader graphs it seems, and not with SpriteRenderer (Used another mesh with MeshRenderer and the same material + authoring scripts (Urp Material Color) and it seems to work)

rustic rain
#

hm

#

When you destroy entitiy, is there a way to specify to also destroy all it's children?

#

transform children I mean

rotund token
#

there's a linked buffer for this built in

candid epoch
#

how are you guess handling static values that you use in bursted jobs? do you move them to static readonly fields? does burst always inline this stuff or should i just keep them as "magic numbers" to make sure they are as close as possible to the code were they are used (to prevent cache misses)?

rustic rain
rustic rain
rustic rain
#
    private static void DestroyEntityRecursively(EntityCommandBuffer.ParallelWriter buffer, int entityInQueryIndex, BufferFromEntity<Child> data, Entity mainEntity)
    {
        if (data.HasComponent(mainEntity))
        {
            var entityChildren = data[mainEntity];
            for (int i = 0; i < entityChildren.Length; i++)
            {
                DestroyEntityRecursively(buffer, entityInQueryIndex, data, entityChildren[i].Value);
            }
        }
        buffer.DestroyEntity(entityInQueryIndex, mainEntity);
    }

yep yep yep

#

that works

#

Kind of annoying tho

#

that you have to create such method yourself

rotund token
#

that's what i'm trying to tell you @rustic rain , you don't have to. You can use LinkedEntityGroup to do it for you

#

by default unity will setup LinkedEntityGroup for you if you do conversion

#

and if you destroy the parent all the children will be destroyed

#

there's also EntityManager.SetEnabled(entity, enabled) methods etc that will enable/disable an entity but also all entities in the LinkedEntityGroup

rustic rain
#

I'm doing it inside job

rotund token
#

call ECB.Destroy(entity)

rustic rain
#
        Entities.WithAll<Interactable>().WithReadOnly(children).ForEach((Entity entity, int entityInQueryIndex, in Translation translation) =>
        {
            if (translation.Value.x < -60f)
            {
                DestroyEntityRecursively(buffer, entityInQueryIndex, children, entity);
            }
        }).ScheduleParallel();
rotund token
#

and it will destroy everything

rustic rain
#

nah, it doesn't

#

buffer.DestroyEntity(entityInQueryIndex, mainEntity);

rotund token
#

did you setup a LinkedEntityGroup?

rustic rain
#

that's what I did in the first place

rotund token
#

if you go into EntityComponentStore.DestroyEntities you can see it in action

#
            ref UnsafeList entitiesList, ref int minBufferLength, ref int maxBufferLength)
        {
            int indexInArchetype = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, m_LinkedGroupType);
            if (indexInArchetype != -1)
            {
                var baseHeader = ChunkDataUtility.GetComponentDataWithTypeRO(chunk, indexInChunk, m_LinkedGroupType);
                var stride = chunk->Archetype->SizeOfs[indexInArchetype];
                for (int i = 0; i != batchCount; i++)
                {
                    var header = (BufferHeader*)(baseHeader + stride * i);

                    var entityGroupCount = header->Length - 1;
                    if (entityGroupCount <= 0)
                        continue;

                    var entityGroupArray = (Entity*)BufferHeader.GetElementPointer(header) + 1;

                    if (entitiesList.Capacity == 0)
                        entitiesList.SetCapacity<Entity>(inputDestroyCount * entityGroupCount /*, Allocator.TempJob*/);
                    entitiesList.AddRange<Entity>(entityGroupArray, entityGroupCount /*, Allocator.TempJob*/);

                    minBufferLength = math.min(minBufferLength, entityGroupCount);
                    maxBufferLength = math.max(maxBufferLength, entityGroupCount);
                }
            }
        }```
rustic rain
#

eh

#

I think I'll go with my way

#

Child component is automatically added

#

no need to setup anything

devout prairie
# candid epoch how are you guess handling static values that you use in bursted jobs? do you mo...

If i understand you correctly.. basically any values you pass into a job are ( as i understand it ) copied into the job so to speak.. ie you don't want the job to have to reach out and grab some value from elsewhere in order to use it, so it works with a local copy of it.. so for example in a system OnUpdate, if you are passing a static value or one of the systems field values into a ForEach, you have to create a local copy of that value and pass it into the ForEach.. i think it's the same idea with custom jobs

pastel field
#

I come to ECS only because I'm motivated by Havok and it's a very bad entry point 🥶

rustic rain
pastel field
#

It doesn't seem to take into account the Wrap mode...

rustic rain
#

native arrays for example

#

or component data structs

worn valley
rustic rain
#

relax guys, it's not actual copying kek

#

from what I'v seen ReadOnly still passes data as reference, just forces you out from modifications during compilation

tepid abyss
#

Is the packages in my project not debugable (specifically, the Hybrid Renderer package)? I am trying to set a breakpoint at some method but it doesn't seem to break

rustic rain
#

make sure Burst is disabled

tepid abyss
#

Ok, I'll try that

#

Doesn't seem to make a difference

#

Umm, I get a "Didn't find loaded method for..." error

candid epoch
# devout prairie If i understand you correctly.. basically any values you pass into a job are ( ...

this is true but afaik only for "non static readonly" values.
i hope this example system illustrates what i mean:

  public class TestSystem : SystemBase
  {
    private float3 notStaticReadonlyFloat;
    private static readonly float3 staticReadonlyFloat;

    protected override void OnUpdate()
    {
      Entities.ForEach
      (
        (in LocalToWorld localToWorld) =>
        {
          // this works without binding to a local variable
          var otherNewValue = new float3(1) + staticReadonlyFloat;
          
          // this doesn't not work without binding to a local variable
          var newValue = new float3(1) + notStaticReadonlyFloat;
        }
      ).Schedule();
    }
  }

my question is if burst inlines the "staticReadonlyFloat" field to ensure there will be less cache misses. i've seen a data oriented programming talk where they talked about the issues that some compilers "lump" static data together, which can result in cache misses and false sharing. was wondering if this is an issue for burst as well.

rustic rain
#

you must copy your static fields to local

#

burst doesn't work with static fields

devout prairie
# rustic rain not really, jobs do work with references too

Yeah i think i've possibly come at this question from the wrong angle. Definitely you don't want to be accessing managed memory inside jobs and as i say ForEach requires a local scope level variable to be passed in ( can't pass in a system field for example, it has to be assigned to a local var ).. Tbh i'd like to know more of the details under the hood of this also 🙂

rustic rain
#

that's how it's intended

#

from what I'v seen, unity did magic with pointers and unsafe operations

candid epoch
rustic rain
#

I doubt you'd be passed a local copy

#

in every job

#

that would cause GC to just kill itself

#

and all perfomance would be wasted

devout prairie
rustic rain
#

after all static readonly fields are assigned before .NET runs at all

candid epoch
#

i mean this is not actually an issue of "it does not work". just wondering if i get a performance hit from moving this to a static readonly field. as i understand this highly depends on how burst compiles this. if it moves it somewhere far away from the orgininal code, this could be a performance hit, if it just inlines the static readonly field it wouln't make a difference

rustic rain
#

uuugh, I wouldn't worry about it too much

devout prairie
#

i think where and how it's stored when the job retrieves it is really the issue.. so for example if you have a value in managed, it's going to take longer for the job to pull it out and use it.. i do wonder if the dots system basically takes all native statics when it initially runs and puts them together into fast pools of native memory, which can then be accessed quickly by jobs alongside the other data they are grabbing from the native memory space..

#

would be an interesting one to test though, run a million jobs using a large static value and compare with a non static version

devout prairie
candid epoch
#

if it inlines a static readonly struct field it would recreated the struct every time the code runs

devout prairie
#

mm

#

there's a couple of people on here that could probs answer this properly i think

#

@rotund token @robust scaffold sorry for the ping 😛

candid epoch
#

i think inlining would probably be better for stuff that needs to run fast because there is no need to lookup the struct value (which would probably be a cache miss) from somewhere else, but that's just an educated guess

devout prairie
#

I think KornFlaks could probs answer this as he does a lot of custom vectorization and looking at the compiled jobs etc

#

Maybe out of timezone atm though, not sure

candid epoch
#

no hurry was just wondering how it works 🙂

devout prairie
#

Yeah it's interesting, kinda prompts me to think more about how it's working under the hood, it's easy to just barge on making a bunch of assumptions about what happens underneath

#

Definitely worth doing a little test tho, million jobs doing it in two different ways

robust scaffold
devout prairie
robust scaffold
#

Creates, I assume, a native array copy of the managed array at compile time that is passed between main thread and job thread when needed.

#

Only one creation occurs. And then that "proper" native array is used repeatedly until that system falls out of scope and is destroyed, if it ever is.

#

When compile-time evaluation fails Burst will try to fall back to compiling all static initialization code into an initialization function to be called once at runtime. This means that if code fails compile time evaluation it needs to be Burst compatible, otherwise compilation will fail

#

Burst compatible which means blittable values. Which means native arrays backing. I dont have much experience with static readonly fields on practice though so I cant tell you how itll look in the Burst inspector.

devout prairie
#

Interesting i've never read the burst docs! So i was kinda sorta thinking in the right direction..

#

I knew you'd have a better understanding of this 🙂

#

@candid epoch

candid epoch
#

thanks for the link. very interesting stuff. will dig into it a little further on the weekend. so it will definitely evaluate it once at compile time. only thing i'll need to figure out is if burst compiles this as a "pass by reference" or "pass by value".

robust scaffold
candid epoch
worn valley
#

How does it pass native arrays in? Does it pass the pointer into the burst job then?

candid epoch
#

my guess would be yes. you can treat a pointer as the start of an array and if you know it's length and the datatype you can easily calculate the end pointer and the step size.

devout prairie
rustic rain
#

but native containers are managed type

deft stump
#

they're not managed by C#'s GC

broken siren
#

Hey guys a quick question please, I just want to know if I can renew my Unity Personal License (which is free by default) after it expires. Or do I have to purchase the next license ?

robust scaffold
robust scaffold
robust scaffold
#

private static readonly byte[] Zeroed = {(byte) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

#

So it appears that for a compile time readonly array, what Burst does is just directly copy the value of that array into the bursted function and then sees if it can optimize the method. In this case, it recognized that it is setting sourcePtr values with Zeroed and just mem-set the destination array with the constant Zeroed array.

robust scaffold
#

In the case of a static constructor, it once again recognizes that it is a constant byte array and optimizes the values to a mem-set

robust scaffold
#

And yea, static constructors can not accept parameters. So there is no dynamic setting of static readonly variables.

#

So basically it's like writing a constant value. There is no issue on whether or not the static readonly variable is located inside or outside the cache because the constant value will be optimized away (by embedding the value into the code itself) at compile time.

#

So final answer, yes a static readonly value is located "inside" the cache.

devout prairie
#

Interesting stuff Kornflaks, so A) it is copied, and B) it is basically what he was asking, kinda inlined into the job

robust scaffold
candid epoch
#

@robust scaffold thanks for looking it up. good to know that burst pretty much exactly optimizes it the way i would expect it to after watching the data oriented programming talk. And even better that i don't have to be concerned about a performance hit when moving static values to static readonly fields.

cunning perch
#

What's the most recent tutorial or guide for setuping up a DOTs project?

karmic basin
#

Check pinned messages

#

Yes, even 1 year old resources still applies :)

#

We are expecting a new release this quarter

#

Maybe it will break everything, maybe it will come with updated docs... we dont know

cunning perch
#

0.5 right? I figure I’d just learn the current version. The knowledge should mostly translate 🙏

karmic basin
#

0.50 yeah

cunning perch
#

Transfer I mean

karmic basin
#

Yes I would do the same

#

There's a forum post were they answered a little bit about what to expect

lusty otter
#

Any way to use Time.realTimeSinceStartup or other timing mechanism in a Bursted job?

#

I have a very expensive loop that I'd like to exit out early if it exceeds for example 10 ms, so to not kill FPS.

deft stump
#

put it in a variable and pass it in

lusty otter
#

I mean I need to access the time during the execution of the job, not before it starts.

coarse turtle
lusty otter
#

😅

#

Sounds a bit complicated for such a seemingly trivial need.

coarse turtle
#

wonder if c# datetime works in a job 🤔

lusty otter
#
Burst error BC1045: Struct `System.DateTime` with auto layout is not supported
devout prairie
#

in Burst, you measure time by the distance between atoms 😮

lusty otter
#

I feel like I can't be the only one that have tried to do something like this

#

Time slicing a long algorithm into multiple frames, except in a Bursted job.

devout prairie
#

yeah i wonder, you'd think there'd be some way

lusty otter
#

I suppose I can fall back to collecting some performance information on low end mobile phones, and see how many loops they can run on average, then split it at that.

#

It will mean for high end phones it will take longer to complete (or I guess I could adjust the loop depending on the speed of first execution)

#

But that's just so unnecessarily complicated, when I feel like this should've been a trivial task.

devout prairie
#

i wonder if there's some hack, for example have another job or code running on main thread which writes to a timer value, and the bursted job kinda unsafely reads from that or something

lusty otter
#

That wouldn't work on single threaded devices, no?

devout prairie
#

mm doesn't seem like it'd apply there no

#

hmm how about have a shared component which is given the time each frame, and also pass that into the job

pliant pike
#

why do you need to access the time during a job 😕

#

only way to do that is WithoutBurst.().Run()

lusty otter
#

I want to run an algorithm on a huge amount of items, each takes variable and undetermined amount of time
I just want to terminate the execution after 10 ms for example and continue in the next frame, so it won't tank the frame rate.

pliant pike
#

in a proper bursted job time doesn't exist, its completely isolated from the outside data

#

you'd have to exit early in some manner or run the job for a certain amount of update cycles from the outside

lusty otter
#

Well I don't think it's too crazy to ask for obtaining time inside a Bursted job

pliant pike
#

it kind of is crazy though

lusty otter
#

I mean I could just call a native API like others have suggested.

pliant pike
#

jobs are designed as completely isolated systems that run on the data you give them as efficiently as possible

#

you can't do that if they have to wait a ton of time to get data from ram

lusty otter
#

I don't really care about the design, for example if you give me a huge file to hash it while keeping the game loop alive, I'll need that.

#

It's not a ridiculous use case that I'm asking for.

devout prairie
#

ah i can see the problem i think now that i think about it.. so you're essentially locked into a bursted job in the main thread in a single threaded environment, burst obviously does not want to reach out into memory to grab an updated time value as this breaks the whole burst execution

#

maybe a solution would be to parse files externally or run a job at some other point which analyses the 'source file' and determines a good scheduling routine / chunk count etc

pliant pike
#

yeah that's why you have to set up the data in specific ways, make sure its local to the update and whether it's read or write etc, its also the same with schedule() and scheduleparralell()

devout prairie
#

yep

pliant pike
#

you could put early out code like I said, import an int iterator that counts the number of cycles, if you know roughly how long it takes to calculate one cycle then you can have exit when the iterator equals however long want

#

that would only work in a single threaded job though, you'd have to create multiple counters and pass them into a multithreaded job

lusty otter
#

The best way is to have a lowball estimate on how many cycles it can safely do in 10 ms even for bad devices, exit out the job and use the elapsed time to adjust how many cycles for next frame

#

Here's my situation:
I currently have a 2 second fade into black screen, and then do this expensive Bursted job here which can take some time (but it's hidden well because of the black screen), and then fade out into gameplay.
On low end devices the pause can still be felt, hence I'm thinking to move some of the workload across the 2 seconds of fade in frames to improve UX.

#

But like if this is going to be the cost then I'm just not going to bother, it's so much work for arguable amount of benefit when user can tolerate a bit of loading

#

I'm just thinking if this wasn't done in Burst, this would take a few lines of code at most.

pliant pike
#

yeah figuring out how to use burst and jobs demands a lot more time and knowledge

lusty otter
#

I mean this has nothing to do with Burst really, it's just straight up not supported use case.

pliant pike
#

yeah people have been asking to do things similar to what your asking since the beginning of dots

devout prairie
lusty otter
#

That's fair.

#

The "transform your code so that it operates on isolated local data" part of Burst I would agree, but this is simply just "I can't call a function which is quite literally a native API on any operating system that has nothing to do with Unity at all"

devout prairie
#

I've saw people post things in here they said took 100 seconds and reduced to 3/4 seconds with burst.. so i guess it's kinda trying to find a way to still get all that benefit, without breaking the paradigm that gives the whole benefit

lusty otter
#

Don't get me wrong I love Burst and my game wouldn't be possible without it, but this is about the only time I couldn't get it to work and it's completely out of my control so it's a bit frustrating.

pliant pike
#

oh I know what you mean, it is really frustrating figuring out the limits and what you can and can't do but when you do figure out something that runs way more efficiently than you could do any other way it's great

#

like there's no way I could figure out how to build code that works multithreaded and as efficiently as it does here on any other engine or from scratch

lusty otter
#

I'm just going to hold it off til later

#

Also the "do some amount of work in Burst then measure outside to then adjust for the amount of work on next frame" solution relies on two assumptions: 1) you are able to split the work into equal units to adjust and 2) the overhead of starting a Bursted job is negligible.

#

I don't know about 2), but 1) seems a bit sketchy for my situation.

worn valley
#

Anyone have good articles on how NativeSlice<T> works. I don't understand what happens with it and I haven't been able to figure out a use case from the documentation

rustic rain
#

I don't really see why you want to get that value inside bursted job, not when you just setup that job

rustic rain
#

it's all going to run in merely same ms anyway

#

hm

#

so basically you want some async operation

#

well, I'm not even sure if you can stop job execution at all

lusty otter
#

The job can stop itself

#

If it can obtain the current time, it can simply check how long has elapsed and stop the loop.

rustic rain
#

seems like a bad design in the first place tho

lusty otter
#

This is not some out of the world idea, it's a pretty common practice to split a huge chunk of work across multiple frames.

rustic rain
#

I get the thing, I'm just not sure if jobs are intended for that usage at all

#

it will affect framerate no matter what tho

#

even if you somehow manage to stop it after 10ms, it's 10ms passed already

#

I think you can do it by forcing job to complete yourself

#

but instead of using whatever method that simply awaits for it to finish

#

you'll just check on it in while loop

lusty otter
#

The loop is inside the job, not outside

rustic rain
#

once it reaches treshold you cancel it, assuming you can do it outside of job

#

you can't access anything of outside world from job tho

#

only locals

lusty otter
#

You could say that, but nothing is stopping me from directly calling an OS level native API to fetch the current time.

rustic rain
#

well, then you'll have to run job without burst and in main thread

#

otherwise it just won't compile

pliant pike
#

the unity api is stopping you from doing that though 😕

lusty otter
#

You could call native code, no?

rustic rain
#

you can't call nothing but whatever api burst supports

lusty otter
#

But regardless, what I'm trying to say is, this is not something that's fundamentally undoable, it's just a design choice.

rustic rain
#

burst has very limited api, that's why it's so fast

lusty otter
#

I could just go and modify the compiled assembly and add that in.

rustic rain
#

well, are you willing to dig that hard into compiler code?

#

meanwhle, are you certain that won't make burst worse for everything else?

lusty otter
#

Nope, because I would just "rewrite it in Rust"

rustic rain
#

kek

#

that's the other solution

#

but overall I think you're just trying to apply techniques from different programming approach to DOTS

#

which might be not smth actually intended

lusty otter
#

Burst isn't DOTS specific even though it's primarily used by DOTS.

rustic rain
#

hmm

lusty otter
#

Well, I suppose at least for me I use it to speed up portions of my code where it makes sense to

rustic rain
#

if your code is just really expensive to run by it's own

#

maybe you might try simply making function pointers of bursted jobs

#

bursted functions*

lusty otter
#

Most of the things Burst doesn't support are directly because of multithreading, getting the current time from OS isn't really a problem.

#

At least in my head it works like that, and I think it's a common enough thing that there's not really a good reason why it can't be done.

#

Alternatively, has anyone measured the overhead of starting a Bursted job with .Run()?

rustic rain
#

well, considering even exceptions aren't really supported in burst I wouldn't be too sure

#

.Run is just doing code here right now

lusty otter
#

If it's negligible, I could just pull the while loop outside and measure time elapsed on each loop.

rustic rain
#

it won't be threaded

#

it'll run on mainthread

#

if that's what you are looking for

lusty otter
#

Right, but there could still be overhead.

rustic rain
#

there's a lot, but burst eats that

#

and still manages to bring more profit

#

but

#

really depends on your code

#

not everything can be vectorized

#

and this is where burst shines

#

I did test some really simple code of doing some transform changes

#

with and without burst

#

so far

#

invoking function pointer is about 10 times more expensive than doing some really simple and cheap math

#

jobs will probably have even more overhead

#

but you profit by putting them on other threads, keeping main thread mostly for scheduling or limited stuff

#

here that comparison

#
    private static float3 NewPos(float3 curPos, float speed, float offset, float delta)
    {
        curPos.x -= speed * delta;
        if (offset * -1.5f > curPos.x)
        {
            curPos += offset * 3f;
        }
        return curPos;
    }

and here the code I compared

worn valley
#

Jobs are supposed to be put info in, get info out another time. Trying to modify them to cancel just seems like it's outside the scope. If you are trying to get information from the OS, what other things could you potentially grab from other places. Kind of defeats the purpose of creating a job.

lusty otter
#

It's not outside telling to job to cancel, job cancels itself once certain amount of time has passed.

worn valley
#

fetching any information from outside of the job's little bubble that can change is not really what the jobs system is designed to do. I am sure you can hack it to do that, but Unity probably wants to keep the use cases simple

#

You just shouldn't grab any information after you schedule the job. I think jobs are much more like functional programming than other types. Inputs -> black box -> outputs

lusty otter
#

Technically you could have the job run on a second thread and repeatedly check a flag which the main thread writes to when the time is up.

#
private void BenchInside() {
    var job = new LoopInsideJob();
    job.Run();

    var startTime = Time.realtimeSinceStartup;
    job.Run();
    var endTime = Time.realtimeSinceStartup;
    Debug.Log($"Inside: {endTime - startTime} seconds");
    // Inside: 5.722046E-06 seconds
}

[BurstCompile]
private struct LoopInsideJob : IJob {
    public void Execute() {
        for (var j = 0; j < 1000000; j++) {
            var v = 670617279;
            for (var i = 0; i < 1000000; i++) {
                v = v % 2 == 0 ? v / 2 : v * 3 + 1;
            }
        }
    }
}

private void BenchOutside() {
    var job = new LoopOutsideJob();
    job.Run();

    var startTime = Time.realtimeSinceStartup;
    for (var j = 0; j < 1000000; j++) {
        job.Run();
    }
    var endTime = Time.realtimeSinceStartup;
    Debug.Log($"Outside: {endTime - startTime} seconds");
    // Outside: 0.6792498 seconds
}

[BurstCompile]
private struct LoopOutsideJob : IJob {
    public void Execute() {
        var v = 670617279;
        for (var i = 0; i < 1000000; i++) {
            v = v % 2 == 0 ? v / 2 : v * 3 + 1;
        }
    }
}

So the overhead of a job is big enough that I can't pull the loop outside.

#

I'm up for suggestions but tbh I think I'm just going to give up at this point

#

I thought this problem would take a few lines at most but apparently not, I'll just have slightly worse UX instead.

rustic rain
#

if the only reason your job takes 10+ ms to run is just that because you too many individual items

#

that can be easily threaded

#

you might want to consider compute shader

#

gpu likes that kind of stuff

#

and it'll probably take WAY less time to compute

worn valley
#

Why don't you record how fast it takes the first time the user does the code on their device and then store that in their player prefs. It would only ever happen once for a player on any device. You could also collect that data and then update a list for future builds depending on phone type.

rustic rain
#

what is intended way for unity to setup dependencies between jobs inside your own project?

#

do you just expose Dependency or Job Handles

#

in public properties?

lusty otter
lusty otter
rustic rain
#

I'm not even sure if you'll profit from jobs or bust then

lusty otter
#

It does, by a huge amount.

#

Vectorization isn’t the only thing Burst offers, just less junk in general comparing to normal build.

#

IL2Cpp generates a lot of junk mainly due to metadata stuffs.

rustic rain
#

I see

#

well, I don't see any other solutions to you rather than either rework your items or accept job limitations
Either way compromises

rustic rain
#

I need help with this system I'm trying to develop

#

basically

#

I have interactable collisions

#

and what I want is to have some sort of tag that will contain info about what collision type I'll use

#

so in my collision resolver I simply put tag that this item wants to get his special collision event

#

and then my for each unique collision type system does unique collision stuff on all items

#

I'm not sure how to resolve this kind of stuff

#

since you can't keep Type in component

#

Any ideas how to that can be done?

robust scaffold
rustic rain
#

I don't want to be hardcoded to enum

#

since I might want to add A LOT of other interactions

#

and every time I'll have to adjust enum which is uuggh

#

and then I'll have to run huge switch on that enum

#

not good

robust scaffold
#

What is Type? Is there an integer component? Is that literally System.Type?

rustic rain
#

In perfect world I'd simply contain Type in my Collidable component which will be added during collision

#

wait a second

#

I think I got it

#

I'll have universal Tag

#

smth like

#

WantCollisionTag

#

WantCollisionEffectTag

#

yeah

#

and then I'll have query that will run only with that tag

robust scaffold
#

Uhh, to be honest. In my experience, ya dont want to add and remove components on a regular basis.

rustic rain
#

and each system will have it's own resolver

#

well

#

you can't really avoid that

#

that's core stuff

#

besides

#

my collisions are basically a goal of game

#

and they don't really happen a lot

#

it's only player that collides

#

and he does it like once per second

#

on average

robust scaffold
#

Alright then. I dont quite have the context here to suggest anything so good luck.

rustic rain
#

Is there a fast way to simply destroy every single component type on all entities?

#

basically I have components that only exist for 1 frame and I need to flush them all at once

#
    protected override void OnUpdate()
    {
        EntityManager.RemoveComponent<CollisionHappenedTag>();
    }

I need smth like this xD

gilded glacier
#

from what I know (although not sure whether correctly), singleton entities are internally handled the same as other entities, that is they have their own chunk

#

I think

rustic rain
#

no no no

#

I mea

#

I can have a lot of entities

#

with that tag

#

I want to remove them all

gilded glacier
#

no, I'm just talking my issue here

rustic rain
#

I want that tag to cease to exist in current world

#

ah

gilded glacier
#

nothing with yours

#

if singletons are actually saved in their own chunks of their type, isn't there a big waste of memory space by having a single entities in a chunk ?

#

and is the use of singleton entities any beneficial (other than the require for update with systems) ?

rustic rain
#

it somewhat is, I remember some custom dots framework adressed it

#

but I'm not sure how whether it's worth to look into at current state

#

since it all might change in 0.5

rustic rain
#

so it can still run through queries

#

bursted

#

and paralleled

#

unlike static fields

#

which will be forced into your main thread

#

unless ofc you make Job.WithCode

rustic rain
#

when you schedule some job with Schedule() will that job run on worker threads or?

#

I'm guessing it will run on first possible worker thread

#

but not splitted into itself through different threads

#

I'm basically trying to understand whether ScheduleParallel makes any sense in super small queries (like 1-2 entities)

rotund token
#

depends more on your workload than your entity count

#

you might only have 2 entities, but if these entities are your AI directors for each team and have to do a bunch of really costly calculations then you probably want them on different threads

#

but if your workload is small, then yeah definitely makes sense to just use Schedule

#

also something people often overlook is that, just because their job isn't running in parallel doesn't mean you're wasting cpu time - other jobs can run at the same time as your job occupying other threads

olive kite
#

Is there any reason why the scale of an entity would reset to 1,1,1 after modifying it and then removing an entity in it? There is an animation I am doing and it does it fine with scaling the entity, but then when it is completed and I remove a flag I'm using to say that it has an animation running it resets the scale back to the original

radiant berry
#

What tutorial is good to make my first simple game with dots like pong for example that is up to date with the 2020 editor version?

robust scaffold
#

Not the best "newbie" tutorial but it is fully up to date with DOTS 0.17 lineup

worn valley
#

That is a good one. Goes through everything

rustic rain
#
        JobHandle = Entities.WithAll<PlayerTag>()
           .ForEach((ref PhysicsColliderBlob collider, in Translation translation, in Rotation rotation) =>
           {
               var colInput = new OverlapColliderInput
               {
                   Collider = collider.Collider,
                   Transform = new PhysicsTransform(translation.Value, rotation.Value),
                   Filter = collider.Collider.Value.Filter
               };
               if (physicsWorld.OverlapCollider(colInput, out OverlapColliderHit hit))
               {
                   beginBuffer.AddComponent<CollisionHappenedTag>(hit.Entity);
                   buffer.RemoveComponent<PhysicsColliderBlob>(hit.Entity);
               }
           }).Schedule(Dependency);

smth is really wrong with this
I can't find what's the problem

#

so far

#

It triggers twice

#

in 2 different frames

#

while it shouldn't

#

since I remove collider component

#

and it works good on everything but one type of entity

#

basically, when it triggers

#

It's supposed to add tag and remove collider

#

that happens

#

BUT, for some reason that tag gets added to some absolutely irrelevant entity

#

0:1

#

index

#

and that ends up breaking game obviously

#

I suspect that's because it triggered twice

#

and there could be some bug that adds CollisionHappenedTag to some random entity

#

I checked with DEBUG which entity is hit.Entity

#

it's always the correct one

#

never entity 0:1

rotund token
rustic rain
#

I don't have fixed update at all

rotund token
#

alternatively, when is the command buffer relative to this update

rustic rain
#

cause 2D physics is outside of it

#

everything is running per frame

#

ok, I think I know what's wrong

#

yeah

#

my pepega brain forgot to mention WithAll

#

in job