#archived-dots

1 messages Β· Page 188 of 1

compact robin
#

ComponentData

#

Each compdata of a player has a native array of size 8

#

Instead of a dynamic buffer

#

I don't need it to be dynamic

#

AFAIK, native array is just a struct that points to unmanaged memory

amber flicker
#

one nativearray of 8 x numb players will be fastest... but.. a dynamic buffer capacity 8 will also be incredibly fast. If you don't exceed the initial capacity, it will all be linear access. Plus there is some code overhead with managing a persistent nativearray, whether you create interdependencies between systems etc.

compact robin
#

Yeah I want the fastest option, since I know it access managed memory

#

When internal buffers are exhausted

#

And I guess internally it does some checks to see if such an access is needed

amber flicker
#

when you say [InitialCapacity(8)] public DynamicBuffer<int> or whatever, you're saying an entity reserves capacity for 8 x int (+2 bytes or something) - it's all linear access and unmanaged. Only when you exceed 8 does it then start managing the data on the heap.

#

There is a good reason to not do the dynamicbuffer route though - that's that the larger your entity, the less you can keep in a chunk/cache while iterating. That's the main reason a persistent nativearray somewhere will win.

compact robin
#

So is it better if I use nativearray

#

With an int

#

As a "ring buffer"

#

And since nativearray is essentially just a struct that points to unmanaged memory ( Correct me if I'm wrong ), its size would be the same, regardless of the nativearray's size, right?

#

And hence you can store the same amount of stuff in a single chunk

amber flicker
#

erm basically.. but in case it's what you're thinking about, it's not supported to e.g. put a NativeArray (or other native container) inside an IComponentData

compact robin
#

Actually, two ints with a native array now that I think about it

#

Oh

#

Damn

#

Why?

#

:c

amber flicker
#

well.. that's what a dynamicbuffer is for - and it's very fast

compact robin
#

But I don't need the dynamic-ness

amber flicker
#

then don't exceed its capacity...

compact robin
#

Hmmm

amber flicker
#

I think you should check some of these assumptions you're making about performance.

compact robin
#

Oh that's why I'm here haha

amber flicker
#

if you want to, you can mess around with unsafe and it is possible to use Native containers with ICDs but I'm very dubious it's worth the headache unless you're iterating millions of them every frame.

compact robin
#

Oh how tho

amber flicker
#

there are a few posts on the forum - give it a google

compact robin
#

Because the thing is, dynamic buffers somehow have to check if its capacity exceeded its internal ones

#

I think

#

Ok I will try thanks

amber flicker
#

I think they would only check when you add to them or otherwise change their size?

compact robin
#

Actually yeah that's a valid point LOL

#

I'm overthinking

amber flicker
#

These are not the places you will have bottlenecks.

compact robin
#

Are those buffers initialized? Or do you have to add stuff before they do

amber flicker
#

I'd guess it will more likely be sync points, scheduling, having to touch managed stuff etc

#

they have a length and a capacity - I don't think it's initialized

compact robin
#

Oof

#

Guess that's why I'm going for nativearray approach

amber flicker
#

It might be though

#

eh?

#

Do a test with dynamicbuffers... find out at what point it's "too slow"

compact robin
#

Can't seem to find any topic about this unfortunately

amber flicker
compact robin
#

I've decided to just stick to dynamic buffers

#

Since apparently a fixed array can't use int3

#

THanks for the help

odd cipher
#

Speaking of DynamicBuffers, I'm trying to get access to them and edit them on a instantiated Entity in a Parallel Job but it doesn't seem to be possible. I tried this:

Entity e = ecb.Instantiate(entityInQueryIndex, entity);
ecb.SetComponent(entityInQueryIndex, e, new CreatureData() { energy = 1 });
ecb.SetComponent(entityInQueryIndex, e, new Translation() { Value = translation.Value + new float3(random.NextFloat(-5f, 5f), 0, random.NextFloat(-5f, 5f)) });

var inputs = GetBuffer<InputNeuronData>(e);
var hidden = GetBuffer<HiddenNeuronData>(e);
var outputs = GetBuffer<OutputNeuronData>(e);
var synapses = GetBuffer<SynapseData>(e);

However this gives a error saying this InvalidOperationException: <>c__DisplayClass_OnUpdate_LambdaJob0.JobData._BufferFromEntity_InputNeuronData_0 is not declared [ReadOnly] in a IJobParallelFor job. The container does not support parallel writing. Please use a more suitable container type.

mint iron
#

can you declare InputNeuronData as ReadOnly? are you tryign to write to the container?

odd cipher
#

Yeah I need to be able to write to it aswell.

mint iron
#

it can still be done, how safe it is to do is another question

#

you could use an IJobChunk, but thats gonna be one thread per chunk.

odd cipher
#

I've never used one of those before.

mint iron
#

might be slightly out of date, havent had time for ECS in a while

#
            var header = *(BufferHeaderProxy**)UnsafeUtility.AddressOf(ref buffer);
            var ptr = BufferHeaderProxy.GetElementPointer(header);
#

then you're just accessing an array var item = ptr[0]

odd cipher
#

Alright I'll take a look later, It's too late over here so tomorrow :p

rare umbra
#

Any good tutorials on DOTS and UI? I’m looking to show an interaction prompt image over an entity when the conditions are valid. I have a system I can trigger this from but on the UI side I’m confused.

Can I just add a sprite to the entity when conditions are valid and remove it again when they’re invalid?

Or other similar component?

frigid onyx
#

I'm sure this question gets asked every other day, but what is the preferred method today of adding a string to a component? Or is it just forbidden, and that's all there is to it? I see references to FixedString and NativeString, but these both look deprecated. I'm not sure BlobString will work for my purposes either.

#

Specifically, when using Netcode, how do I communicate a player's name to another player? Or do I have to roll my own API for that?

karmic basin
#

I have no tuts to recommend on that topic, mainly saw forum threads for that one

rare umbra
#

So I could just use a GO with a child that has a sprite that I enable and disable and the parent would have the entity authoring component as well as the MB?

#

I think I need to look at some hybrid examples

karmic basin
#

Yup

#

It's not well documented yet but you can sure call ECS packages from Monobehaviour

hollow sorrel
#

too long

karmic basin
#

Yeah thanks

#

I hoped with a block :p

#

ANd on the system side, a public class variable or a getter, updated by the system

#

(not tested though)

hollow sorrel
#

@frigid onyx nativestring is the old one but fixedstring is the current way to put strings on components
haven't used netcode so dunno about that specifically
you could also consider storing strings outside components, e.g. a system that holds a list of playernames, and have the components contain an index for this list instead of the full string

frigid onyx
#

Right, the transmission is the difficult part.

#

I'll play with fixedstring and see if Netcode will relay it automagically

#

Thanks for the confirmation, I thought fixedstring was deprecated, I was just looking in the wrong namespace

rare umbra
karmic basin
#

You're welcome, happy coding

odd cipher
#

@mint iron I don't see how a IJobChunk would help.

pliant pike
#

I'm confused do commandbuffers not require m_EndSimulationEcbSystem.AddJobHandleForProducer(this.Dependency); anymore? πŸ˜•

zenith wyvern
#

Yes they do. If you find it working without it it's just a coincidence and you probably have a sync point or structural change between when your job is scheduled and when the command buffer runs

pliant pike
#

yeah I figured, it's weird it works without it

#

I also cannot find AddJobHandleForProducer

#

maybe I'm using a different kind of buffer

zenith wyvern
#

What do you mean you can't find it? Are you getting an error of some kind?

pliant pike
#

no, no errors its just not in the list of methods

zenith wyvern
#

Oh, like your IDE is failing to find it? Whenever stuff like that happens for me I just close visual studio and delete all my vsproject files and the ".vs" folder, it always fixes it.

#

Extremely dumb that I even have to do it, but it works

pliant pike
#

damn yeah I keep getting quite a few bugs with VS lately

safe lintel
#

i quite often have to restart rider and clear its cache too 😩

#

i wonder if these issues come up often in non gaming code stuff

zenith wyvern
#

I didn't even consider that, I just assumed it was some weird interaction between VS and unity

#

Good question

odd cipher
#

Well,, I need some help with finding closest entity from entity again. It's just way too slow with the current method (which is going through every entity for every entity)

hollow sorrel
odd cipher
#

Yeah I know, I've looked at it before but I don't really understand it.

hollow sorrel
#

think of the world being divided into a grid
let's say for example sake each cell is 10x10
if an entity is at position (15, 5) you know it's in cell (1, 0) or an entity at (50, 50) is at cell (4, 4)

#

if you wanna check what other entities are within 10 units you only have to check the entities in the surrounding cells

#

rather than every entity in the world

odd cipher
#

Mhm I get that, It's just the code I don't understand much.

karmic basin
#

Sure there's a lot of boilerplate to make it work with DOTS :/

zenith wyvern
#

It doesn't help that the native multi hash map api issomething that no human should ever have to use

safe lintel
#

nativemultihashmapmergesharedwhatthehellisgoingonhere

odd cipher
#

Yeah..

coarse turtle
#

Could roll your own spatial hash map - take the position hash it store it into a multi valued hash map (hashmap + unsafelist combination)

odd cipher
#

I'm not sure how that would work

coarse turtle
#

you pretty much get a region divided into a grid/cube (depending on the # of axis) and each region stores a certain # of entities

#

so you wouldnt need to iterate through every single entity to determine which is closest

#

you would just need to search in the region

odd cipher
#

Ahh, I'll try it and see if I can get something like that working.

karmic basin
#

@odd cipher That's always the same idea. Be it called a quadrant, an octree, a grid, or the native multi hashmaps of the Boids demo...

odd cipher
#

Mhm alright

zenith wyvern
#

Google spatial hashing, there's plenty of material online you could build from

gleaming plank
#

Chapter 7 of the book Real-Time Collision Detection has more details on these methods.

gleaming plank
#

Actually, if it's just finding the closest entity within a certain radius, couldn't you just use the UnityPhysics package and do like a PhysicsCollider distance query?

stone osprey
#

To obtain the "forward" vector of a transform we do "this.rotation * Vector3.forward"... im using "quaternion" instead of "Quaternion"... and i can multiply that one with a vector3, it says this operation is not supported. So how can i calculate the forward vector in another way ?

odd cipher
#

@gleaming plank I tried doing that but it never worked

stone osprey
#

Oh and is there any advantage using "float3" over "Vector3" for dots ?

odd ridge
#

@stone osprey vector3 is not dots

stone osprey
#

Yeah i know ^^ but its also a struct storing x,y,z

gleaming plank
#

the BurstCompiler only recognizes the Unity.Mathematics primitives

stone osprey
#

That means float3 is more performant than using unity-s standard vector3 ?

gleaming plank
#

Yeah, you should use float3 if you're hoping to see SIMD speed-ups from Burst. You can pun/reinterpret Vector3 as float3

stone osprey
#

Ok, thats great... but i saw that its missing a lot of functions... for example Vector3.RotateTowards(...) is not implemented for float3

gleaming plank
#

I think you're going to have to re-implement those functions (unless somebody's made an asset)

stone osprey
#

Ok thanks ^^ could anyone here provide a simple example of how we rotate a dots entity ? The new math api is strange... rotate returns float3 instead of another quaternion

stone osprey
#

Thanks ! Looks a bit... more clunky than the average unity vector3/Quaternion rotation code... hopefully they'll compress this in the future

odd ridge
#

@zenith wyvern is that .ScheduleParallel required? I think it's parallel by default now right?

zenith wyvern
#

No. It used to be that schedule was parallel, but they reversed it after they got rid of IJobParallelFor

#

Now schedule runs in a single thread

odd ridge
#

and there's no ScheduleParallel anymore?

zenith wyvern
#

Yes there is, like in the code I linked above

#

If you want to force your job to run in a single thread you use Schedule. For parallel you use ScheduleParallel

#

When I said they reversed I meant that they used to have "Schedule" (parallel) vs "ScheduleSingle". Now it's "Schedule" vs "ScheduleParallel"

odd ridge
#

ah okay

zenith wyvern
#

Try messing with the boids sample and you'll see

compact robin
#

I still don't get why xd

zenith wyvern
#

Because it's awkward to add elements and to access the elements of a key.

compact robin
#

Hmmm but I use it when I want to group stuff based on Entity

zenith wyvern
#

I didn't say it doesn't work, I said the api is bad

compact robin
#

Like in terms of usability or speed?

#

That's what I care about lol

zenith wyvern
#

Usability. Although in a lot of cases you can get way better performance if you can use NativeStream instead. Just depends if your problem fits

compact robin
#

I need access via keys, in my case Entities

#

Like to access data specific to an Entity inside Entities.ForEach()

craggy orbit
#

does "Override Property Declaration" replace "Hybrid Instanced (Experimental)" in Shader Graph?

#

ah nvm

#

yes it does

dusty sleet
#

Is it possible to change an variable's value in one element of DynamicBuffer throught EntityCommandBuffer?

#

the three buffer related functions of ECB seems neither works this way.

safe pulsar
#

When I ToComponentDataArray<Translation> and set the values and afterwards copy the values via CopyFromComponentDataArray the entities doesnt render in their new position?

#

I can see the values of the translation value change in the entity debugger, but the hybrid renderer doesnt render the entities in the new position.

#

If I set them via a Entities.Foreach it renders correctly. I don't get it

rocky thorn
#

Is it possible to figure out when a Scene is ready to go after loading it with SceneSystem.LoadSceneAsync with the LoadParameter flag DisableAutoLoad?

I want to be able to control a transition between scenes when an event happens and the async loading/streaming progress is done to have the experience be as smooth as possible.

#

Also, when I want this transition to happen I call SceneSystem.LoadSceneAsync again on the same GUID with flag LoadAdditive, it seems to do the trick but is there a better method to push the scene that was set to DisableAutoLoad to then load?

pulsar jay
#

As command buffers can only be used in a job and the EntityManager cannot be used in ForEach what am I supposed to use for structural changes in a main thread ForEach?

zenith wyvern
#

Command buffers can be used on the main thread. And EntityManager can be used in ForEach as long as it's used .WithoutBurst() and .Run()

safe lintel
#

also WithStructuralChanges() if you are changing stuff

zenith wyvern
#

Actually if you're doing strucutral changes you need WithStructuralChanges()

odd cipher
fringe sinew
#

How does Unity's ECS determine if a system needs to be called or not?

#

Systems don't provide any info about which set of archetypes they need to iterate over. Most I saw is that they store created archetypes locally to later query with them, but those are private variables

hollow sorrel
#

@fringe sinew if you use Entities.ForEach unity codegen creates an entityquery for it
in systembase update() it checks if its queries have entities and if at least 1 query has at least 1 entity it will run OnUpdate()

karmic basin
#

@hollow sorrel That is for the default world I assume ?

#

Ssytems from other worlds wont load automagically ?

hollow sorrel
#

no it's world independent

#

systems from any world will use that to check if they should run

karmic basin
#

alright nice

fringe sinew
#

But how? The queries are stored locally. How does a system knows if it should call it?

#

Like, hold on, gimme a moment

hollow sorrel
#

it all happens in the systembase itself

#

world calls system.update() (unity code) -> system checks if its entityqueries have entities -> system calls system.OnUpdate() (user code)

fringe sinew
#

But I don't pass anything into sysytembase. I store the queries locally. It shouldn't even know anything about my systems. So how does it?

#

How can it check the queries if it doesn't see them?

#

I'm opening the project, I'll illustrate it to you rn

karmic basin
#

Unity ECS automatically discovers system classes in your project and instantiates them at runtime

#

And it puts them in a group

#

the simulation one by default if I remember well

fringe sinew
#

Yes, I know. That's not the topic of the discussion.

karmic basin
#

It shouldn't even know anything about my systems
Sorry I didnt understood well then.

#

my bad

fringe sinew
#

...takes awfully long to open it

#

Okay, this. The system has an EntityQuery as a private field. It's created in OnCreate.

#

And I found the answer. It adds the copy of the query to an internal systemstate upon creation.

karmic basin
#

Yeah, Scorr told you in which order it's discovered

fringe sinew
#

I wanted to know how exactly.

#

"system checks if its entityqueries have entities"

#

"How exactly?" was my question.

zenith wyvern
#

Yes, by default it adds any queries from the system to a list and checks those, including ForEach queries

#

You can override that behaviour with RequireForUpdate/RequireSingletonForUpdate

fringe sinew
#

Sounds like an easy recipe for disaster if one were to create queries in OnUpdate. Guess the api is not verbose enough?

zenith wyvern
#

As far as I know GetEntityQuery tries to be smart about it and will cache queries if possible. But yeah generally you should be creating your queries in OnCreate and storing them in the system

#

I'm not sure but I assume they do something like that during codegen for ForEachs

karmic basin
#

They say so in the docs but I'm not sure if they mean when you use WithStoreEntityQueryInField or always

hollow sorrel
#

yeah it always gets cached with entities.foreach

#

creating entityqueries has some overhead so you don't wanna be doing it in onupdate

safe lintel
#

whats your usecase for creating queries in onupdate?

odd ridge
#

I'm trying to figure out how to group my entities

#

the context is a RTS with a lot of entities

#

for example, if I press Ctrl+1, I will group all the entities I have selected in Group 1

#

I only see 2 possible solutions, first is to have a native array of entities, and iterate this array when I have to process only this group

#

second is to have a Group1 tag, so I can only process this group by querying <Group1>

zenith wyvern
#

Just use tag components. It should always be the goto unless you have performance concerns.

odd ridge
#

what do you mean unless I have performance concerns? is it slow to group by tag components?

karmic basin
#

Each time you'll move groups, it will move entities to other chunks

zenith wyvern
#

It causes structural changes, which can be slow if you're doing it a lot - like many many times per frame. For something related to user input it should be fine.

odd ridge
#

do you think I will see a speedup with structural changes in release build?

#

I have hickups in my game and I realize this is probably because of structural changes happening

zenith wyvern
#

Don't make any assumptions. Profile it.

odd ridge
#

can I see structural changes happening in the profiler?

zenith wyvern
#

Yes, it will force all your jobs to complete

#

If you're using ECBs then it should show them as taking up the time. If that's what's slowing you down. Which again, who knows until you profile it

pulsar jay
#

@safe lintel @zenith wyvern sry got distracted. This seems to be the missing piece. Is this also necessary with command buffer?

zenith wyvern
#

Sorry, is what neccessary?

pulsar jay
#

WithStructuralChanges()

safe lintel
#

no

zenith wyvern
#

No, command buffers will work in burst. That's their whole purpose, they defer structural changes to later in the frame or the next frame

pulsar jay
#

yeah just wasnt sure if it was recommended to use WithStructuralChanges() still

zenith wyvern
#

That disables burst so no, if you can avoid it you should

pulsar jay
#

I see thx

odd ridge
#

yes I'm using ECB

odd cipher
odd ridge
#

is it regular practice to create a new ECB for very job?

tawdry tree
#

You mean using ecbSystem.CreateCommandBuffer().ToConcurrent(); (with or without concurrent) in OnUpdate?

odd ridge
#

@tawdry tree yes. although I'm doing .AsParallelWriter(), because the docs does it like that

tawdry tree
#

@odd ridge I think you pretty much need to create it in OnUpdate, and even the docs do it, so it shouldn't be bad practice at least. Assuming the docs are not way old and un-updated

odd ridge
#

when should I use or not use .AsParallelWriter()?

coarse turtle
#

Well if you aren't using multiple threads to write then you wouldnt use asparallelwriter

pulsar salmon
#

Is there a way to asynchronously update a texture from the CPU using a job? Updating a texture blocks for a long time and I would rather not do that on the main thread because I need to do it lots of times every frame.

zenith wyvern
pulsar salmon
#

The problem isn't the generation of the pixels, that is very fast. Texture2D.Apply actually writes the data to the GPU, and takes a few milliseconds! Unfortunately, this cannot be done in a job.

#

Is there a function to batch the Apply method on a collection of textures?

half jay
#

Does EntityManager.RemoveComponent<T> check if components exists ? Or it should be done manually?

karmic basin
compact robin
#

Is it possible to do Entities.ForEach on another world?

odd cipher
karmic basin
#

Wait with the code inside the system ? That's great.
Then you would have to Raycast in the physics world, against the ground if you want to follow the mouse hover

odd cipher
#

Yeah the Debug stuff works but doesn't seem to show the correct information. A raycast could probably work but I've had some problems with doing that as well. Not sure how to do it :/

karmic basin
#

You're using Camera.ScreenPointToRay with mouse input right ?

#

RaycastInput.Start is Ray.origin, RaycastInput.End is Ray.GetPoint()

#

then you can read the RaycastHit.Position

odd cipher
#

Alright I'll give it a shot

karmic basin
#

cool

#

I think that's enough, then of course you feed the position to your quadrant system

#

quadrant-debugger-method * I meant

#

Actually, if it works when you move the camera, that should enough to help you debug, no ?

odd cipher
#

Yes, it would. But it doesn't work. It doesn't say the correct amount of 'food' entities in the quad.

pulsar jay
#

Unity seemingly just failed to "Import" the authoring components on my prefabs. All the values were set to default values. A reimport of the prefabs fixed the issue. Did anybody ever had this happening? Is this a Unity bug?

odd cipher
#

@karmic basin The raycast mostly works but it refuses to go to the corner for some reason. Not sure if that has anything to do with the problem with the wrong data being given.
https://gyazo.com/8e0ba30f5fcdcc64ab1f43427320e0d8
https://pastebin.com/mWYsG0ba

slim nebula
#

might be an index 0 vs index 1 issue?

odd cipher
#

Not sure..

karmic basin
#

You should floor the position based on cell size no?

#

Vector3 lowerLeft = new Vector3(Mathf.Floor((int)position.x / cellSize) * cellSize, 0, Mathf.Floor((int)position.z / cellSize) * cellSize); something like that ? (not tested)

#

because yeah that seems like a one-off error

odd cipher
#

Nope, didn't make a difference

zenith wyvern
#

I'm not 100% sure but it looks like you're drawing based on a world position and expecting it to draw based on the local position of your mesh

#

If you move your mesh so the bottom left corner is aligned with the world grid does it behave like you expect?

#

Also you don't need vector3s. You can pass float3 directly to DrawLine and it converts them implicitly

#

So you can do something like ``` void DebugDrawCell(float3 p)
{
p.xz = math.floor(p.xz / cellSize) * cellSize;
float3 right = new float3(cellSize, 0, 0);
float3 up = new float3(0, 0, cellSize);

    Debug.DrawLine(p, p + right);
    Debug.DrawLine(p, p + up);
    Debug.DrawLine(p + right, p + right + up);
    Debug.DrawLine(p + up, p + up + right);
}
odd cipher
#

Thank you! That fixed all of the problems I had. Now I can move on from this :p

karmic basin
#

Cooooool

odd cipher
#

Alright well for the performance, the Quadrant system itself takes ~5ms and the system that read the quadrant data for each entity takes ~0.05ms with 1000 entities that are searching and 500 food entities

#

I feel like it can be improved

#

Not sure, but it is definitely better than what I had before. However I will need to search neighboring quadrants if their 'search radius' goes outside of a singular quadrant. Which I am not sure how to do.

#

Oh oops! The quadrant system was running instead of scheduling. My bad, with scheduling on it runs in just ~0.05ms as well. Way better than I thought.

karmic basin
#

Yeah also remove Debug for the build, it should get slightly better

odd cipher
#

Yeah I did.

karmic basin
#

it's similar to how you started to debug draw your quadrant. You go +1 in each direction

odd cipher
#

Mhm, I'll try getting that to work.

karmic basin
#

Let's say you are checking Quadrant at index(2, 5), you also check all combinations of -1 and +1 on X axis, and -1 and +1 on Z axis,
Quadrant (1, 4)
Quadrant (1, 5)
Quadrant (1, 6)
Quadrant (2, 4)
Quadrant (2, 5)
Quadrant (2, 6)
Quadrant (3, 4)
Quadrant (3, 5)
Quadrant (3, 6)

odd cipher
#

Precisely. Though only problem with this is that the radius that a entity could have could be larger than that 3x3 quadrant area
And if that radius is the same as one quadrant I don't need to check the neighboring ones at all.

karmic basin
#

Totally, as long as you scale everything right you're fine with one

#

You avoid the hassle πŸ™‚

odd cipher
#

I'm guessing you mean that I can scale the quadrant to the size of the radius. It won't work like that as each of those entities has their own radius. They don't share the same one.

karmic basin
#

Set your quadrant system based on the largest radius ? This way you still benefit, unless you have an entity that can see the whole map :p

#

Anyway you still need to check neighbors in case your entity is too close to the border

#

Or maybe each Entity can tell how many quadrant offset they are allowed to check, for those who see further

#

And you dont need to store that data, you have everyhting with radius and cellsize

#

Man I'm tired

odd cipher
#

Heh yeah, I just need to figure out the right math for it :p. There are probably some examples on how to do it online that I can take a look at. It'll just take a little bit of time.

karmic basin
#

Alright good luck

stone osprey
#

How do i make one "Scheduled()" loop run after another one ?

zenith wyvern
#

When you're not messing with jobhandles that's the default behaviour of systembase.

stone osprey
#

Oh... alright, thanks ^^

#

One other little question... my server sends every 500 ms a new location to each entity. This way it looks like my entities are teleporting around. Any idea how i could interpolate the movement ? Currently the flow looks like this : New Packet received -> entityTransform.position = packetPosition -> System places entity down... i also have a "Movement" component that interpolates a entity's position, but i have no idea how to use that one properly because the new location gets parsed into the transform instead of the "Movement component"

zenith wyvern
#

Sorry I have no idea when it comes to networking stuff

stone osprey
#

Damn... me neither

#

Probably some sort of history is required for such a task...

#

Like always storing the last position, then when a new one comes we use the old one as the position and the new one as the target

hollow sorrel
#

yea basically that

#

then it's just a math.lerp between positions

stone osprey
#

@hollow sorrel Thanks πŸ™‚ Then the only last problem left is choosing a architecture. My Packet-Receiver simply writes the new position inside my transform component. I want to automate this later, so i cant implement the logic in there. Which means i need to implement it inside the ecs instead :/

#

And thats my main problem... i have no idea how. Im already tracking the past position by simply writing the last location into another component at the end of the movement system. Now i need some way to use write the new position into "MoveTo" and the last position into the transform

hollow sorrel
#

not sure if i understand correctly but i think what you'd want is to seperate the 'networked' position from the 'real' position, and maybe even another seperation with 'interpolated position' and 'real' position

#

what i do is seperate 'real' position that is used for physics, updates at a fixed rate, and then a 'interpolated position' that is only used for rendering

#

i don't use networking but if i did i'd prob have another component that keeps track of what the networked position is

stone osprey
#

So i should basically have a "RealTransform" and a "NetworkTransform" and then i interpolate the realtransform towards the network transform ? ^^ That makes sense... thats actually easier than tracking the last location and also much more flexible

hollow sorrel
#

yeah, or RealTransform can just be a copy of NetworkTransform, and then a seperate RenderTransform that has the interpolated version

#

RealTransform and NetworkTransform are prob pretty similar but i think i'd personally want to have at least a mental seperation of the network version being 'what the server reports' and 'real' as what is running on the local client

stone osprey
#

Thanks, thats what im gonna do... much more clean that tracking locations ^^ its a pitty that structs cant inherit from each other :p now im forced to write an exact copy of that one

weak oak
zenith wyvern
#

Are you sure it's bursted? You have burst enabled in the editor and you have the [BurstCompile] attribute on the job struct?

weak oak
#

yeah i added the attribute and enabled burst but it doesn't work

zenith wyvern
#

I can see you have a couple functions taking managed arrays. Just make those static

weak oak
#

the burst inspector says something about remark unknown:0:0 loop not vectorized

#

you mean the get and set map?

zenith wyvern
#

Yeah. I'm not sure if that would cause errors unless you're explicitly calling them from inside burst though, not sure

#

I would try making them static and see if it still errors

weak oak
#

So I made a new version but it still complains about loop not being vectorized

#

does it compile static methods to burst too?

zenith wyvern
#

Can you post the exact error? And no, it definitely won't compile static functions unless you call them from inside burst

weak oak
zenith wyvern
#

You can surround it in triple backticks with linebreaks between or just some pastebin

zenith wyvern
#

Backtick is `

weak oak
#

Oh cool thanks

#

How do i send the message after that though? enter doesn't work

zenith wyvern
#

You have to click after the last backtick and press enter

#

So one set of 3 backticks, code, then 3 backticks, enter

weak oak
#

did you see the error?

#

oh thanks

#
test
#

Aah it works!

zenith wyvern
#

I did yeah, from what I could see that error can happen if you try to pass in a member variable to a job. Are you doing that? Anything you pass into a job must be assigned to a local variable first

#

Even if it's just an int

#

From only what you posted I can't see what would be causing it. Can show the code where you're running the job?

weak oak
#

I was

stone osprey
#

Another quick question... how do we "slerp" or "lerp" a "quaternion" ? I mean that one from the new math library

zenith wyvern
#

math.slerp

stone osprey
#

perfect, thanks ^^

frigid onyx
#

So there's an AddBuffer and GetBuffer, but it looks like GetBuffer creates a buffer if it doesn't exist? Or am I not reading their code correctly?

#

If that's not the case, how do I check for the existence of a buffer (to know to use AddBuffer)

#

I can't test a DynamicBuffer<T> != null

#

EntityManager.GetBuffer<T>(ent).IsCreated , maybe?

zenith wyvern
#

EntityManager.HasComponent<BufferType>

frigid onyx
#

So like EntityManager.HasComponent<DyanmicBuffer<T>>(ent)?

zenith wyvern
#

No. Just the "T" part

frigid onyx
#

How would it differentiate between T and a DynamicBuffer of T?

zenith wyvern
#

It doesn't make sense for it to differentiate. An entity either has a dynamic buffer of your type or it doesn't

frigid onyx
#

So let's say you have MyComponent , which inherits from IComponentData. How would HasComponent distinguish an entity that has a component of MyComponent from a DynamicBuffer<MyComponent>?

zenith wyvern
#

You can't have a DynamicBuffer of MyComponent because MyComponent is an IComponentData. The contents of a d DynamicBuffer can only be IBufferElementData

frigid onyx
#

Or, in my actual use case, ICommandData.

#

Ok, that helps, thanks

pulsar salmon
#

Is it possible to have a NativeArray of NativeArrays? It seems like no... Or should I allocate one big NativeArray and sub-arrays using NativeSlice?

zenith wyvern
#

You can't have native arrays inside nativearrays. You need to collapse everything into a 1D array or use NativeMultiHashMap or NativeStream

gusty comet
#

Is ECS and such good to start learning again or is it constantly changing still? I gave up after learning it two-three times as it kept removing/adding things that changed everything entirely. So I'm hoping it's aged enough to be usable and next week not changing a million things again.

wary anchor
#

Hi all, need some advice about Worlds.

I'm a fair way through development, but when I started I did everything in one World, including all my physics and movement, so it's all on the same Update() loop. My game is GPU-bound because it's 100% raymarching; on older GPUs, I now realise if the frame rate drops really low, I get problems with the player not colliding properly with the environment because the deltas are too big during a single frame.
I'm not sure how best to tackle this. I could in theory separate all the non-rendering related code out into a different World, but have no idea where to start with this or how the worlds interface with each other. Alternatively, I could try to modify my physics specifically to mitigate the issue, but that does feel a bit of a hacky approach to the problem.
What say you gurus?

visual juniper
#

I would only consider multiple worlds in situations where i would want to keep iterations over entities small. For example you have 10 game floors and on each you have units searching for valid opponents (assume a pathfinding algorithm like A*), if those floors are never connected, you could keep itterations low by having 10 worlds so that the search for valid opponents ends up beeing 10 small loops (it's basically a pre-filter in a sense).

Otherwise I would suggest to first tackle your frame drops anyways as those are obviously always an issue. Would be interesting to hear different opinions though

icy hinge
#

I am trying to sync and interpolate rotation with NetCode ghostfields, but if the rotation value goes from 359 to 0 the interpolation makes the object rotate the full 360 degrees back.
In the DOTS Sample the character class has an angle float with a custom [GhostAngleValue] attribute that uses angle lerping instead of normal lerping.
This custom functionality is implemented in a class that's derived from GhostSnapshotValue which doesn't exist in the latest version of NetCode.
How can I implement this behaviour in the latest version?

pulsar jay
#

I think having different tick rates might be a good reason for having multiple worlds. Though I havent thought about the update rate of the physics group yet. I thought it had a custom tick rate even if it is the same world

visual juniper
wary anchor
#

obviously I'll be addressing the slow frame rate issue - but this is an edge case for older graphics cards where the settings have been bumped up. I could just say "well don't do that" but in the event someone does buy my game and runs it on slow hardware or on an insanely high res display, I'd like to handle the edge case a bit more gracefully than at present!

visual juniper
#

was thinking a bit now, i think i would still go with multiple worlds instead of shared component data @pulsar jay (in the example i made). because most probably a lot more is happening per floor than just units searching each other. and having a shared comp on all the entities that are floor specific is not only error prone but also tedious. it's far easier to use a entity transaction and move everything to that world it should participate in. Also you don't have to write chunk itteration or set any filters, but you can use full power ScheduleParallel systems πŸ™‚ @wary anchor sorry, didn't mean to give stupid advice of course πŸ˜‰ The tick argument i would actually agree upon. also nice link, didn't know that. seems worth a try

distant imp
visual juniper
gusty comet
#

@visual juniper Thanks mate, I might try to dive into it a bit for my game. Do animated meshes get more performance benefits with it? As we all know skinned mesh renderers kill performance kinda bad (or can at least). So curious if there's performance benefits with ECS and animated meshes.

visual juniper
#

So far we used a hybrid approach for skinned meshes (but we also don't work on projects that have high numbers of them where it would become relevant).
I think there's somthing on the way though, you might wanna check out forum topics like this : https://forum.unity.com/threads/how-can-i-animate-skinned-meshes-in-ecs.894688/

gusty comet
#

I hear ya mate, I've thought about doing hybrid, just seems like it might make things more complex (could be wrong), just seems like it would be an organization mess mixing regular components and ecs logic together. But i'll check it out right now, thanks for the info πŸ™‚

#

Dang they getting killer performance (the person talking about the cliffs, trees, etc)

#

17K Skinned Meshes, wow haha. I and here I was thinking 100 players on a map was gonna be hard on skinned meshes, yeah I might try this hybrid approach lol

icy hinge
#

Keep in mind that a human character has a lot of bones, so the performance impact might be a lot bigger depending on the model and the rig you're using

#

Since they're using a mesh that only takes up a small part of the screen they can get away with way less detail

#

less tris and less bones

gusty comet
#

Most of my rigs will be of animals, so may end up being more bones and such than a person to account for tails, paws and their toes, etc. I guess I can try sticking with normal stuff for as long as I can, no sense in premature optimization lol. If I can get it to work smoothly no sense in using ECS until I need too. I guess I can run a test once I get some animals made and stick as many as I can on the screen doing various things to see the performance impacts.

#

I'd say each animal will be about 10K Poly's for the animal and 20+K for the haircards (unless I can figure out how to do Fur in HDRP)

#

with shadergraph

#

But thanks everyone for helping me get a bit more up-to-date on ECS πŸ™‚

distant imp
# karmic basin https://docs.unity3d.com/Packages/com.unity.entities@0.16/manual/transform_syste...

Thanks! Read it a few times now but maybe I'm not getting it. I have this code:

var entity = EntityManager.CreateEntity(typeof(Translation),
                                        typeof(LocalToWorld),
                                        typeof(RenderMesh),
                                        typeof(RenderBounds),
                                        typeof(ScalePivot),
                                        typeof(NonUniformScale),
                                        typeof(CompositeScale));

EntityManager.AddSharedComponentData(entity,
                                     new RenderMesh
                                     {
                                         mesh     = CreateMesh(1), // Creates a 1x1 mesh
                                         material = material
                                     });

// omitted other RenderBounds code

EntityManager.AddComponentData(entity, new ScalePivot { Value = new float3(1, 1, 1) });

EntityManager.AddComponentData(entity, new NonUniformScale { Value = new float3(2, 2, 1) });

And in OnUpdate I have this:

var deltaTime = Time.DeltaTime;

Entities.ForEach((ref NonUniformScale scale) =>
                 {
                     scale.Value += new float3(0.5f, 0.5f, 0) * deltaTime;
                 })
        .Schedule();

I'm expecting for it to scale from top-right, but I'm getting bottom-left

eager jungle
#

Hey guys. I've got a massive hierarchy of meshes, which are static. It seems like they don't like being converted (using Convert To Entity). Meshes are spread all over the place (positions are wrong). Not converting works fine. Converting and making them not static works fine as well. Also maybe related, I've got really bad framerate when converted, even worse than not converted + not static. Any idea? I'm using hdrp9, hybrid0.8p19, in unity 2020.1.6

safe lintel
#

i dont know why but ive had issues with static gameobjects being converted too.

#

only workaround was to mark them not static so far\

#

any reason you are relying on it for conversion? i found you can bake navmesh data and then unset static or at least set it to navigation static only and it does convert properly

eager jungle
#

i just assumed entities + static would be more performant and be a better choice overall. Also we are using dots physics.
I could leave them as not static, but its super slow compared to classic static non converted GO. In the end i had to leave them as static Go, and to create proxy entities just for the physics... which im not super fan of

safe lintel
#

are you using staticoptimize on your entities? and did you profile exactly what is causing the lesser performance compared to non converted static gameobjects?

radiant sentinel
#

hi, Entity index is int, what happen if we create more than int.maxValue entities?

tawdry tree
#

Entity has two ints as identifier, so unless you make 2 billion entities without ever deleting one, I assume it'd just use freed indexes

#

And if you do make 2 billion entities without ever deleting one, I'm sure the DOTS team would like to learn about your unique use-case

hollow sorrel
#

i dunno but also i think there's currently a limit of 128 million entities per world

#

at the same time

#

not sure why that number, just saw it come by in changelog

zenith wyvern
#

Huh, Unity is now integrating MLAPI. I wonder what that means for dots netcode

#

Oh I see, from the blog post As we mentioned above, this announcement is focused on developers working with a GameObjects pattern. For developers that are working with, or evaluating, the Entity Component System (ECS) pattern, either because of preference or because their title needs that level of hyper performance, the Unity NetCode package (Preview) continues to be Unity’s first-party framework for the scenario.

karmic basin
#

Yeah I guess dots networking will still be a thing, looks like it will fight against Mirror

zenith wyvern
#

I guess they got tired of people talking mess about their built in solution (for good reason)

safe lintel
#

havent been paying attention but was mlapi some sort of mirror like project prior to being bought out? havent heard of it before

zenith wyvern
#

It's just an open source networking solution, I guess a pretty good one. I hadn't heard of it either until earlier this year

eager jungle
safe lintel
#

it removes unnecessary transform components. might wanna profile though to narrow down your problem

dull copper
#

on one traditional game level demo I tried that static optimize and without it, it made a huge difference. also if you have static objects I can't see why you wouldn't use that (altho I somehow wish it would just set that on it's own from the static gameobject flag during conversion or something)

low tangle
#

one thing I disliked when using hybrid render was that you couldn't just remove 99% percent of transform components and get a static setup

#

on my custom engine, the only thing the rendering needs is the L2W plus Bounds for culling

#

you can cut all components right off (or disable) and it just shaves all the cpu cost away. seems like it should be inclusive instead of exclusive but who knows

#

also I see a few mentions of fixed update, are people not using fixed update utility?

#

@wary anchor if you want different fixed rates within a world, just use this and set them to different groups

#

to interpolate the results between ticks, make a presentation component, put a long tick number on it, along with the current fixed rate length (the delta). inside the group, set the delta time (will be the groups fixed dt) and bump the tick number. on components for interpolation, you bump the last tick value to somewhere (usually just a Current, Last field in the component)
then outside of the fixed group, you take the current tick, your actual frame dt, div the floats into a percent and (s)lerp the values between the two ticks

#

fixed rate utils also lets you set and unset the fixed rate while running

#

I did that from network events from the server to sync up the tick rates between server & client

rare umbra
#

Hey all, what’s a good design pattern for having global system parameters editable in the editor but not instantiated per entity. I need my system to be able to reference these

deep nymph
#

Is there a way I can get an Entity to collide with a game object in version 0.0.12? (2018 is the latest version that can run on my computer)

I’m trying to create a Bullet Hell framework for Unity and I don’t need everything on my game to be an entity.

hollow sorrel
#

@deep nymph either use gameobject physics and make entity copies, or use entity physics and make gameobject copies

rare umbra
#

anyone know what this might be caused by?

Internal: JobTempAlloc has allocations that are more than 4 frames old - this is not allowed and likely a leak

How do I track down said leak?

hollow sorrel
#

look for native containers that are allocated using jobtemp alloc

#

or ctrl f Allocator.TempJob

#

if it's not your own code, it might also be happening if you're using a commandbuffer and executing it more than 4 frames later

rare umbra
#

@hollow sorrel ctrl+f didn't find anything in my c# project :/

#

no commandbuffer either - I literally have 1 dumb system in this project and it's not really doing much yet

hollow sorrel
#

@rare umbra what entities version? if you only have 1 system could be unity bug

hollow sorrel
#

huh weird

rare umbra
#

it was working a few weeks ago when I set it up. Maybe it's because I'm on the latest version of Unity

#

also my GO's seem to disappear from the scene when I hit play (after conversion - their mesh isn't converted to an entity component).

I step away from ECS for a couple of weeks and I feel like I'm back to square one.

zenith wyvern
#

Are you sure you have the hybrid renderer package installed?

rare umbra
spark glade
#

Has anyone seen a error log like this before:

#
ReadWriteBuffers are restricted to only read & write the element at the job index. You can use double buffering strategies to avoid race conditions due to reading & writing in parallel to the same elements from a job.
Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at /Users/bokken/buildslave/unity/build/Runtime/Export/NativeArray/NativeArray.cs:254)
Unity.Collections.NativeArray`1[T].CheckElementWriteAccess (System.Int32 index) (at /Users/bokken/buildslave/unity/build/Runtime/Export/NativeArray/NativeArray.cs:142)
Unity.Collections.NativeArray`1[T].set_Item (System.Int32 index, T value) (at /Users/bokken/buildslave/unity/build/Runtime/Export/NativeArray/NativeArray.cs:161)```
#

Deep inside Unity.Physics.Systems.BuildPhysicsWorld+Jobs+CheckStaticBodyChangesJob

#

which touches

#
                [ReadOnly] public ComponentTypeHandle<LocalToWorld> LocalToWorldType;
                [ReadOnly] public ComponentTypeHandle<Parent> ParentType;
                [ReadOnly] public ComponentTypeHandle<Translation> PositionType;
                [ReadOnly] public ComponentTypeHandle<Rotation> RotationType;
                [ReadOnly] public ComponentTypeHandle<PhysicsCollider> PhysicsColliderType;
rare umbra
#

@zenith wyvern @hollow sorrel found my issues - both were caused by the netcode package

spark glade
#

I think it started happening when upgrading entities or physics package (maybe it got smarter in detecting issues) πŸ€”

spark glade
#

Did anyone upgrade physics to 0.5.1-preview.2 ? When I tried my entities started disappearing because the physics eventuelly caused my transforms to end up having a bunch of NaNs. no issues on 0.4.1 😦

safe lintel
#

havent had any issues and all my packages are the latest

spark glade
#

maybe the issues are related, just express themselves differently πŸ€”

rare umbra
#

Really dumb question - if I have a monobehavior on a GO and convert that GO into an entity - how do I reference that entity within the monobehavior?

spark glade
safe lintel
#

i would do the painstaking thing of start disabling everything until it doesnt error to narrow it down 😒

spark glade
#

yeah :/

#

Finally some free time again and I'm wasting it all (presumably) on fucking package incompatibility 😦

safe lintel
#

hmm didnt snacktime have some error regarding entities that popped up during animation?

spark glade
#

Let me stalk him in the forums πŸ˜„

frigid onyx
#

NetCode question: It looks like you can't have more than one type of DynamicBuffer<ICommandData> at the same time? Is there a reason for this?

#

Or--has anyone ran into this? If so, what is the workaround? It looks like if I've already established one input buffer, adding another one gets set up fine, but doesn't actually relay the buffer from the client to the server, even if both input buffers are defined on the same command target entity

spark glade
#

@safe lintel if I simply comment out the following things: physicsVelocity.ApplyAngularImpulse, physicsVelocity.ApplyLinearImpuls and physicsVelocity.Linear = foo I get no errors πŸ€”

#

makes me wonder if something changed there πŸ€”

#

Lemme undo to 0.4.1 and see if that fixes the issue s well

safe lintel
#

is that commenting out in your systems or the package itself?

spark glade
#

that part of my system

#

Commenting out futher, ApplyAngularImpulse seems to be the culprit 😱 Why on earth would that behave differently now...

safe lintel
#

@rare umbra in the conversion thing just store it in a field in your monobehaviour

Entity myEntity;
void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
  myEntity = entity;
}
// do stuff with it
void Update(){
World.DefaultGameObjectInjectionWorld.EntityManager.SetComponentData(myEntity, new Translation{Value = transform.position})
}
rare umbra
#

I’m probably missing something insanely simple πŸ˜„

safe lintel
#

first how do you want to interact with your entity?

#

as i guess i dont understand what youre trying to do

rare umbra
#

Oh so I have a component that has data like radius, lengthOfPress etc.

I have a system which checks if the player is in radius and sets a bool to true. I’m reading that bool in a MB for the HUD icon which is on the original GO for the interaction and then if the bool is true I’m displaying a sprite over the entity

solemn ice
#

noise functions in Unity.Mathematics seems to go negative, do anyone know what's the range supposed to be? Is it supposed to be [-1,1]

rare umbra
#

So basically displaying an interaction prompt over an entity if player is in range @safe lintel

safe lintel
#

ok so in the monobehaviour that converts the component, can you not just use GetComponent to tell the other monobehaviour what the entity is for future reference?

left spindle
#

I'm trying to convert my old DOTS Training system (using IJobForEach) to the more modern way (IJobChunk) but the results are far from the same. Can someone tell me what's wrong with my "Chunk conversion"? https://hastebin.com/jejecebuju.csharp

spark glade
#

Somehow I have NaNs creep in....

#
// physicsVelocity.ApplyAngularImpulse(physicsMass, angularImpulse);
physicsVelocity.ApplyAngularImpulse(physicsMass, 1);
#

making them spin in circles at a fixed rate seems just fine

left spindle
#

Okay, I figured it out, the problem was "BoneMatrices boneMatrices = allBoneMatrices[index];"

spark glade
#

Logging angularImpulse doesn't seem to have any sort of crazy values

left spindle
#

That needs to be: New BoneMatrices() and assign it at the end of the loop: allBoneMatrices[index] = boneMatrices;

#

For those who find this later on. When writing in IJobChunk, you have to assign it to the array, not a variable.

spark glade
left spindle
#

Oh, back on my point (sorry) boneMatrices is an unsafe array, itself.

#

I can't help you, I'm just posting so someone else might find my problem later.

spark glade
spark glade
#

hm, so it appears it's something with the inverseinertia settings

#

this used to be the way to lock rotation for bodies:

#
public void Convert(Entity entity, EntityManager entityManager, GameObjectConversionSystem gameObjectConversionSystem) {
    if (entityManager.HasComponent<PhysicsMass>(entity)) {
        var physicsMass = entityManager.GetComponentData<PhysicsMass>(entity);
        physicsMass.InverseInertia[0] = LockX ? 0 : physicsMass.InverseInertia[0];
        physicsMass.InverseInertia[1] = LockY ? 0 : physicsMass.InverseInertia[1];
        physicsMass.InverseInertia[2] = LockZ ? 0 : physicsMass.InverseInertia[2];
        entityManager.SetComponentData(entity, physicsMass);
    }
}
#

When I set the "locked" inverse inertia to something small like 0.000001f instead of 0, things work fine again.

#
        public static void ApplyAngularImpulse(ref this PhysicsVelocity velocityData, in PhysicsMass massData, in float3 impulse)
        {
            velocityData.Angular += impulse * massData.InverseInertia;
        }
#

public float InverseMass; // zero is allowed, for infinite mass

#

🀷

#

maybe it also has to do with the fact that physics run on fixed step since 0.5.0... and maybe previously I was lucky to have had the right dependencies that it never was an issue πŸ€”

#

So many questions... so few answers I have πŸ™ƒ

spark glade
odd cipher
#

@spark glade Are you trying to lock the entities rotation? I've been trying to do the same thing but haven't gotten it to work very well.

spark glade
#

Above method of setting inverse intertia to 0 worked until 0.4.1, but with 0.5.0 there appear to be some issues 🀷

#

I'll ask around in the forums tomorrow

radiant sentinel
odd cipher
#

How would I set specific indexes of a buffer in a parallel job? This doesn't work in parallel it seems.

tawdry tree
rare umbra
radiant sentinel
tawdry tree
rare umbra
#

I have a gamemanager singleton which holds a reference to a player entity. What is the appropriate way to get the component data from that entity from within a system. My system is currently running a ForEach and not on entities which have the "player" component

tawdry tree
rare umbra
tawdry tree
#

Given that you're doing hybrid code it's perfectly fine to store the Entity in in a MonoBehavior. The protips are more if you're doing pure ECS (or as pure as in reasonable to do at the moment).
The patterns for that would be:
-If you only need the reference in one system, just use a field on the system (ie. System.PlayerEntity). You could also scale this up for multiple systems(easy and reliable)
-Or you could create a singleton component which holds the player reference, and query for this as needed (a bit more cumbersome, need to decide which system gets to create the singleton, probably want to store it to the system, etc.)

Of those two general methods, #1 is definitely the easiest, but there are use-cases where it is not feasible.
For example, if the player is created "some time" during runtime, and you can't easily query for it (for example if the player archetype("sum" of components) is not unique), you would probably want whatever system spawns the player also create a singleton component with a reference to the new entity.

valid haven
#

What are the situations where JOBs + Burst + Mono are greatly out performed by JOBs + Burst + EntitySystem

#

its not clear to me the expected order of magnitude difference and where this difference becomes most pronounced.

tawdry tree
#

The only case where that would happen is if the overhead of the system and queries is higher than the overhead of the MB stuff.
The systems have a "static" overhead and scales extremely well, where that is not the case with MBs.
If most heavy code is in burst jobs you should have pretty dang good perf either way, though.

valid haven
#

Hmm ok, I mean I can layout the relevant MB classes in a data-originated manner to help with this I assume.

tawdry tree
#

If you're not sure whether to go for ECS or MB, I recommend going for MBs, unless you specifically want to learn/experiment with ECS, of course.
The general route I would suggest is:
-Write code as normal in MBs.
-When you have code you think is heavy, profile to verify - you might be wrong. Be sure to profile at a light load, but also at the highest expected normal load (for example max enemies in play at once)
-When you have code you know is heavy, extract it to jobs. The burstify and parallelize as possible/necessary.

valid haven
#

understood, for my current project I am thinking of staying away from EntityComp entirely, but using Jobs+Burst where it make sense.

tawdry tree
rare umbra
valid haven
#

I assume I am precluded from doing any Physx related stuff in jobs since its not written for it.

#

i.e. I cannot accelerate raycasts

tawdry tree
tawdry tree
valid haven
#

My game is an open world game, with a fair amount of procedural events and a lot of dynamic objects (player building system, large interconnected inventory systems, complex resource / entity spawning system).

#

So updating world state for a number of these things will be good to get off the main thread.

tawdry tree
#

Buildings will probably be more or less inert, I assume (collision, maybe something like a furnace (level of complexity like minecraft furnace, maybe a bit higher, like MC modded basic tech mods))

valid haven
#

Also there will be quite a few entities that need transforms

#

well buildings do need to update stability states and the buildings structures can be fairly complex, but ya these events wont be often but heavy when they happen.

tawdry tree
#

Pretty much one-off, side-thread jobs, then

#

Probably wouldn't matter much if they skip a couple frames, too

#

If you're talking about something like Don't Starve or even 3D like ARK, I seriously doubt you're gonna get perf issues if you build the architecture well and use parallel, bursted, jobs.

valid haven
#

also the game will have ALOT of active combat related traps, projectiles, triggers etc... that will need a lot of updates/checking.

#

Hod ya that is the plan

tawdry tree
#

...are you also planning on multiplayer?

valid haven
#

of course πŸ™‚

tawdry tree
#

Brave. I really hope you have a few games under your belt, including at least one (even simple) multiplayer game

valid haven
#

brave indeed. Nothing at this scale, pushing personal boundries =). My last project has about 200k users. Supporting 32 simultaneous players controlling up to a few thousand multiplayer objects. Wasn't in unity and I had to write the netcode and physics myself so in someways things are easier =).

#

This project is not just me tho

tawdry tree
#

If you're familiar with netcode at that level, it sounds like at least networking (probably) won't be a killer in this project

#

Well, "you" here being the collective team

valid haven
#

Ya my plan was to modify MLAPI for my needs. But with the recent announcement I may have less/nothing to modify by the time I release.

#

jobs/burst also makes things a lot easier as I dont need to do my own low level threading infrastructure.

tawdry tree
#

There's some guidelines for that, I'm sure you can find them, but it boils down to "short term, keep using the existing stuff, but if you're not gonna release in a few years, don't get too fond of the current implementation"

valid haven
#

yup thats the thinking. Feature wise I am targeting 2021 LTS most likely.

rare umbra
#

If I have system A which takes data A and outputs data B and system B which takes in data B and outputs data C does that mean to see the effects of changing A on C I need to wait 2 frames?

shy pilot
#

dumb question here, entity worlds aren't erased on scene load right?

gusty comet
#

Is DOTS only suited for games that have a high amount of scripted characters? What about an open world game?

#

All the examples I'm seeing is "look how many entities I can have doing things on one screen"

safe lintel
#

well technically dots isnt suited towards much given its current state. dots is really solving the problems of performance and data management, so the easiest things to showcase are instances where there are many things on screen to show the benefits. why bother showcasing something with just a handful of things if gameobjects already covers that? it wouldnt make for a sexy marketing demo.

gusty comet
#

Right - I'm just trying to figure out if the system is better suited to particular genres or if it's more of a question of your programming skills (indie vs AAA). It would seem to be most beneficial in RTS games for instance but something like a 3d platformerer... the physics and rendering might be a bit faster but is this significant or is it generally not going to do much for 3d platformerer type games.

#

Basically is it something everyone should be looking into and questioning if it will be useful to them...or only for certain games

rare umbra
#

I would’ve thought that it’d be very useful in an Open World game. If you have a big world you have lots of entities.

low tangle
#

I highly highly suggest not counting on anything unity is bringing out in the future, build using what you have in your hands now. not what they will have by the time you get to it (like the MLAPI). architecting up front helps keep the project sane and on track, you know this. @valid haven

valid haven
#

June I have access to MLAPI, so I am using the open source version for now

low tangle
#

make sure you evaluate that its good enough for your needs now is all I'm saying

#

dont count on future updates to it

valid haven
#

if I need to manage my own git of it that is fine

#

πŸ™‚

low tangle
#

alright, just be mindful of that extra burden

valid haven
#

understood

low tangle
#

experimental / new tools come at a cost to the project, too many and the project wont be finished

valid haven
#

having reviewed the various public unity netcode stacks at a source level MLAPI is really the only one I am willing to use

low tangle
#

all AAA engines at this point include a task/job system, and unity's job system + burst is quite stable and 100% ready for use. I suggest to most people to just get started with that and not touch UECS yet

valid haven
#

ya I am on the same page. Would like to use Jobs/Burst but am saying away from ecs

low tangle
#

after using it for two years, Its only just now starting to become possible to finish complex games with it. lots of baggage with that statement though

valid haven
#

yup, at this point I think its in a good enough state where its worth not writing my own thread pools and what not =).

low tangle
#

that and burst creates some quite good results

#

if you have questions, sometimes people can help here with it

valid haven
#

πŸ‘

zenith wyvern
#

Awesome tips thank you! Given that I’m going hybrid (because I’m using a spriteComponent) do you have any tips about how to get the component data from an entity within a system that the component isn’t part of the JobForEach?
@rare umbra

Usually you would get the first entity via a query on the main thread or a separate job then pass it into the foreach

#

Or that's how I would do it at least

rare umbra
zenith wyvern
#
var tar = new NativeReference<Entity>(Allocator.TempJob);
Entities.ForEach((Entity e, in Whatever whatever)=>{
// Get your entity, assign it to your nativereference
}).Schedule;

// schedule new job, pass in NativeReference ( and remember to dispose it after)
#

Sorry I'm at work on my phone, best I could do

#

If you don't need this to be done in jobs you don't even need the nativereference, just use a normal entity and use .Run on your jobs

rare umbra
#

yeah I just need to grab it before I do Entities.ForEach and pass it in

zenith wyvern
#

Then you can just call GetComponent on the entity reference to get your data

odd cipher
#

I still have a problem where the entities are rotating, trying to suppress that but there's no easy way to do so it seems.

#

it runs at about ~90 fps in editor (although that is with quite a lot of additional systems and the drawing)

rare umbra
#

Woo nice!

#

Grr I’m having a frustrating issue where each second OnUpdate of my system I get a null reference exception when trying to GetComponentData.

No idea why it works half of the time and other half it doesn’t. The entity is cached in a private Entity OnStart and then referenced in each OnUpdate

#

I think I could probably do a null check but I’d really like to know why this is happening

#

Not sure how to debug :/

#

Ln 25

#

ok, so it's actually failinng every time methinks.

#

Translation playerTranslation = EntityManager.GetComponentData<Translation>(playerEntity);

This seems to work!

zenith wyvern
rare umbra
#

doh!

even so, if I use this OnUpdate it doesn't work:
manager = World.DefaultGameObjectInjectionWorld.EntityManager;

zenith wyvern
#

You should go through the ECS samples from the pinned messages. They are well documented and will help you a lot I think

rare umbra
#

cool, will do thanks @zenith wyvern It's also been a few years since I've written c# in Unity so I'm all round rusty

#

ok, perfect - works like a charm now

rare umbra
#

btw does the new input system play nice with ECS? or are we still waiting on that?

safe lintel
#

it works fine, but its not ecs native

rare umbra
low tangle
#

you can do just that

#

monobehaviour setups the input callbacks and stuffs whatever data into a new entity

#

mine thread access of the entity manager is fine

rare umbra
#

Yeah makes sense though feels quite long winded. Thinking about just using MBs instead of systems to handle any reactions to input

safe lintel
#

you can use it directly in a system without monobehaviours

#

its more elegant than using a monobehaviour imo, theres an example in the physics samples of how its setup

vagrant surge
#

they have integrated a unity'style ECS for animation calculation in Sequencer (cinematic tool)

odd cipher
#

Interesting

vagrant surge
#

tho what is the funniest is this

#

recode literally the entire animation runtime into data-oriented ECS paradigm for highly parallel and uberfast

#

inmediately bottleneck on the crappy OOP overhead of the scenenode system

#

they could have gotten a better gain if they tried to do delayed-transform or similar to improve SetActorTransform cost

warm panther
#

I can't work with subscenes anymore, and have no idea what causes it:

Loading Entity Scene failed because the entity header file couldn't be resolved. This might be caused by a failed import of the entity scene. Please take a look at the SubScene MonoBehaviour that references this scene or at the asset import worker log in C:\Projects\protojovian\Logs. scenePath=Assets/Scenes/Jupiter/FloatingOriginTest.unity guid=d1fcf33267b30a947851aa73f06c77c7
UnityEngine.Debug:LogError (object)
Unity.Debug:LogError (object) (at Library/PackageCache/com.unity.entities@0.16.0-preview.21/Unity.Entities/Stubs/Unity/Debug.cs:13)
Unity.Scenes.ResolveSceneSectionUtility:ResolveSceneSections (Unity.Entities.EntityManager,Unity.Entities.Entity,Unity.Entities.Hash128,Unity.Entities.RequestSceneLoaded,Unity.Entities.Hash128) (at Library/PackageCache/com.unity.entities@0.16.0-preview.21/Unity.Scenes/ResolveSceneSectionUtility.cs:76)
Unity.Scenes.ResolveSceneReferenceSystem:OnUpdate () (at Library/PackageCache/com.unity.entities@0.16.0-preview.21/Unity.Scenes/ResolveSceneReferenceSystem.cs:174)
Unity.Entities.SystemBase:Update () (at ... )
Unity.Entities.ComponentSystem:Update () (at Library/PackageCache/com.unity.entities@0.16.0-preview.21/Unity.Entities/ComponentSystem.cs:113)
Unity.Entities.ScriptBehaviourUpdateOrder/DummyDelegateWrapper:TriggerUpdate () (at Library/PackageCache/com.unity.entities@0.16.0-preview.21/Unity.Entities/ScriptBehaviourUpdateOrder.cs:333)
#

The message also refers me to a log file, the most prominent issue there appears to be this one:
System.IO.FileNotFoundException: Could not load file or assembly 'Unity.Burst.Unsafe, Version=4.0.5.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.

#

The error occurs whenever I try to deserialize a subscene, i.e. when unchecking it in the hierarchy (unity 2020.2), or when running the game.

north bay
#

Did you check the import log out?

warm panther
#

Yes.

#

It's the 2nd block.

#

Could not load file or assembly 'Unity.Burst.Unsafe

#

I reset all the packages, tried several burst versions, used my own and the original version of unity physics...

#

Tried it in an empty scene with fresh subscenes... to no avail.

#

What I am trying now is to somehow stop a lot of my code from compiling (wow I wish there was a checkbox to just remove a file temporarily...) to see whether it's maybe a circular dependency in physics or so, but that usually gets caught.

#

Ok I gutted my project and took out almost all ECS code. It still doesn't work.

#

Pretty close to starting from a new template but this is awful.

warm panther
#

Well it doesn't occur in unity 2021.1 alpha... ugh.

#

I really don't want to go there πŸ˜„

pliant pike
#

Is there something wrong with the Entity Debugger, its showing different numbers of entities?

#

I did an EntityQuery.CalculateEntityCount() and it says 100 entitys of that type and yet in the debugger it shows 200

zenith wyvern
#

Queries will ignore entities with "Prefab" or "Disabled" components unless you explicitly include them, maybe that's why?

pliant pike
#

yeah I know you can end up with copies with prefabs and things like that

#

but I have a list of 200 entities which all have the exact same data

#

well like entity 12 has the same data as 111 and so on

#

like they've been copied twice

#

I'm creating the entity's purely in code also

rare umbra
#

So I guess if the β€œDefault” scheme is not active then isTriggered is false, even if that button is pressed?

zenith wyvern
#

Correct

rare umbra
#

Huzzah this is so simple and scalable

#

Thank you so much!

pliant pike
#

I just realised I am copying the data using ToComponentDataArray<CellData>(Allocator.Persistent); in a monobehaviour, would that maybe show up as extra data in the entity debugger πŸ€”

zenith wyvern
#

I wouldn't think so, I thought that would just create a nativearray of structs, not entities

#

Could be wrong

pliant pike
#

yeah maybe its just a weird bug

rare umbra
#

If I want to find the lowest value of a variable on all components of type T and return the component data for that variable, do I have to do this via looping through a ForEach and caching the lowest one? Or is there a better way?

zenith wyvern
#

You have to loop through and assign it to a container. Native containers/NativeReference are the only way to get data out of a job

#

You can also use entityQuery.ToComponentDataArray<T> to easily get a copy of all your components then pass that into the next job

gusty comet
#

So would it be recommended to use standard OOP to create Characters, PlayerCharacters, and NPCharacters and then have NPCharacters be converted to Entities as opposed to using ECS for everything?

#

Because I'm thinking for the player, we don't really need ECS because there's only 1 player so his affect on performance will be minimal

#

but would it be less confusing to use ECS for everything?

safe lintel
#

definitely would be less confusing to keep things mostly in one area or the other. if you havent already tried it out id suggest you experiment with a mecanim animated char interacting with a pure entity and see what your tolerance for the back and forth communication that is involved with that.

#

all of my npcs are hybrid gameobjects with animators and also some pure ecs data, but my player is a pure ecs entity. tbh i cant wait to drop monobehaviour stuff as soon as possible for the majority of things except in cases like ui where its mostly minimal

gusty comet
#

I never liked the whole monobehavior stuff. Too many different scripts all forcing themselves on one another with complex gameobjects

#

But ECS is strange - just getting started with it

#

It definitely seems to be the way to go when you have large amounts of the same thing, but when you have a singleton-style class like the player...its odd

odd cipher
#

Does anyone know how you would prevent entities from falling over? I've tried doing physicsMass.InverseInertia = float3.zero; every update, it somewhat works but they occasionally still fall over and rotate very slowly.

safe lintel
#

you can set the velocity

odd cipher
#

I'm not sure what you mean, the physicsVelocity component?

#

I'm already doing that for movement but it's not great

#

or you mean angular velocity?

safe lintel
#

actually maybe the rotation component makes more sense here?

odd cipher
#

I guess I could constantly reset that variable to float4.zero?

#

though I'm not sure what the 4th value in the float4 means

#

actually new quaternion(0, 0, 0, 1); seems to work better.

#

yeah that seems to work way better than doing physicsMass.InverseInertia = float3.zero;, I don't see any rotating entities anymore :p

safe lintel
#

yeah i think float4.zero is an invalid rotation, i remember weird stuff when i was doing that

odd cipher
#

mhm, it gave some weird errors, that quaternion works though.

gusty comet
#

So I did this tutorial:

https://www.raywenderlich.com/7630142-entity-component-system-for-unity-getting-started

Granted, it doesn't take advantage of the jobs system OR the burst compiler...

However....

My non-ecs scene took about 80 seconds to reach 60 FPS

My ECS scene took about 45 seconds to reach 60 FPS.

So....the non-ecs was almost twice as efficient. Is this normal? I do have a 32 thread CPU w/ 64GB of RAM so maybe that screws up the performance advantage???

raywenderlich.com

In this Unity tutorial you’ll learn how to efficiently leverage the Entity Component System for more performant gameplay code.

#

Again, I know the real performance advantage comes w/ burst and jobs but I find it curious that ECS is almost 2x less efficient

safe lintel
#

if you disable the jobs in Jobs>use job threads, do you get better performance?

#

scheduling jobs has its own overhead and for low amounts of work you might get worse perf if you are scheduling everything as parallel jobs vs a single job thread or just mainthread.

gusty comet
#

The tutorial did not include jobs

#

So all the code is single threaded

#

Not claiming that DOTS is slower than Monobehvaiors as a whole, but it's interesting to me that on some hardware, ECS (w/o jobs and burst) can be up to twice as slow as a monobehavior approach. So makes me wonder if what you're doing can't really take advantage of the jobs system (say its a singleton and all the behaviors can't be split into a multithreaded workload), it may be more efficient to use the standard monobehavior approach

#

Though if I had to guess, I would imagine converting gameobjects to entities (Hybrid ECS) which this one does for every "drone enemy" has a performance cost and may be the culprit.

#

We've been seeing the devs show off DOTS in applications where DOTS is most advantageous over the traditional monobehavior scripts, but I wonder what the performance gain (or potentially, loss) would be in applications where DOTS is least advantageous

rare umbra
#

Performance isn’t the only reason to use DOTS though. It has some really nice data oriented programming paradigms. As a gameplay systems designer the way DOTS works is how I think about my game entities. Inputs, processes and outputs. It’s very pure.

For me this is enough reason to use it and also figure out some headaches with hybrid where necessary

gusty comet
#

Yea - I'm just not sure what the dev's vision for DOTS is. Are they putting up Hybrid ECS as the defacto standard for DOTS or are they going to push along a pure ECS option. Right now, can we even serialize entity data without Hybrid ECS? And I don't believe we are able to place entities directly in the scene

lusty otter
#

One of the reasons to use ECS is that it better takes advantage of Job system and Burst though

#

As I see it, most issues of ECS stems from this whole conversion workflow.

gusty comet
#

Yea - my concern is that it may turn out that ECS is only advantageous in applications that take advantage of the jobs system and burst. And not all applications do. Theoretically, it should be advantageous in all scenarios but if the conversion process is responsible for my decreased performance on that tutorial...programmers may need to sort out which applications are suitable for DOTS and which are suitable for Monobehavior - not use one for everything.

lusty otter
#

If Unity was to be rebuilt from the ground up (unrealistic) with ECS I don't think things would be nearly as chaotic as they are now.

safe lintel
#

im skeptical of a 50% reduction in performance even without multithreading

#

does this have two final projects to compare with? as i cant really be bothered to actually walk through it

gusty comet
#

I believe it has a final project in the download

safe lintel
#

also does the tutorial mention that there is a large performance delta between mono/dots and dots being lesser of the two?

gusty comet
#

And then there's two scenes, one with ECS and one without

#

The tutorial author responded to another comment of someone else saying they got slower performance with "Well it shouldn't"

#

So I'm not sure if it depends on the user's hardware or if the tutorial author simply didn't test it and made assumptions that it would be faster

#

Either way, the author is under the impression that using ECS will result in performance gains, not losses

safe lintel
#

alright will check it out in a bit

tawdry tree
#

Just gonna point out that ECS does not automagically give you more perf. It's complicated, as always. Any number of hardware, firmware, and even software differences can change up results.
Either way, where DOTS excel is:
-When many things do many things
-And you let it parallelize
If one or none of those fit (you already said no parallelism), you might have better perf using GameObjects and MonoBehaviors.
Of course, a simple project does not give you much meaningful information compared to a real project, with a real, complicated use case.

lusty otter
#

Burst also gives good performance boost in single thread.

gusty comet
#

Right, and if it didn't increase performance I wouldn't be concerned. My concern is that it seemed to heavily decrease performance. Thus, I wonder if we should all be steering clear of pure-ECS projects and instead think of ECS as something we should only consider using when we would expect it to have a noticibly positive impact on performance

#

IE the physics system would benefit heavily from DOTS, a button that opens a door would probably not. Use Unity's new physics DOTS system for the physics but use monobehaviors for the door and button

#

To be fair, I am not very familiar with the burst compiler so that aspect of DOTS is not something I've really explored in detail

lusty otter
#

My argument for ECS is that, projects that are big enough to worry about performance are usually the ones that fit the "many things do many things" point and can gain significant performance, and the others shouldn't have performance issue to begin with, even if ECS did have a performance penalty (who cares if your cookie clicker game runs at 300 FPS instead of 400)

tawdry tree
#

If you have an existing project, or even if you're making a new one, my recommendation at the current time is not to go for the full DOTS and ECS, but rather to jobify and burstify particularly heavy code.
That should give you a decent chunk of the potential performance gains while being familiar(assuming you already know your way with GameObjects), and also not having the gaping holes for certain features like ECS does.

#

The exceptions are if you want to learn/play around with ECS, or if the paradigms/design patterns sound themselves sound useful to you.

gusty comet
#

That seems to be my thinking at this time @tawdry tree.

rare umbra
#

Is it true that ECS can’t serialize component data? Given that they’re just structs?

tawdry tree
#

What do you mean ECS can't serialize component data?

gusty comet
#

Well if you're using hybrid ECS you can serialize the data on the gameobject before runtime and at runtime it is converted into an entity. I'm not seeing a way to serialize data on a pure entity that was never a gameobject

rare umbra
#

I was just quoting what @gusty comet said

tawdry tree
#

You can totally get all the components on an entity and serialize that. Or for that matter, I'm pretty sure there are some way to basically serialize an entire World to save it.

gusty comet
#

Easily though? I'm not talking about serializing data on a [GenerateAuthoringComponent] that is then added to a gameobject. Of course that can be easily serialized

tawdry tree
#

You're gonna need to write some infrastructure code to do it, but entities are just containers of components, so it stands to reason you could grab all components an an entity and serialize that.
The harder/more complex part would likely be deserialization and spawning them back in...

gusty comet
#

Right - I just meant there was no equivalent to [SerializeField] for a PURE entity

#

So if you have serialized fields and don't want to write custom serialize functionality, you kinda have to use hybrid ecs over pure ecs

tawdry tree
#

As long as they're properties you can just use standard .NET features, can't you? [Serializable] on the struct itself, and all data as properties with public { get; set; }

gusty comet
#

I suppose - to be honest I'm not too familiar with .NET - I'm more of a C++ guy

#

C# comes pretty easy from a syntax standpoint from C++

tawdry tree
#

The C family of languages are all fairly similar

#

My point is more that components are just structs.
And structs can be serialized.

gusty comet
#

Does the convert and inject gameobject make a reference to the gameobject property in the entity?

tawdry tree
#

The GO keeps a ref to the Entity, but i don't think the opposite is true

#

I know you can get the Go from an entity, though

gusty comet
#

Interesting - that seems like that may be what I need. I could make enemy entities but also have the player be both an entity and a player so I can run code that is common between enemies and the player through ECS but still be able to throw on monobehaviors to the player for player-specific tasks, correct?

tawdry tree
#

Sounds like it might be easier to just have the player logic in ECS, but yes, that should be possible.
(assuming I understand correctly - you want player to be hybrid to let common Player/Enemy logic apply to it, but primarily be a GO for MB)

gusty comet
#

well so basically, I'm thinking that things like raycasting to check whether characters are on the ground or not could be done through a System on the player and NPCs. This could be split off into several threads to improve performance if I have thousands of characters constantly raycasting to update their distance to a floor. Things like health regeneration (assuming all my characters regenerate health over time), could also be done through ECS w/ multithreading. However, things like the player picking up an item, wouldn't necessarily benefit from multitasking so why run that through a system

tawdry tree
#

Short answer: Because it's easier to keep things pure ECS.
Longer answer: if you did that you'd make it singlethreaded and the system would be very basic, doing none of the +perf things

tawdry tree
gusty comet
#

Thinking about it further....my lack of performance on that tutorial cannot be blamed on Hybrid ECS converting gameobjects to entities. Because #1 this is only done once on the prefab and then it spawns entities from an entityprefab so there's only one conversion per wave spawned and #2 the performance drop is based on the number of entities performing tasks vs the number of gameobjects performing the same tasks (though written through monobehaviors). It's not like I'm getting lagspikes on new waves

So, I have no idea why I would get less performance with a large set of entities vs a large set of gameobjects, when not using burst and jobs

rare umbra
#

@gusty comet you’re working on an open world game, right? Best optimization would be to use a loading ring πŸ™‚

gusty comet
#

πŸ™‚

#

All I can think of is that looping through all of your entities searching for ones that contain certain parameters and/or tags on several different systems is just not efficient in a singlethreaded scenario. The alternative, monobehavior, way simply calls the update() function on every game object every frame - there's no conditional check to see what it's parameters are and you're not performing this check multiple times per frame for each implementation

#

I know the developer of Factorio tried to convert his project to use ECS entities one time and did not see a positive performance impact

safe lintel
#

ok some things

#

first of all, i commented out the FXManager createexplosion code for both ecs and non ecs and just did a quick build of each scene, both pretty much the same fps in a build. entities has overhead in the editor that you cant disable so checking perf in a build is the best way to measure performance(not sure if you did that).

#

second, that version of entities is pretty old and using ComponentSystem which is deprecated now. theres no burst usage at all in the project(but it is used by hybridrenderer and inside the project) which is really like the second part of the wombo combo of what gives dots its performance(the third being jobs).

north bay
#

Any guess when the next entities version will drop? I'm really looking forward to burstable systems. Did any of you already try the itnernal ISystemState out? I ported one of my systems that runs in client prediction to it and the performance gains were crazy (from 0.5ms to 0.06ms)

safe lintel
#

seems like they release something every 2ish months? iirc joachim mentioned q4 for next release

odd cipher
#

burstable systems? πŸ€”

gusty comet
#

@safe lintel Interesting - I would update the discord's wiki then to not recommend this tutorial if ComponentSystem is depreciated

#

Whoever is in charge of that πŸ™‚

spark glade
#

What's a space efficient "bit flag" data type i can use in IComponentData? Basically want a couple bools, like "attacking", "idle", "death", "charge" and not use 6 actual bools.

#

I could roll my own ofc, but wondering if there's something off the shelf

zenith wyvern
#

There's BitField32/64/128/etc

#

Or FixedList<bool>

safe lintel
#

@gusty comet i think the two guys who wrote the majority up stopped working with dots πŸ˜… there are some bits of that wiki that i disagree with but im a bit too lazy/passive to bother changing. you are free to edit it though, should be open to changes

zenith wyvern
#

Yeah that wiki is a bit weird. Strange tone for a wiki. The best resource for learning by far imo it the ECS samples and manual

safe lintel
#

agreed, it can be self loathing and a bit adversarial lol

#

(though those things do kind of go hand in hand with my experiences)

zenith wyvern
#

Fair

zinc plinth
#

@spark glade use an enum with bit values and a int64 ?

low tangle
#

wikis are meant to be written neutral without agenda

warm panther
#

What's the difference between AddInputDependency and AddInputDependencyToComplete in BuildPhysicsWorld (DOTS Physics 0.51-2)?

#

I have a set of systems that must run before or after Physics, but not during.

I thought I do it as follows:

        protected override void OnUpdate()
        {
            Dependency = Entities.ForEach((ref Translation translation, in FloatingPosition floating) =>
                {
                    translation.Value = (float3) (floating.position / Scale);
                }
            ).ScheduleParallel(Dependency);
            
            buildPhysicsWorldSystem.AddInputDependency(Dependency);
        }

But that throws:

#

(also, is this the old problem of dependencies, even in fixed time step simuulation system group, overlapping frame boundaries if you don't also build a dependency from the end back to the BuildPhysicsWorld?)

#

I really, REALLY struggle to understand this dependency management. I really want to run a system after another system is finished, and only then. (and I guess I don't want that first system to not start again before the other is finished)

#
       protected override void OnUpdate()
        {
            Dependency = JobHandle.CombineDependencies(endFramePhysicsSystem.GetOutputDependency(), Dependency);
            
            Dependency = Entities.ForEach((ref Translation translation, in FloatingPosition floating) =>
                {
                    translation.Value = (float3) (floating.position / Scale);
                }
            ).ScheduleParallel(Dependency);
            
            buildPhysicsWorldSystem.AddInputDependency(Dependency);
        }
#

This doesn't solve my problem at all though.

warm panther
#

A possibility is - I'd say they should run between EndFramePhysicsSystem and EndFixedStepSimulationEntityCommandBufferSystem but I have not the slightest idea how to do this. (a good primer on the way these magical dependencies are supposed to work would be really helpful - I can't glimpse it one bit from the documentation, which is odd, what am I missing here?) Also, the ECBS doesn't even have input dependencies... how does THAT know when it can run and when it cannot?

#

(between ExportPhysicsWorldSystem and EndFramePhysicsSystem is also an option)

#

But... that gives me, with this code:

protected override void OnUpdate()
        {
            Dependency = JobHandle.CombineDependencies(exportPhysicsWorldSystem.GetOutputDependency(), Dependency);
            
            Dependency = Entities.ForEach((ref Translation translation, in FloatingPosition floating) =>
                {
                    translation.Value = (float3) (floating.position / Scale);
                }
            ).ScheduleParallel(Dependency);
            
            endFramePhysicsSystem.AddInputDependency(Dependency);
        }
#

What am I getting wrong, I read this code as:

  • this system's job has a dependency on the output of ExportPhysicsWorldSystem, meaning it will run not before Export Physics World is complete.
  • EndFramePhysicsSystem is dependent on the output of this system's job, meaning it won't run before that's completed.
  • EndFramePhysicsSystem informs (in its own OnUpdate) BuildPhysicsWorld that it can't start before it is completed.

So where's the gap in my logic?

warm panther
#
    [UpdateAfter(typeof(ExportPhysicsWorld))]
...
    [UpdateBefore(typeof(BuildPhysicsWorld))]

So I guess we still need those, regardless of job dependencies? Why? And why can't this system express the dependencies that are needed, then? What does it actually express?

rancid geode
#

The Attributes are used to manage the order that OnUpdate gets called, the dependency stuff is to manage, well, the dependency

warm panther
#

Makes sense.

rancid geode
#

They are separated things, but yeah, in case of physics they usually are needed together

warm panther
#

That stuff needs a visual editor. πŸ™‚

rancid geode
#

For sure haha

warm panther
#

So when do I use BuildPhysicsWorld.AddInputDependencyToComplete() vs. the other one?

signal flicker
#

hey guys, i have an AI that uses raycasts to see. each AI does 5 raycasts. My project would slow down when i added alot of AI, so i decided to try out the jobs system to handle the raycasts. when i implimented it, it didnt improve my FPS at all, even though its using the new raycastcommand and job scheduler. any idea whats going wrong? (posting code soon)

#

its worth noting that the slowdown goes away when i comment out

JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle));
handle.Complete();
#

meaning the slowdown isnt coming from the data collection functions, just the raycasts themselves

karmic basin
#

You sure you want to complete right away ?

JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle));
                handle.Complete();
#

that doesnt make sense to me, you're losing the batch scheduling

signal flicker
#

handle.complete() just waits until all the commands are done, no?

karmic basin
#

you're telling the job to execute immediately in this thread, thoug you asked for multithreading the line above.
Basically you're creating a sync point, the script will stop there and wait for the job to complete before executing the next line

signal flicker
#

well i want the job to finish before attempting to read the result array

karmic basin
#

You might want to have 2 systems maybe (didnt really read all the code because the textfile), one that's cast rays, another one that have a dep and reads results later

signal flicker
#

by later do you mean on a later frame?

#

i call the sight function every server tick

#

each ai does 5 raycasts to each of the players on the enemy team

#

so if there are 3 enemies, he will do 15 raycasts

karmic basin
#

I meant 2 jobs, not 2 systems sorry

signal flicker
#

the code tells each of the ai to do the first of the raycasts to each enemy. if the ai spots the enemy, it doesnt do the second raycast to that enemy and so on

karmic basin
#

let's say "CastVisionRaysJob", scheduled in parrallel, then a for example a "ReadVisionHits" Job, that have the first one as e dependency

signal flicker
#

so it would run async with the rest of the code?

#

i dont think i want to do that cause i need to call the sight function every tick

#

is the way im setting it up not using extra cpu threads?

#

with 20 AIs its doing about 1100 rays per tick

#

and 60 ticks per second

solar turret
#

Hi guys, question with DOTS and camera's.
I'm working on a spaceship battle project, but I cant seem to implement a good chase camera without jitter.
I have tried to work with a ECS camera and run all movement system before the camera and a gameobject camera in late update, but I seem to have a constant jitter also when creating a build.

#

Does anyone have an idea of how to resolve jitter with a chasing camera in Dots?

gleaming plank
#

How are you rotating the camera currently?

solar turret
#

Like this:

Quaternion targetRot = entityManager.GetComponentData<Rotation>(entityTarget).Value;
transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, rotateSpeed * Time.deltaTime);
gleaming plank
#

Try replacing Quaternion.Slerp with Quaternion.RotateTowards.

#

The third argument to slerp is "what percentage to move from current to target", not a rate.

solar turret
#

The camera rotates a lot different, but the jitter still is just as present.

#

I did leave the third parameter the same as I also saw it being used like this in the Unity Documentation

gleaming plank
#

Oh, that's weird. Is targetRot what you want the camera rotation to be or is it the rotation of some target entity that you want the camera to look at?

solar turret
#

Yes, its the rotation of the target entity

gleaming plank
#

Okay, so the transform here belongs to the camera and you're having it change its rotation to match the target entity's. Is that right?

solar turret
#

Yes that is correct

gleaming plank
#

Hmm, is the target entity's rotation jittery? The camera rotation could be jittery by proxy if the target entity isn't smoothly rotating.

gleaming plank
# signal flicker meaning the slowdown isnt coming from the data collection functions, just the ra...

So calling Complete() doesn't make the job run faster, like you've noticed it just stalls the thread until the job is finished. I think the issue is that you've buried this raycasting job inside a loop, so you're stalling the thread every iteration. What you want is to collect all RaycastCommands for all the AIs and then ScheduleBatch once. Ideally, you also jobify and schedule the entire dependency chain and defer calling complete on the final job until you need it (like Mr.K was saying).

solar turret
#

It could indeed be that the problem lays there

coarse turtle
#

I'd look at the profiler timeline view since it provides a rough idea of when the threads are executing, are the jobs running/completing while the main thread is idling?

karmic basin
#

@solar turret you're updating the cam rotation to match the entity rotation, but because you're updating the entity rotation value, the wanted rotation for the cam keeps getting changed. I would try to cache the targetRotation value in another var instead of being read directly from the component Value. maybe have the cam job updateAfter the entity one.

gleaming plank
#

Are you able to place a camera on the target (or is the target the ship)? That'd probably be the easiest way to see it, but you could also try logging how much the target rotates every frame and check if that delta fluctuates unexpectedly.

#

If the target doesn't change and targetRot itself is being smoothly rotated by Slerp or RotateTowards, and you just want the camera to always match it perfectly, you could just set the camera rotation equal to that rotation.

solar turret
#

Just tested it and yes, the target entity(in my case the spaceship) does jitter

signal flicker
#

trygetcomponent(out c) fixed it

gleaming plank
# solar turret Just tested it and yes, the target entity(in my case the spaceship) does jitter

So if the camera never changes its target from the ship, one thing you could do is fix jitter on the ship (might be as simple as changing Slerp to RotateTowards) and then either 1) Set the camera's transform.rotation = targetRot (or vice-versa) or 2) Give the same target rotation to both the ship and the camera and have them independently rotate towards it (useful if you want them to rotate at different speeds).

solar turret
#

Thanks that does seem like a good solution πŸ™‚ I'll try them out!

odd cipher
#

I've asked this before but haven't found a solution yet, How would I access specific indexes of a buffer in a parallel job? Burst doesn't like it.

karmic basin
#

Yeah should only be able to write to Native Containers

#

But still you should be able to read

#

You tried to access index like an array ?

odd cipher
#

yeah like this buffer[0]

karmic basin
#

and how do you assign your DynamicBuffer ?

odd cipher
#

I do a loop on every entity in onstartrunning to add some to the buffer

karmic basin
#

arlight and at this point you set by index and tht works I assume

#

it's a IJobParallelFor ?

odd cipher
#

that's what doesn't work. But I've encountered a different problem. The loop I mentioned doesn't seem to work anymore..

karmic basin
#

hehe you might have tried tweaks and mixed things up

odd cipher
#

Maybe, adding a EntityCommandBuffer ParallelWriter to my update loop breaks the onstartrunning loop.

#

not sure how

karmic basin
#

you tried to add to the buffer after adding it to the ECB ?

#

I meant in another job, not after

#

You cant reach it in this case I think

#

until ECB executes

#

COuld be wrong I still get confused by those, not used them enough

odd cipher
#

Hm, I'll try a different way to do the loop. I imagine I can remove it and instead just use a Authoring Component.

karmic basin
#

Native Containers might be easier

#

just a little bit higher level

#

that might be easy enough :p

odd cipher
#

No, they have to be buffers.

karmic basin
#

what are you storing ? You said entities ?

odd cipher
#

I'm attempting to create a neural network, so I'm storing neurons in buffers.

karmic basin
#

inputs and outputs ? 0s and 1s ?

odd cipher
#

It's a bit more than that since each element in the buffer has an activation function and so on. Plus it's 3 buffers, one for inputs neurons, one for hidden neurons and one for output neurons.

#

It's quite complicated but it seems to work fine right now.

karmic basin
#

Dont know what type your T would be but do you Reinterpret<T>() to access your buffer ?

odd cipher
#

No

#

But I think I realized something. I'm pretty sure I'm not doing the correct entitycommandbuffer method to set a certain buffer element in a buffer.

#

I'm not sure what the correct one is, there might not be one?

karmic basin
#

ecb.AddBuffer<T>()

#

oh no thats not what you mean

#

let me re-read your sentence

#

xD

#

Im not even sure I understand what you're trying to achieve

#

but you should be able to .Add to your DynamicBuffer after .Reinterpret<T>()

#

and for IJobChunk it's different because you get all buffers (from all entities)

odd cipher
#

I guess I would be able to avoid using a commandbuffer then? I thought I'd have to use it.

karmic basin
#

Yes you have

odd cipher
#

?

karmic basin
#

that's true you add your buffer to the ecb

odd cipher
#

I'm not sure how that would work, Adding a buffer is not the same thing as changing a specific entry in a buffer. Not sure if we are on the same page or not lol.

karmic basin
#

its like asking the ecb to add/set/remove components on entities

#

you add your buffer to the ecb, then add to it or update it, then it will be resolved when the ecb executes

#

and I think you cant touch it anymore until that point

#

but you can copy values to a native container and use them in another job for example

#

but I dont know what's your use case is really

#

I hope I'm not confusing you :/

odd cipher
#

Hm, I'm not sure if we are talking about the same thing, if we are then I just don't understand. Are you talking about the start loop or the loop I have in update?

#

I figured out why the buffer was set to 0 because of the commandbuffer, I thought calling SetBuffer on it would somehow change it but it just sets it to a buffer with zero things in it, thats why I need to know a different way to set a specific entry in the buffer with a commandbuffer. If you understand what i mean.

karmic basin
#

Yeah SetBuffer is like a Clear() for lists

odd cipher
#

Mhm, for some reason I thought it wasn't. That was the problem I had but now it works fine except I need a different way to do what I want to do :p

karmic basin
#

SetBuffer returns the DynamicBuffer

#

try to .Reinterpet<T>() it, then .Add() ?

odd cipher
#

That would still clear the buffer no?

karmic basin
#

oh you dont want to SetBuffer then ?

#

wanna share a few lines of code ?

odd cipher
#

One moment

#

It looks like this ```csharp
InputNeuronData data = inputNeuronData[0];
data.neuron.value = healthData.energy;
// update buffer?

I'm pretty sure I need to update the buffer atleast, lol.
#

the InputNeuronData buffercomponent consists of a Neuron struct.

karmic basin
#
public struct InputNeuronData : IBufferElementData
{
    public float neuron;
}

Like that ?

odd cipher
#

Yes except that the neuron variable is not a float, rather a struct. Which is why the buffer itself needs to be updated.

#

I think... lol

karmic basin
#

and what job Interface you're using ?

#

IJobParallelFor ? IJobChunk ?

odd cipher
#

It's an Entities ForEach.

#

Parallel.

karmic basin
#

oh okay

#

syntax is even simpler

odd cipher
#

I've had problems with me wanting to change the buffer and that creates problems because that foreach loop constantly edits it aswell. So I thought a commandbuffer would fix that.

karmic basin
#

but you can't write in parallel

#

only with .Run()

#

otherwise use a Job

#

yeah should be a referenec so you mutate values yeah

karmic basin
odd cipher
#

lol well, I'm not exactly sure on how to explain it further, I'm changing every entry in the buffer in my update method. And occasionally I want to edit that buffer from a different system as well, but that clashes with the other system.

karmic basin
#

make sure the second system executes after the first ?

#

and after the ecb

#

in the other job you use BufferFromEntity<T>() ?

odd cipher
#

Oh yeah, that makes sense, however I'm still not sure how to set one entry in a buffer in a ecb.

#

No it's a ForEach aswell.

karmic basin
#

with E.ForEach it's more simple, you can access the DynamicBuffer like a component, in your query, if the queried entities have the buffer on them

#

but yeah, only .Run()

#

with the ecb you can do it in parallel but you have to do it immediately

odd cipher
#

I would like to do it parallel, if possible.

karmic basin
#
Entities.ForEach( () => {
    DynamicBuffer<InputNeuronData> buffer = yourECB.AddBuffer<InputNeuronData>(yourEntity);
    DynamicBuffer<T> neurons = buffer.Reinterpret<T>();
    neurons.Add(new ([...]));
}).ScheduleParallel(); // you can do parallel here
#

I would try smthg like this

#

Don't know if you can use struct for T, will there be a circular reference because it's a struct of struct ? Never tried 🀷

odd cipher
#

Ah so you create a new buffer every update?

karmic basin
#

I dont know what you need but you can query .WithNone<InputNeuronData>

#

if you only need to add once

odd cipher
#

Interesting, I'll try it

karmic basin
#

Hopefully I understood what you need, sorry if not πŸ˜›

#

If the Reinterpet thing doesnt work, try to set directly buffer[i].neuron, I dont see why it wouldnt work as long as you do it in this lambda

odd cipher
#

Yep, it works, not exactly the way I was thinking of doing it but it does work.

karmic basin
#

Great

odd cipher
#
DynamicBuffer<InputNeuronData> buffer = ecb.SetBuffer<InputNeuronData>(0, entity);
DynamicBuffer<Neuron> neurons = buffer.Reinterpret<Neuron>();
neurons.Add(new Neuron(0, NeuronType.INPUT, ActivationFunction.LIN) { value = healthData.energy } );
neurons.Add(new Neuron(1, NeuronType.INPUT, ActivationFunction.LIN) { value = closestFoodDistance } );

It does make it so you have to recreate the neuron with the arguments and so on and it would be nice to avoid that but not sure if you can.

karmic basin
#

You mean yo already created them earlier and don't want to repeat them here ?

odd cipher
#

Precisely.

#

I only want to change the 'value' variable.

karmic basin
#

(So in the end you keep .SetBuffer to reset it)

odd cipher
#

Yeah that's what I have to do with how this works.

#

I only want to change the 'value' variable so recreating the entire thing every time seems like something you should be able to avoid?

karmic basin
#

I showcased .Add but you should be able to loop and assign a new .value at index i

#

or neurons.ElementAt(i).value

karmic basin
odd cipher
#

Yeah that's what I thought you misunderstood :p

karmic basin
#

erf :p

#

where you want to access it then ?

#

From another entity ?

odd cipher
#

in the update method, but what you just said works great.

DynamicBuffer<Neuron> neurons = inputNeuronData.Reinterpret<Neuron>();
neurons.ElementAt(0).value = healthData.energy;
neurons.ElementAt(1).value = closestFoodDistance;
karmic basin
#

or the neurons are available in the query ?

odd cipher
#

This is very much what I was looking for.

karmic basin
#

ok great. I misunderstood again then, because I thought we were wiping the buffer and that was useless :p

odd cipher
#

Mhm

karmic basin
#

sorry to make it difficult :p

odd cipher
#

Nah it's fine, it took a while but eventually we got there :)

#

Now I'll just have to convert all my other code to use this instead..

karmic basin
#

Awesome, happy coding

rare umbra
karmic basin
#

@rare umbra SHould be new input System

#

com.unity.inputsystem

rare umbra
#

Yeah I’m doing this
β€˜using UnityEngine.InputSystem;’

#

Finds the rest of the classes in the sample but not Controls

karmic basin
#

oh πŸ€”

rare umbra
#

Wondering if Controls is a custom class or if it’s part of that system because I can’t find references to it online

safe lintel
#

looks like a custom class

karmic basin
#

yeah maybe an helper class haha

safe lintel
#

could be the codegen class that input system can create from your input mapping

karmic basin
#

sounds legit

rare umbra
#

Ok so just need to figure out how to run the code gen for my input data πŸ˜„

karmic basin
#

when you do the mapping from the editor I assume ?

safe lintel
#

its your inputactions file

#

theres a tickbox to generate the class

rare umbra
#

Aah cool will check it when the little one has gone to bed

safe lintel
rare umbra
#

I think I did see a project for input in VS

safe lintel
rare umbra
#

Yeah I have some actions defined, guess I’m not doing codegen or I need to switch Controls with a class it’s actually generating

rare umbra
#

This seems incredibly long winded compared to what Sark wrote. Though I guess that’s just because I don’t understand it πŸ˜„

safe lintel
#

its not so bad, though the new input system is definitely more complex than the previous one.

#

it will make sense when you dive into things πŸ™‚

rare umbra
#

I guess if my understanding is correct it’s registering a bunch of callbacks within the system and then each time a control input is updated it updates a local variable which is then used to set the data on a component?

safe lintel
#

yeah

rare umbra
#

Yeah don’t think I need to store that data on a component. I can just grab it each update of the system like in @zenith wyvern’s example

#

Not doing much yet that needs to simultaneously read that data

zenith wyvern
#

Yeah "Controls" is just the codegen class from the Actions asset. There should be some okayish documentation on how to use it

#

So in my example the "Controls" was the actions asset and "Default" was one of the action maps

rare umbra
#

@zenith wyvern thank you! turns out I wasn't generating the code - doh!. Seems to be working mostly... translation changes when I do +=1 but not so much when I change that to be a product of movespeed and delta time. Now trying to debug with break points, but they're not being hit. Is it possible that anything in a Entities.ForEach can't be debugged with breakpoints?

zenith wyvern
#

I don't think burst can be. If you use WithoutBurst it should work

empty reef
#

Guys, i want to use ontriggerenter (player with sphere collider) to many object (dots collider) and destroy it, how to make collider but only a dot ?

agile dome
#

@empty reef Don't cross post. I deleted the other one.

empty reef
#

Yea sorry, i thought there's no dots channel :)

rare umbra
#

I guess I could wrap my OnUpdate code in a check of _controls.InGame.enabled

spark glade
maiden delta
#

how do you create joints in dots unity physics?

odd cipher
#

@karmic basin I have a question about what we did yesterday, How would you make this work with monobehaviours? I want to have a button that adds something to a buffer but that clashes with the update loop that constantly changes the buffers. I suppose I could have the monobehaviour add a component to the entity and a system to run after the other system which updates on those components to add a buffer, somewhat like a queue. If you get what I mean.

#

So the systems never clash with each other.

karmic basin
#

Yeah you can access entities package from MBs (EntityManager, systems, queries, ...)
Straightest way would be through the EntityManager I guess. Grab a reference to your world's EntityManager + your Entity and then
DynamicBuffer<InputNeuronData> dynamicBuffer = EntityManager.GetBuffer<InputNeuronData>(entity);
But then yeah what about sync points... I never tried to mess with buffers in hybrid. You're right you might fall into race conditions so your idea of a queue component looks good. But I would not run it after the one that adds to the buffer, because between the adding part and the ECB (when it executes) you can't touch it. I would just add the queue component in the query lambda and add the Neurons at the same time you do the others. Or if really want to split to another system, use [UpdateAfter(typeof(yourECBSystem))] and not before

#

But that's strange you need to add from MBs AND from Systems

#

so you need to store them in 2 different ways, I don't like that, there might be a better solution I don't see yet

#

Thinking out loud here, you could also access a native container of your system from the MB instead of components, at least you dont mess with structural changes on your Entities

odd cipher
#

Got it πŸ‘ I'll try to do something like the queue thing I suggested.

gusty comet
#

hey guys i was wondering if theres any overhead with using the conversion workflow compared to just using dots normally?

amber flicker
#

performance overhead? Quite the opposite - conversion is designed to make everything a blob of data that can be loaded pretty much directly into ram

gusty comet
#

ahh ok thank you

amber flicker
#

Oh I should say, "conversion workflow" to me means at edit time. Conversion at runtime is generally something to avoid.

gusty comet
#

what would be better for 100s-1000s of projectiles? or does it not matter? so i could get away with just using conversion instead of using full on ecs/dots?

coarse turtle
#

well if you just convert the projectile once (as it can be marked as a Prefab entity), you can reuse the entity projectile and instantiate 100s to a 1000s depending on your need

zenith wyvern
#

There is no conversion "instead" of dots. Setting up your entities in the editor using conversion is a part of dots.

#

Or a part of ECS I should say

coarse turtle
#

similarly, you may not even need the whole conversion/Entities workflow, setting up a monobehaviour and using DrawMeshInstanced (or DrawMeshInstancedIndirect) to render the thousands of projectiles is also a feasible way too

amber flicker
#

The same as above put a slightly different way - once you've converted e.g. a bullet prefab, it becomes an optimised binary representation of that bullet - instantiating it is then as simple as a memcpy pretty much (plus consequential chunk activity) so it's pretty optimal.

pulsar jay
#

How would you guys handle mutually exclusive components? E.g. some enemies have a RangedAttack component and some have a MeleeAttack. Is there any way to enforce an enemy to have only one of those or do I have to handle constraints like this through authoring components? In OOP I would have handled this through Polymorphism but this isnt a thing in ECS πŸ€”

amber flicker
#

Just have a Component with an Enum and set the enum (is how I would do it) - tags aren't supposed to be exclusive

coarse turtle
#

yea - also split them into different chunks and have chunk based logic is another approach, so you enforce different enemies to have different archetypes

pulsar jay
amber flicker
#

it depends... πŸ™‚ - on the one hand, it's better than tags because it doesn't fragment your entities so much.. on the other, you lose the query syntax and can't use that fragmentation to only iterate those specific entities

#

this state-machine esque question comes up a lot - there was a recent post on the forums if you want me to find it - there's also the Unity example but it only really applies for very simple states

pulsar jay
#

sounds good. would be really glad if you could find it

pulsar jay
#

its always tricky to decide whether to go for components or enums