#archived-dots
1 messages ยท Page 276 of 1
Looks like an angry cloud about to shoot lightning at me
haha it does lol!
game objects are used for simplicity of authoring
in fact it makes it so much easier to create scenes
and lets you reuse authoring components however you want
yup, and i have no idea how to use gameobjects with them, so for now i wont, although tommorrow morning i will learn how to!
Any idea whether all jobs are reusable?
Can I just assign job to field
so I don't repopulate fields again?
or is there some kind of codegen that breaks this approach?
Never tried. But you can think of a similar approach where you gather your fields in a struct and keep that around
yeah, should work. only handles need to be updated
Do jobs have any sort of code gen related to them?
except IJobEntity ofc
and also ComponentDataFromEntity does it need to be refreshed on each update?
i think for CDFE you need another GetComponentDataFromEntity<T> call. for handles there's Update()
hmm get very weird error
and it points to this line
And I don't get where it can possibly happen
Player 100% has physicsVelocity
or maybe it doesn't?
๐ค
they reduced the character limit from what I saw
spam filter?
no idea, but it's painful
is this one of the job structs that you are reusing?
yeah
I'll try to remake it
oh wait
nvm
me dum dum
passing Entity.Null
as player entity
lol
just keep in mind, as soon as you set a new value on the player entity the version changes so your job would have an old player entity. i dunno, reusing a job with entity fields sounds like a bad idea
it's fine, it reapplies field on every OnStartRunning
which is triggered by singleton player
kek
there could be still a case where OnStartRunning is not triggered and there's a change on the player entity. reusing job structs is really not worth it other than opening up yourself for some weird problems.
I currently have some data in a grid that I am storing in a large dynamic buffer on an entity, and then reading in jobs. for example, the height value of a certain position. There's a few other values I plan to store here, such as the biome. However, not all jobs plan to always read all of this data.
Now I'm kind of torn between only putting single values in each buffer (e.g. 1 buffer for height, 1 buffer for biomes), and each job retrieving the buffers it requires, or just putting all of the values in a single buffer (there is some overlap where multiple values are required, e.g. many jobs require the height and biome at once).
the design itself is bad tbh (random access) so it'll not matter if you put 1 or 5 fields in a buffer element when you profile
but if you want to continue with this, put as much data as possible in it to at least reduce the amount of random access
personally I'd redesign this to a hashmap
How does a hashmap make it not random access
Also the access inside of a job is spatially related, meaning it will (hopefully) be in the cache after the first access
I feel like a hashmap will be even slower, since I will just be mapping all grid positions non-linearly, and require an additional hash calculation for each access
Also this isn't really true, since less data in the buffer will mean more can fit into cache
I'm not following. What's your internal buffer capacity? From what you wrote you have a large buffer so it won't be in the chunk.
Are buffers handled differently if they exceed the chunk capacity?
Basically I'm just caching some data in array form, but it's easier for me to store it on an entity to access in a job. It's also not super huge at ~1024x512
if you don't set any capacity, the default is 8 and will allocate memory in the chunk. if that exceeds or the internalBufferCapacity is set to 0 it'll be a randomly allocated array and work just like a list
so, yes, they work very differently when exceeded
I mean if I didn't have it on an entity I would be storing it in a nativearray on a system, I don't see how that would be any better
the bad thing about it, even if they are allocated in the chunk, their performance is underwhelming
Why?
I don't know exactly, mostly overhead and the sum of things. are we talking about 1 buffer or several?
usually 1, max maybe 5 for a single save game
and you have direct access because you know the index?
Access is based on world position
So e.g. for pathfinding I would access the buffer based on whatever node is currently being searched
and what's the method of finding the correct node?
WorldPosition / ChunkSize
And then transforming that 2d position to a 1d array index
ok, so the answer is yes, you have direct access by index. in that case, I'm sorry, it's okay what you're doing. to get back to your question, you can put as much data as you want in an element. it's just some pointer arithmetic when you have more fields in the struct. hardly any performance loss. getting to the right memory address though is pretty hefty with lots of access from jobs, so if you stay mostly in the same memory space it nets better performance than splitting up the data in several smaller arrays
and if you don't believe me (you shouldn't ๐ ) -> profile
I don't have massive performance requirements like you, I just like talking about these things to learn and see what others would do
you have enough performance requirements to use dots ๐
I'm using it because because I wanted to learn something new, and I can write a chapter about it in my masters thesis since it's more interesting than "basic OOP setup #1023"
i never had much success with splitting data in general. splitting data is really only worth it if you can vectorize code through it
Also it's much nicer for networking than something like mirror (at least I like it more)
the tighter you pack the memory the less the cpu has to jump around in memory and if you get really low level, this is where it's at
we like to think about cache lines and all that but that's mostly machine stuff
I still don't see how this can be true since that would mean there is a significant difference between a nativearray and a dynamicbuffer
Since I'm using the same interface to access them
in how they act, they are very different. a nativearray is always just a block of unmanaged memory. pointer and length. a dynamic buffer can be reduced to the same thing that's why AsNativeArray is a thing but a DB has the ability to either store the data in the chunk or outside of chunk memory. it has also the ability to act as a list, that's why you can add more elements which a NativeArray can't do. as long as the chunk can fit the DB data it will stay there, once it exceeds the chunkSize a new block of memory will be allocated, just like a list and copied and moved there. the data that will always be static and stay in the chunk is that a DB has a pointer, capacity and length (like a list).
to get a better feel for that. try a [InternalBufferCapacity(n)] tag on an IBufferElementData. set it to 0 and you'll see 144 allocated bytes as minimum in the archetype. pointer, length, capacity and something I forgot. set it to 4, 8 or smth, the additional sizeOf the struct will be allocated. also a reason why I don't like DBs because they take away a huge amount of data from the chunk
I guess it's a tradeoff, memory for speed. How else would you store multiples of some data that belongs to an entity?
well that's the thing. you trade memory and speed when the data is in the chunk. you'd think that it's great design that the data of a DB stays in the chunk. sounds really fast! right? well it isn't, because it's using pointer access and that trips up any compiler. it doesn't know that the data is just around the corner. so even the whole cacheline thing won't help. also a reason why many, tertle and me included are suggesting to set the InternalBufferCapacity to 0 when the size is unclear. If it's totally fixed an IComp with pinned ptr to the first element and index access is much faster. arrays belonging to entities is the biggest problem in ecs design. the best solution I've found is to use the same entry point for the array, that's speeding things up by a lot. once the cpu knows that you're accessing the same array over and over again timings go down by a lot.
I'm mostly finding reasons for what I've measured btw. even if my reasons are wrong (I don't pretend to know every little detail) the performance characteristics are 100% true
Very interesting, thanks for the write up. I assume something like a fixed array would be much faster then
Ah you wrote that, I just missed it
the best solution I've found is to use the same entry point for the array, that's speeding things up by a lot.
By this do you mean use the same base pointer and then offset from that?
yes
Would it be enough to get a DB, cast as native array and index it? Or is it doing something else under the hood
e.g. get a pointer to the first element and then index off that (DynamicBuffer.GetUnsafePtr)
there's a lot of overhead to get the DB pointer which can't be optimised that well, so a plain native array would be better. once you have the ptr and length a DB and NativeArray is 1:1
also a good idea would be to cache the DB ptr/length in every way possible to reduce this lookup
Kind of an issue if the DB can change though
right, I don't mean cache it over many frames. just in one chunk iteration for example or on job schedule
Ah, alright
I guess for a lot of these things it depends on whether or not you are actually bottlenecking on these things. I don't doubt it's a performance issue, but it feels overkill to do this for every DB
But it's nice to know if I ever run into performance issues
I'm 100% sure, the most performance issues in ECS right now are coming from DBs. They are just so convenient to use ๐ I've replaced many different kinds of DBs now in my project and I'm 80% sure that every DB can be replaced with another NativeContainer.
I mean yeah you could stick an UnsafeList inside a component, I guess the "useful" feature is the automatic cleanup
most recent example, every entity/npc/player needs to know with which entity it is in combat with. could be 0, 1, 250k ๐ very basic thing but I need to check with new combat events if the entity is already in combat with the other entity, otherwise I'd have lots of duplicates. my first try was with a DB and calling Contains(Entity) so a linear search. perf tanked to 8seconds a frame. then I used tertles dynamic hashmap, MUCH better, the linear search was now gone but still bad overall. I thought, well, as 250k are attacking 1 target, calling ContainsKey 250k on the boss is expensive but it turned out, the single ContainsKey on the 250k casters was the expensive part due to the random access. I then rewrote it to a hashset and hashmap, slightly more complicated and more involved but that reduced it down by a LOT. sadly I don't remember the exact numbers anymore
I don't see how a hashmap removes random access, the data is not linearly laid out (between keys)
it's random but not totally random is my best explanation. like it's local to where the memory pointer is. the cpu knows where to start and then just access the correct index
But that should be the same for tertles dynamic hashmap. The block of data where the hashmap is stored (a dynamic buffer) is linearly laid out in memory. At the end of the day both should be storing their data in arrays
no, my solution is one long key/value array. the db hashmap is a fragmented key/value array all over the memory.
Why is it fragmented, the dynamic buffer just knows the start of it's memory address, and the length
for the casters, which were so expensive, there were 250k, very small key/value arrays
Ah, you meant you had many dynamic buffers before, and moved it to a single hashmap?
Yeah that makes sense it would be much faster, I thought you meant you had the single hashmap stored on a dynamic buffer
nope, that was sadly not possible with the design. the single hashmap performed, as expected really well
Your original approach would also have been slower even if it was stored as nativehashmaps, and not on a dynamic buffer. close to linear memory access is just much faster than spreading it all over the place
right, and that's the problem when you have many entities and DBs. as long as there are not many entities, all is good but when this reaches a certain point the melting process starts
just something to keep in mind. if you know the pros and cons of DBs they work really well
I also really depends on how many entities you have ๐ I don't think very many games require 250k actors
i mean, the whole point of ecs is to keep random memory access down. hehe, certainly not ๐ I just saw many devs considering grid tiles as entities with a DB so my alarm bells go off
you can basically write OOP code when relying on DBs too much. well, burst helps a little ๐
i am new to using DOTS but i have a quick question, is turning objects to entities improve the performance? my game is a simple lab room, and i have tones of objects in the room like beakers and lab equipments that are there for the environment style only, if i turn them all to entities, would that help ?
If they are just static, then no, it will not change anything afaik.
There is no data being changed.
yeah, for graphics and just a small but detailed scene you don't necessarily need entities. at least not right now because the hybrid renderer is still very alpha
can someone eli5 write groups?
like, i don't understand their usage. to hijack some entities so another system doesn't process them?
allows you to make systems that can be disabled by components that use that write group
you have system that writes to local to world and uses write group filter
if you add any component with write group to LocalToWorld
system will filter that entity
i see, so does this only make sense when i'm not really the programmer of a system or the system is internal and not changeable?
well, it makes sense for a lot of cases
any examples? do you use them?
I personally haven't got a chance yet
unity itself has an example:
when player invincible he doesn't need health color to be calculated
so health calculation system uses filter
and if invincible tag is applied to entity it's filtered
in case you'll have some other component that will be supposed to disable health color system you just add to it write group filter
for example, it can be used to switch into other logic of calculating color
ah thanks, that makes sense
should i dispose blob assets manually?
they are disposed automatically
that depends how you create them
if you simply create one yourself outside of a blob asset store, nothing is magically disposing it
var b = BlobAssetReference<int>.Create(1);
for example
a common case of this is creating your own physics colliders in a system
if you add it to a store
var store = new BlobAssetStore();
store.AddUniqueBlobAsset(ref b);
then when you dispose the store it'll dispose all the blobs
during authoring unity gives you that store for you via GameObjectConversionSystem and handles its lifecycle for you
oh damn, that's new. is this also true when using a BlobBuilder?
Here I am creating and disposing of all of my blobs manually, didn't know blob asset store exists 
shouldn't the leak detection tell me about it? ๐ค
Is there any point to using a blob asset store if I currently already have a system that manages them?
not really
Guess I'll leave it as is then
if you read the blob builder comment
/// 1. Declare the structure of the blob asset as a struct.
/// 2. Create a BlobBuilder object.
/// 3. Call the <see cref="ConstructRoot{T}"/> method, where `T` is the struct defining the asset structure.
/// 4. Initialize primitive values defined at the root level of the asset.
/// 5. Allocate memory for arrays, structs, and <see cref="BlobString"/> instances at the root.
/// 6. Initialize the values of those arrays, structs, and strings.
/// 7. Continue allocating memory and initializing values until you have fully constructed the asset.
/// 8. Call <see cref="CreateBlobAssetReference{T}"/> to create a reference to the blob asset in memory.
/// 9. Dispose the BlobBuilder object.
///
/// Use the <see cref="BlobAssetReference{T}"/> returned by <see cref="CreateBlobAssetReference{T}"/> to reference
/// the blob asset. You can use a <see cref="BlobAssetReference{T}"/> as a field of an <see cref="IComponentData"/>
/// struct. More than one entity can reference the same blob asset.
///
/// Call <see cref="BlobAssetReference{T}.Dispose()"/> to free the memory allocated for a blob asset.```
specifically tells you to dispose it
but yeah, doing conversion whole thing is much easier as you can just pass it to the store
and let the world handle it
Wouldn't I still need to call Dispose on the store when the world itself is disposed?
the store passed during conversion is created and handled by the world
Ah I meant a custom store
yep, I've missed that. so I just create a manual BlobAssetStore, throw the blobs in there and call dispose on the store. should be good then, right?
yes you would just need to dispose the store
thanks for bringing that up then ๐ don't want to have a leak
the big benefit of the store is actually how it works
if you pass in a new blob asset that already exists in the store, it disposes what you just created and then returns the existing store
Yeah I convert a lot of scriptable object data to blob assets for use in jobs, I guess mass disposing of them when the world is disposed might be faster with a store, but probably not worth it
haha
It checks the memory contents to find equality?
are you also having trouble with code blocks?
works for me ๐คท
there's a line limit or smth
Looks like the bot only scans new lines though
So make a small code block then edit it
lol, that's a really dumb change for such a code centric discord
Yep
Something I was wondering about since the 0.51 migration is coming up soon for me I guess:
How exactly does the subscene workflow generate prefab entities? Are all entities that are referenced by scene objects that have an authoring component that points to the prefab created?
I still don't use any subscenes since it was broken a while ago due to some weird UIToolkit error
can you rephrase that question?
well i posted the giant chunk like 2 comments above
Basically, I want to know under what conditions a prefab is converted to a prefab entity
then tried to post 6 lines then and discord just would not have it
I assume if a subscene component references it
oh, yeah, right. that's so weird
i think you should test it, you can view the converted entities in the hierarchy. just make a subscene and put some gameobject in there
I guess I can test it now, I never actually attempted to use subscenes again
I just remember they broke due to UIToolkit or something
they are just converted at editor stage and the whole scene is saved in a nice format for fast reading. the downside of this is that the entity that is created doesn't match the runtime entity index/version
so referencing in that sense won't work unless it goes through patching
most cases should work as expected though, just something to keep in mind when wanting references outside of the entity world
i.e. some monobehaviour wants the entity index/verison
@rotund token thank you for such detailed answer!๐
But it patches it for other components that reference the gameobject?
yes
Hmm, still kind of annoying since I have some scriptable objects that reference prefabs
yeah, those are a problem. I don't have a real solution for that.
Eh, worst case I'll just slap a component on it that maps to the assets guid and then find it that way
I'd be really glad if the editor->runtime would match tbh. It would open up a lot of things that can be done much more elegantly
but that's probably a pipe dream and really hard to do out of the box
I don't think it would even be possible, since you can load a subscene into the world multiple times
yeah, right. there's so much normal cases that would totally break this. maybe some additional call could be made. i just feel like there should be a solution in place for that problem. especially when this whole hybrid GO thing is here to stay for much longer
You mean the conversion workflow or actual gameobjects due to missing features (animation)?
the actual gameobjects. if you stay within entities, references are working great
Ah okay
it all relies on spawners now, although I'm pretty sure that's just a personal dislike and it's actually not a real problem. it's just a habit that I want to have the actual enemy in place and not a spawner. I've written a bunch of helpers to draw prefab meshes so spawners can be seen in the world so it gets better with some tools
I mean you can still just place entities right? Since a gameobject in the scene is just converted to an in-place (non-prefab) entity
it's about the presentation of the entity, the gameobject with the audio sources, skinned mesh renderer, animations, etc...
What does DOTS convert those things to atm?
hm, not much actually. i've not even seen one good example in their repo when it comes to that. the best thing is companionobjects that link the GO and entity but I've not got that working in the authoring stage
unity has us pretty much hanging in the air unless I've totally missed something. from what I know everyone is doing their own thing when it comes to Go presentation for entities
everyone does that right now ๐
Yeah I just never checked if there was some dots native stuff out already
I saw that audio library that dreamingimlatios posted
it was promising with the animations package and then it went dark
I'm working on a graphically very simple 2D game, so I feel like I really dodged a lot of the difficulties with more complex rendering stuff in DOTS
hm, some what. you still need to make the link and manage, sprites, etc... so in some sense it's very similar
How do people handle something like mecanim? Have a monobehaviour that reads the component data and updates the animation controller?
Or the other way around? (system that writes values to animation controller from component)
I mean I guess it really isn't very different from settings sprites via animations...
pretty much that, i have a animation comp that is written to via burst and then a managed system that copies the values to the animator
feels like duct tape overall ๐คฃ
I guess for a 2d game it's at least easier to write a simple animation system that works with burst and jobs
mecanim in dots feels like hot potato coding, โno you deal with this data, no you deal with it!โ Each system continuously passes the buck til it finally gets to the animator
Can you profile timings in burst jobs, or do you need to turn off burst to profile it?
i havent actually had luck profiling specific things inside of jobs but that was a while ago
you mean like ProfilerMarker?
e.g. UnityEngine.Profiling.Profiler.BeginSample
in system: static readonly ProfilerMarker marker1 = new ProfilerMarker("marker 1"); set this in the job then
and then you can beginSample, endSample or use auto() instead and measure the thing in brackets
works for burst too
isn't it nice when you just open burst inspector, look at your job
and you have 161 lines of simd in a row first try
hey this is probably a stupid question, but do rigidbodies and colliders convert automatically to the entity version of those components, or do you have to replace them with the entity versions manually?
the physics system includes conversion from existing physic components, so yes they convert automatically
oh ok thank you so much!
if you use the new physics shape, physics body components though you get new features and control
ooh, id like to try those, how do i find them?
how, i tried searching for them in the component menu, they dont appear to be there
you have unity physics installed right?
i hope so, i just installed hybrid renderer and i thought it auto installed everything else with it, but ill go check brb
oh ok, well then ill install it manually, thank you so much!
thanks!
ok that makes sense, thank you so much!
day 9 and over 50 hours of not being able to compile a standalone approaching, no one answering my addressables questions. It should be easy... My game ain't making the .json file.
a) probably wrong channel for #๐ฆโaddressables
b) how are you building them anyway?
I know tertle, but no one answers my question for 3 days
I'll get the info together as concise as possible. My system is building a build, takes 3 minutes a try
i don't think we need that much information about building addressables (and honestly if it's more than about 2 sentences I won't read it =D)
it's usually 1 button to build them?
really just want to check if you're building them the normal way or have a custom build script doing it etc
I changed build paths along the way because I thought it was putting settings.json in wrong place
Here I have no settings.json on my entire computer
Its not making the assemblies
By default, Unity should have assemblies work, I was using nothing custom at all
Error I get: System.Exception: Invalid path in TextDataProvider : 'C:/UnityProjectfiles/StarfighterGeneralOnSteam/Builds/buildme/starfighter_Data/StreamingAssets/aa/settings.json'.
Looks to be an unsolved bug from Unity from 2 years ago: https://forum.unity.com/threads/addressables-not-loading-in-build.925982/
Looks like I have to downgrade to: 1.16.15 addressables?
is there addressables in
PROJECT\Library\com.unity.addressables\aa\Windows
and if not, when you build addressables what error do you get
that means you've never built it in the editor
I built it many times
so it's never going to be included in your build
build, new build, default build script?
yes
I want it working now tho
(it means none of your assets will ever unload from memory)
If unity can't handle 2 groups, I'll do one. I'm not picky
you should have anywhere from 10 to 1000 groups
I know, I had 2 groups to start
1 music, one my droppables
But when it didn't work, I thought Unity had an error understanding more than one group.
idea
maybe I have to make the directory by hand
Unity never made those directories
Maybe it was a bug that it forgot to mkdir
I'm gonna make those directories by hand and try
it should error when you build ๐
my build goes through and game plays
just sends tons of errors trying to load the addreessables it can't find
yeah because its clearly never been build
because its not in that folder
so it's never copied it to streaming assets when building your game
so its never been included in your build
BuildPath for group 'Default Local Group' is set to the dynamic-lookup version of StreamingAssets, but LoadPath is not.
if it's not in Library\com.unity.addressables\aa\
there's nothing to copy to your game
I never saw the errors on a "Addressables build"
Now I see there are ones, it uses the same console unity uses for play.
well that's a good start
Yah, we're getting someplace
This is the only place I could google about it: https://forum.unity.com/threads/buildpath-for-group-is-set-to-the-dynamic-lookup-version-of-streamingassets-but-loadpath-is-not.1230894/
I'm pretty sure we're striking distance from ending this tech hurdle.
ok
my build path and load path were set to the same thing, and it can't be like that says: https://l-u-k-e.tistory.com/13
Looks like it is building now. TY tertle, you're a boss who helped me TOOOOOONS. I want to be making the hundred mil a month like other MMOs and hook you up. lol. I personally don't care about money, I'd rather just be gamin or coding.
As a UI guy, I'd recommend that if a build fails, and the console window is not visible, that it becomes rendered.
I quite literally got no feedback and assumed the build succeeded
Addressable content successfully built (duration : 0:04:00.474)
hey stupid question, but how do i get a reference to an entity that the script is attatched to, a bit like how you can use this.gameObject to get the game object the script is attacched to?
yes
okay, simple and useful, let me get you code
You want an entity from a monobehavior script or a Systembase ?
monobehaviour would be nice
I got you my man.
cause i plan on having it attatched to an entity, and it destroys the entity after existing a certain amount of time basically
Its useful to use entities in some monobehaviors, especially the player controller
Wait that should be a system base
I have the code for you
ok
if you use monobehavior for that it slows you down
oh ok, what should i use then?
Sec, let me get u code
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
If you attach a Bastian to an Entity, it sets it to destroy
Let me give you the destroy code
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
you'll have to edit this radically to get it to work tho
Use it as notes
ok i shall, thank you so much!!!
Basically it cycles through entities with Bastian and destroys them, and or drops loot and or destroys other entities dependent on it
Its overkill
ok thank you so much!
lol
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
ok thank you so much!
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
So do you know there's two systembases
And two icomponentdatas
The systembases processes each
It might be a bit unorthodox, uneloquent and such, but this code is tapping into power and early.
But hey
let me answer your original question
how to read and write to an entity from mono
ok, ye ill mess around with both ways, and see what works good for me, considering how i am a bit of a newbie to dots lol (also pasting code doesnt work in this channel, just screenshot or pastebin it)
Here's how to add componentdata via mono: https://pastebin.com/BETtXwzz
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
You want to do EVERYTHING you can in dots
thank you so much!
The only thing you do not want to do in DOTS is your player controller, and only if you have a mature game you're expanding to have a dots level
Translation entPos =World.DefaultGameObjectInjectionWorld.EntityManager.GetComponentData<Translation>(shootingEntity);
That's how to get componentdata
ye luckilly im not doing much with dots, just a large amount of frictionless spheres that would otherwise grind performance to a halt without dots, but ye all you have said shall be very useful, thank you so much!
Yah, I gave you some stuff to mechanically putz with
Its unedited from my current game, so you got ship wreck comments and nonsense constants you can't use
ill figure out some way of making work eventually though, i always do lol
My character controller is written in dots >_>
IT WORKED MY MAN! I should be able to make a live compile soon
Thats perfectly fine. There's just a super awesome trick for people with mature Gameobject games they had on steam for years or jury rigging it. I told you before?
I'll tell it again, it's exciting.
So say you have 300 levels of games in your GameObjectgame and people loved it for like 5 years.
You want to add dots levels
But don't want to make a new game.
You take your already working Player controller.
At the very start, get position/velocity/etc of your player
well, anyone who is suggesting switching an existing project to dots I have simple advice - don't ^_^'
Have your player gameobject be invisible and non rendered.
Then at the end of the cycle, add the velocity, rotation
Boom!
Your player is now an entity
that's just the standard hybrid workflow
Super super simple
Enemies, enviro, items, etc should be all new
All new scripts for stuff except the player
Having one monobehavior script doesn't hurt dots performance
But having hundreds of mono for enemies would.
The best part is as you change your player for gameobject land, it auto changes for entity land
the same controller on my characters is the same controller on my enemies
You edit once, change twice
oooh,
You could... Say... Super Mario 64 sequel take over them with a hat
Or, get apower up
where every move you input
gets inputed to them
Make a dance party
Dad, tell us again how you defeated the bad guys? Oh we taught them how to dance and have fun. Turns out people having fun don't want to take over the world much.
another stupid thing, but couldnt you use a component system on each entity the way you would instantiate, but destroy entities instead of creating them, or is this not a good idea?
when you do instantiate an entity
it has all the components the old one had
so the way I datapool
is instantiate one entity
then save it in a List
and then instantiate it by index
It generates SOOOOOO fast its basically instant
Its better than buffer datapooling in gameobjects
Thats one of many things DOTS ECS got right
ecb.RemoveComponent<Disabled>(e);
ecb.RemoveComponent<DisableRendering>(e);
ecb.RemoveComponent<DOTS_OBJECT_POOLER>(e);
I put a Disabled/DisabledRendering and DOTS_OBJECT_POOLER tag
Diabled and DIsabledRendering are UNitys
ooh that is clever, i should probably do that eventually, but for now ill keep using my stupid instantiation script cause it works well enough for now lol, but imma try my odd method of destruction now because even if it aint the fastes i think it may work in a stupid way
DOTS_OBJECT_POOLER is mine so I don't process it in places
Sometimes you gotta get stuff working to do more
But DOTS/ECS is the way for all
Don't do MONObehavior stuff you want to keep long term
I recommend not using it all for destroy
i wont use monobehavior for destroy, i wanna see if i can do it in a component system in a similer way i did the instantiating, but with destruction instead
apparrently Time.time does not exist in a component system, are there any replacments for it?
wait im stupid i can just use delta time and do the equation backwards
from googling around it seems there is no way to figure out what entity the script is attatched to, atleast not in a component system, surprised there is a this.entity or something like that
guessing im missing something obvious though, so any dots magicians feel free to correct my stupidity
I just updated Entities to 0.51 (from 0.50) and all of a sudden Newtonsoft disappeared from the face of the earth. I'm getting errors that Newtonsoft namespace cannot be found. I looked at my ASMDEF where they were and they are now greyed out and says None. I can't find it in the UPM either anymore. What's going on?
Just downgraded back to 0.50, and Newtonsoft.Json.dll appeared again (even in UPM). What am I missing?
Hmm..updated Newtonsoft from 2.0.0 to 3.0.2, and then updated Entities to 0.51 no problem.
entities removed it's dependency on newtonsoft
so unless you manually add a reference (e.g. updating it) it won't be included in your project
I see. Thanks for that clarification.
But why would it disappear from UPM? I was going to add it manually but it wasnโt in the registry. I had to downgrade entities, upgrade newtonsoft and then upgrade entities lol
yup, the more i research the less i find, it seems instead of being able to use anything simple, ill have to ring around the posy until i find the entity that is the script is on, which seems a bit silly personally, but my research is pulling up no better solutions, odd
your question doesn't really make sense to me
and i'm not sure what you're trying to do
so basically i have a script attatched to an entity, that destroys said entity
that is what i want
so that right there
makes no sense
because you don't attach scripts to entities
you attach components
which are just data
oh
Not quite sure what exactly youโre asking, but if you are trying to tap into the entity that is being queried inside a ForEach loop, have the first argument be Entity entityโฆ
the whole point of entities over gameobjects is to not attach logic to the entity
gameobjects have components attached but these contain data + logic
entities have components attached but these only contain data and systems provide the logic
that is like the fundamental of ECS and the difference with gameobjects
ok that makes sense, so rather what i should have is each entity having a float for time, that then a loop goes round for all entities and lowers teh time and if any of the entities time is 0 or lower, i destroy that entity, is that more correct then?
yep
ok, thank you so much!
you can have a LifeTime component with a value in it
and a system that iterates all these components, when it hits 0 (or when it hits X time) destroy the entity
ye that would make sense, i shall start figuring out how to do that!
small question though, how do you make components, is it just a regular c sharp script with the data in it that is attatched to the entity
also how do you loop through a list of all entities, all my googling is coming up nothing, i have a bad feeling im missing something obvious
and ye i still cant figure out how to add components, it seems that all the info on dots is really well hidden from google, and if you dare add "unity" to the end of any search it automaticallly pulls up stuff about only GameObjects and nothing about entities
@late mural https://github.com/Unity-Technologies/EntityComponentSystemSamples just poke around the samples. They have pretty much everything you could need. Either do git searches or actually look at the readme use cases for each sample
oh ok thank you so much!!!
also is there any good solution to not have to restart unity every time you add a component, or do anything dots related, cause i have to wait about 10 - 15 minutes each time for unity to start up again
why are you restarting?
because for some reason i just get an error that my scripts cannot be found in the file system, despite me literally dragging my scripts from the file system onto the objects, as such i have to restart to fix this odd bug
this happens every time i create a new script, or add dots to an old script
haven't seen that specific one before
that said, entities 0.51 has its problems
if you want a more stable experience 0.50 is probably where you want to stick for learning
(though you have to stick on 2020.3.3X)
oh that is unfortunate, guessing 0.5.0 does not work on the 2021 lts versions?
*0.50.1
no 0.51.0 brought 2021 support
oh that is unlucky, i guess for now considering how the rest of my project is built on 2021 and i dont wanna downgrade, im just gonna keep dealing with these odd bugs and hope a patch comes out soon, and also use min max strategies to minimise the amount of restarts i do
@viral sonnet finally ran into your, GetNativeArray chunk version bumping issue, ^_^
You did something similar to this right?
var original = conditionActiveTypeRead.GetUnsafeReadOnlyPtr();
var updated = this.conditionActiveBuffer.GetUnsafeReadOnlyPtr();
var hasChanged = UnsafeUtility.MemCmp(original, updated, UnsafeUtility.SizeOf<BitArray8>() * this.conditionActiveBuffer.Length) != 0;
if (hasChanged)
{
var conditionActives = batchInChunk.GetNativeArray(this.ConditionActiveType);
conditionActives.Reinterpret<BitArray8>().CopyFrom(this.conditionActiveBuffer.AsArray());
}```
Have you tried reimproting in editor?
re importing what?
Just right click in folder explorer and click reimport
oh ok, ill try that next time
also im trying to work out how the for each thing works, and i think i get it, but how do you get the entity, after you have gotten the component?
i have a list of all components, and all these variables, and i can change them at will, but no way of getting any entities
the samples are very useful in showing how to do all the variables in a for each loop and all that cool stuff, but they show no way of getting a list of entities
wait could i do ref Entity thing? that might work!
yes it works i think, i just dont know how to use get component on an entity, but otherwise, i have it!
i found a vague description in https://docs.unity3d.com/Packages/com.unity.entities@0.17/api/Unity.Entities.SystemBase.GetComponent.html, although it has no samples, so i have no clue what it means or how to use it, so imma trial and error until i work out what on earth this means
ok i figured it out, but now im even more confused, apparrently im not allowed to modify public floats, because they are not variables, how do i make public floats be variables?
google aint helping, as per usual, and the samples dont talk about how to make floats be variables either, so im hopeing someone might know the answer here?
aren't you trying to access components in a Entities.ForEach?
By default for each lambda is bursted and threaded
That means you can't access fields inside
But you can store all variables in onupdate scope
exactly, i think
what does that mean exactly?
Make local variables
here I am accessing the rotation component
Lambda can read and modify them
oh thank you so much!
you can add more params depending on components you want
i thought you could only have 1 lol
you can only have 8 in a foreach, but you need a custom delegate for more, and surely you will adjust your systems if you need that many
that will be fine, i only need 2 lol, so thank you so much!
also quick thing, just making certain you can have if statements in a for each loop right?
yep
yay, thank you so much!
is this a normal warning to receive?
ok now this is weird, ive somehow made my performance dance, consistently
like it will stay at around 60 fps for about 10 seconds, then for the next 10 seconds it will drop to 10 fps, then the cycle repeats
anyone got any ideas why?
im guessing my code is quite unoptimised, because i used to get around 100fps with around 500 rigid bodies, and now that i get rid of entities that have been around for too long my game suddenly lags way more, but is more consistent
here is my code, incase im majorly messing something up
from testing, it seems to be that the line that destroys the entity is the most expensive
is there a way of getting rid of, or hiding, an entity that is more performant than destroying it?
try to not use EntityManager, instead opt to create an EntityCommandBuffer to process entity destruction
oh ok, i havent heard of those before, ill do some research and try them out, thanks!
I would think that would give you an error saying that you need to use .WithoutBurst()
i thought so aswell, but for some reason it does not
ok from basic research, those things look super cool, and super complex, im excited to learn them, thanks lol yet again!
yep, whenever you use a System, be sure to use those
it's pretty simple to set up, you can have it working in a few lines of code, but it does use some long class names
fascinating!
because structural changes already contains it
ok, i think im using the buffer thing correctly, just making certain though?
now that you are using the command buffer, you don't need to run it on the main thread and without burst, so you can get rid of the .WithStructuralChanges()
oh nice!
it will just queue all your structural changes to execute after you are done processing the entities
should i still use Run() or should i use one of the schedule things
probably just Run
ok, ill try it out and report back on the performance!
Why not ScheduleParallel?
well its a pretty small amount of work right now
Yeah that's fair
I dont see a reason to fully multithread it, but if it's running on tons of entities and has a bit more math involved, then it might be worthwhile
ok, performance is up, it now averages around 20 - 40 fps, which is better, not as good as i would have liked it, but still pretty good
have you fully profiled it? this is really what's causing the bottleneck?
keep in mind that the editor has burst compilation disabled by default, so it will be much slower than if it's enabled or you are in a release build
there is also stack trace stuff that gets added into the editor / development builds
i havent fully profiled it, i have been going off of changing stuff and seeing the result, without the entire system thing i get 300 fps for a while, until the entities get to such a great number that performance grinds to a halt at around 1 fps or less, adding the system back but not destroying the entities has the same result as the first test, destroying the entities is the bottle neck as such i would assume
ok that would make sense
if you go here you can enable burst compilation in the editor
hmm, okay
well if it's really that many entities, you might want to extend your command buffer into a ParallelWriter and use ScheduleParallel then
Well how many systems are there?
you would just do
EntityCommandBuffer.ParallelWriter parallelWriter = ecb.AsParallelWriter();
and at the end of your OnUpdate you would do
buffer_system.AddJobHandleForProducer(Dependency);
I am highly sceptical that destroying the entities is the bottleneck to be honest.
A simple look at the profiler should give you heaps of information
ok, ill mess around with that and see if i can get anything with it
ok ill do that
1 i think
here is my profiler if that helps
you would have to click a certain point in time and look through the functions taking up the most computation time
how would i do that, im not very famillier with the profiler sorry lol
We can see the scripts are wrecking you though, so that's nice ๐
lol
the green stuff also wrecks me, although less frequently, only about once a minute
like this
yup lol, and i got no clue what
oh ok, ill do that brb
You can open those and go all the way to the methods.
Also, enable the entities stuff there
Then at the bottom you will see this
Might be you have several thousands of structural changes every frame
im a little confused on what you mean by any of those, but i got this if this is helpful?
you can physically move your mouse and click on a time in this graph
how do i open them, i dont get that, i tried clicking on it, and takes me all over the place
im not very clever sorry lol
it will show you a snapshot of all the collected profile info at that point in time
oh ok, let me try that
ok i did that, it did nothing
issue, i dont have the timeline button, it isnt there on mine, and pressing the arrows just shows their children, none of which seem helpful
yes, it looks like that
Show me a screenshot of your whole profiler
ok!
It's probably hidden at the bottom
Set to timeline
how?
Don't hover over the function
click something else then
it opened automaticall
that then creates another box
lol
lol
press copy then and maybe it will go away haha
tried that, did not work
tried that, did not work
im stuck with this box one way or another
Works for me
open what one, how can you open stuff here?
oh, i didnt see those...
Profiling is an art ๐
I have never seen anything like that ๐
neither have i, although i suspect for different reasons, cause ive never used the profiler before
Isnt it the Run thats wrecking him?
it is the green stuff and the blue stuff, that is all i know
Does it run all the entities in small jobs now?
i have no clue
I hope Danon5 does
same lol
I always ScheduleParallel my stuff so ๐
ill try that, just to see how that affects performance
I don't think I have looked at the dots job profile section before, so I'm not really sure what it should look like
lol
but 12 milliseconds on basically the most simple task ever seems strange
a) are you creating/destroying entities every frame
b) you are in a fixed update death spiral
yup, very weird, should i go over to the frames when the green stuff takes over and see how the profiler looks then?
i am destroying entities every frame
you can't destroy something that doesn't exist
so are you creating entities every frame as well?
Can you show how you are creating entities?
and creating them, although creating them quite efficiently, i get around 100 fps without destruction
sure!
i assume your entities have physics on them
yup
i think you're triggering a full physics rebuild every frame
oh, that aint good, how would i avoid that
ok ill try that!
do each one individually or all at once?
All at once
ok i shall!
actually for b) On is fine, just make sure it's not full stack traces (Expensive)
but yeah make sure jobs debugger is off (unlike my screenshot) and integrity checks
ok, it crashed my unity trying to turn the integrity checks off, so is it ok if i dont do that one?
thats the most important one
did you turn it off while in play mode
oh
nope
well frozen, not crashed
and triggers a recompile
must be a long recompile then
been a minute and a half since it started
should i force close unity, or wait for something to happen?
it loaded yay!
lol
ok now i can continue with the steps
a nice drop into 4 fps land
here is the green domination part, ill do the blue one next
here is the blue
now that ive done all this, any ideas?
The jobs are still scuffed.
ye, it is weird
also the green domination that randomly occurs is odd
oh well, it seems to have had interestin affects on fps
randomly dropping to around 5 fps every 20 seconds or so
sometimes getting up to 100 fps, but usually staying at around 30 fps
anyone got any ideas what on earth is going on?
If the other people don't have suggestions you can try making a development build and profile that.
how many entities do you have?
That way it is way better in the Jobs and not a lot of overhead
i will try that if there are no other options, but that is cool cause i did not know that you could profile dev builds
to me it looks like you have a lot of physic colliders really close
alternatively can you save your profile and upload it?
a lot, a couple hundred, the destroy script is meant to keep the numbers lower for hopefully better performance
oh, how would i do that?
are you creating them all on top of each other
yes, randomly positioned within a 1 ^ 3 space
ok ill do that!
yeah i think you're literally just killing physics by having too many collisions in a small area
as for this something in your editor is killing you
but that wont happen in build
Would that mess up the Jobs so bad like that?
ok that makes sense, but it doesnt match reality, when i dont have the destroy script, i get insanely high fps until the number of entities gets too high
The more you know ๐
yeah but it probably only calculates it once
calculates what once?
this is what happens when you spawn 1000 physics objects in same spot
oh i see
as a solution, should i rather space out the spawning place for my instantiated entities, like have them randomly spawn in a 10 by 10 instead of a 1 by 1?
yup it is definitely the collisions, just from a little bit of a space out, it is doing much better
getting around 100 fps now
Didn't know the Physics ones also showed up in Jobs, learned something. ๐
Problem is fixed then?
yup, although gonna make my random selection position code be a bit better to help fix the issue even more!
also a bit of a math check up, if i use the random.value, and i times it by a number, call it x, it will give me a number between 0 and x right?
it isnt inside a job luckilly, cause im doing the instantiating very stupidly dont worry
(though I'd always just use Range() anyway)
oh ye, i forgot that exist, i should probably use that
Yeah, but remember it does not include the last number. So Range(-3, 3) = -3, -2, -1, 0, 1 and 2
ok, is there a range but for floats?
Range(0, 1) also is one of those things you think should work but doesn't
Yeah there is, google it
guessing it just gives 0 all the time, or perhaps an error lol?
Just 0
only for int
could be useful for claiming a gambling app has a random function, while secretly is still rigged
yeah, it's just to make it easier to generate a random index
Oddly specific ๐ค
But its possible yeah
lol
wondering how parenting works with dots, let us say i have 1 parent object with a rigidbody, and then the colliders on seperate children gameobjects, where should i place the conver to entity component, and should i put it on all of them or only 1?
it works disgusting xD
children have Parent component
ah, that helps me a little
parents have Child buffer
ok, so i dont need the child buffer on teh parent then?
and i have convert to dots on everyone then?
sometimes you do need it, but hopefully you won't face that trouble
i hope so aswell
I personally had to write an algorithm that restores child buffers through painful checks
yikes
where do you find the parent component?
what is rider?
an IDE
ok
like notepad but better
it isnt, i cant find it there
ok lol
Use manual's search to figure out namespace
well, you ask about where do you get it
I assumed your IDE didn't resolve it for you?
you need a name space to get it?
new Parent()
oh i meant in unity
oh good
through normal transform hierarchy
if you want to create children manually through code
you add Parent
ok thank you so much
(No intention to interrupt) Hello there! Quick question, is it possible to iterate in parallel (in a job) through the different values per key of a NativeMultiHashMap?
I saw that before there were IJob's dedicated to that kind of collection, but they were removed
For example, before existed IJobNativeMultiHashMapVisitKeyValue
im a newbie to dots, but i swear ive seen the exact thing your talking about somewhere in a unity fluid simulation tutorial
I'm getting a few JobsUtilities errors when upgrading to v.51 using 2021.3.2f1:
'JobsUtility' does not contain a definition for 'ClearSystemIds'
Any idea how this might be fixed?
Hmm, do you have the proper name of the tutorial or indications of how to find it? xD
ill send a link quickly brb
think it was this one https://medium.com/@leomontes_60748/how-to-implement-a-fluid-simulation-on-the-cpu-with-unity-ecs-job-system-bf90a0f2724f
it uses hashmaps for something i remember, hope it helps!
Hmm yeah, it just goes through all the values, instead of the keys, with an IJobParallelFor
I guess I could do that instead too
welp i wish you luck in finding a solution!
Thank you @late mural !
Try to upgrade unity to 2021.3.4 at least
Yeah manual says so
wondering how do you add rigidbody constraints, is it possible to do in the editor, or does it have to be done via code
https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/PhysicsSamples/Assets/Demos/4. Joints/Scripts Unity's physics sample project has code for physics joint authoring components, and one of those is a limiter that acts as a rigidbody constraint (I think it's the LimitDOFJoint)
oh thank you so much!
woah that stuff is cool looking! I'll try it out soon, thanks a ton!
When I first tried DOTS way back when it was just called ECS, the docs were a bit weak and I had to rely on youtube to fill in the gaps. Coming back, it looks like the docs are a lot better, but are there still parts of the workflow that I'll need to learn from third-party? And if so, has enough changed with the 0.50 update to invalidate older youtube content?
it didn't really invalidate
a lot of things are obsolete now
but overall ideas are still legit
mostly it's due to ComponentSystem -> SystemBase
switch
also
ECS is part of DOTS
That whole thing confused me to begin with so it's probably for the best that I'll need to relearn it
Yeah I'm aware, it just used to be called ECS before the rest of the packages were developed
it's still called ECS
but it's not DOTS
it's ECS package
DOTS contains: Jobs, Burst, ECS
all are independent
I know... I was referring to the period of time where all of the new systems, including things which do not fall under the ECS label, were just called "Unity ECS" as an umbrella term.
ppl tend to call ECS DOTS, because ECS is using all power of DOTS as dependency
How fast is allocating a large amount of temp memory? Say I want to speed up my pathfinding by moving from a nativehashmap to a nativearray, I would need to request the entire grid (~5MB) at the start of the job. Also, how big is the temp memory pool?
from memory there's only 256KB per block of Temp memory
at 5MB (per thread) you'll probably be using the fallback allocator
it won't be that bad though if you can do it per thread (entity chunk), not per entity
you can do something like this to re-use allocations per chunk that ends up on the same per thread (literally wrote this today)
private NativeList<BitArray8> conditionActiveBuffer;
public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
{
var conditionTypeBuffers = batchInChunk.GetBufferAccessor(this.ConditionType);
if (!this.conditionActiveBuffer.IsCreated)
{
this.conditionActiveBuffer = new NativeList<BitArray8>(conditionTypeBuffers.Length, Allocator.Temp);
}
this.conditionActiveBuffer.ResizeUninitialized(this.conditionActiveBuffer.Length);```
@tertle hehe, I knew you would run into it sooner or later. good solution to do a memcmp. i did it on an individual level because I had something like 5+ handles that could or could not change. your solution seems better
So running it with batchesPerChunk set to 1 should be fine?
Also I'm guessing the fallback allocator for temp is just tempjob?
@rotund token oh, what are you using for the var updated (conditionActiveBuffer)? is this a temp array? just wondering how you keep the original and updated around without too much copying
funny enough i just posted this like the comment before you replied
^
per thread nativelist
Why does this work? Does each thread reuse its job struct for all chunks it handles?
oh missed that! quite involved. i just use ref and write to the readonly ptr. then bump the version manually
in my case I know when changes happen. something you don't seem to have the luxury of
yes, stripping out a lot of code it basically simplifies down to this
{
// If we have no range to steal, exit the loop.
if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out beginBatchIndex, out endBatchIndex))
break;
for (int batchIndex = beginBatchIndex; batchIndex < endBatchIndex; ++batchIndex)
{
jobWrapper.JobData.Execute(batch, batchIndex);
}
}```
Huh, interesting. That would also mean if you write any "state" data to the struct from execute (which you shouldn't anyways I guess), that would not "reset" on the next batch
so each thread gets their own jobdata struct and just how structs work this means state is preserved yes
Cool trick, thanks
Another thing, if I request "too much" memory using the temp allocator and it falls back, I'm guessing I still don't need to dispose it manually
nah you dont need to worry about that
Yeah that would be awfully error prone ๐
Is this also true for unsafe collections allocated with temp allocators inside a running job? (im guessing they are also automatically disposed for me)
hmm
rn I started to wonder whether systems check whether they should run every frame
or only after structural changes
Judging by source code - every frame
but this is so inneffective
iirc it's every frame
literally comparing all queries every frame
well it compares queries you tell it to compare
by default that's any query in the system
but you can restrict this with RequireForUpdate
yeah, but I mean
it can be done only once
on structural change
kind of like: make all systems dirty after structural change
a) how does it know there's a structural change
b) checking a structural change requires a sync point
because you can implement b) if you want
simply to [UpdateAlways] so it doesnt check any query
Structural changes run on main thread anyway
meaning you can just add additional code to it
then do a if(query.IsEmpty) return;
oh sorry you meant structural changes
not change filters
ah most systems don't care about structural changes for updates
yes
well
then I think that checking whether queries exist every frame is a waste
quite large one
oh you mean if the query is valid?
ah you realize unity already caches this right?
public bool IsEmptyIgnoreFilter => _QueryData->GetMatchingChunkCache().Length == 0;
it's more about
hmm
It's checking all queries
array of them
meanwhile everything can be simplified to just boolean
Have you profiled if it's actually slow?
and be 100 times faster
it's literally just doing int == 0
sure it will be faster
but i doubt you'll even profile a difference
using chunk caches was one of the big improvements of entities 0.50
but even with that, did you notice a performance difference? because it is something like 20x faster than 0.17
if profiled independently
but when we profiled our entire project, we couldn't notice more than 0.5-1% in real world, well within any error margin
I imagine it would be pretty fast to check if any archetype chunk exists even without caching it
welp, not sure I understand, but hopefully it's all cached
it only requires 1 query to return true for a system to run
You only need a single query that contains an entity to run the system
I learned this the hard way when I made a really dumb mistake initially:
I create a LogColor singleton so that each network world (client and server) would print logs in different colors.
I then had a system that inherited from SystemBase that my systems would implement. The color was fetched with EntityQuery.GetSingleton.
This meant that since all of my systems inheriting this class had an entityquery that was always true (the log color singleton always existed), all of them ran each frame. So maybe don't do that...
Currently my systems run based of RequireSingletonForUpdate
mostly these are state entities
hmm, I do wonder though
if I add requirment for several singletons
they are will be combined requirment, right?
and probably same for queries
RequireSingletonForUpdate just gets a query for that type and then calls RequireForUpdate
yeah, but is it using OR or AND logic when you add it this way?
You can add multiple required queries to a system; all of them must match at least one entity for the system to run.
ah, yes
I didn't notice
@rotund token sorry to bother you with this, but is this true? I'm not sure how to check since I have no idea where temp memory is freed, and after the job runs the unsafe container's IsCreated is obviously still true since it wouldn't know about it. Calling dispose on it after the job runs doesn't throw an exception though (due to the missing dispose sentinel)
What about the components "Occluder" and "Occludee" for occlusion culling, are these replaced or just not needed anymore
temp allocated memory in jobs doesn't need to be disposed
Same for unsafe containers?
Since safe containers throw an error it's easy to check for those
hm, good question. I'd say no because it doesn't implement anything for the job to know
I'd stick to native containers for any temp allocations
they are optimized really well especially in burst jobs
What if I need to stick a container in another container inside a job
I'd say rethink your design approach ๐
But what if I wanna do it
I'd still say the same thing ^^ I mean, it's possible for sure and I'd handle disposing just to be sure
TBH I think they are disposed, otherwise it would be impossible to dispose any unsafe containers that use temp memory, since UnsafeUtility.Free is a no-op for temp memory, meaning you could never dispose an unsafe container if it wasn't already being auto-disposed. I don't think the temp dispose mechanism has anything to do with jobs
could be true, there's a mechanism in place that prevents of doing temp allocs outside of jobs
That's not actually true, you can alloc temp memory outside of a job iirc
You just can't pass it to a job
Not 100% sure though
This is all it says in the docs:
Allocator.Temp has the fastest allocation. Use it for allocations with a lifespan of one frame or fewer. However, you canโt use Temp to pass NativeContainer allocations to jobs.
ah ok, so yeah, it seems then that temp is just freed every frame
and every thread has its own temp memory
Yeah, I was just wondering about unsafe collections, but I guess they are automatically freed to, since again, you can't actually dispose them manually since UnsafeUtilities.Free doesn't do anything for temp memory
Hey all, I'm trying to get all the positions of all my FireballTag'ed Entities in a MonoBehaviour .
Currently I have this:
EntityManager manager;
private void Awake()
{
manager = World.DefaultGameObjectInjectionWorld.EntityManager;
}
void FixedUpdate()
{
EntityQuery eq = manager.CreateEntityQuery(typeof(FireballTag));
manager.GetComponentData() <<< No idea what to do here, I want a list or an array of all the fireball positions, or should I use a Job for this and prepare a list in that?
}
What I am trying to do is put the positions of all the fireballs in a pixel of a Texture2D that is fed to a VFX Graph so I can batch tens of thousands VFX spells in a single graph.
Any tips/links/suggestions would be appreciated. I want this piece of code to be as performant as possible, because I would like hundreds of thousands of fireballs.
good writeup: https://www.jacksondunstan.com/articles/5446
You can create an entityquery and then call ToComponentDataArray on it to get all components of a specific type from it
Allocator.Temp appears to be backed by a "bump allocator" that is cleared between every frame. Whether you call Dispose or not, you should only read and write to memory allocated by it during the same frame that you allocated it. Starting with the next frame, you'll either get an exception or data corruption.
I tried reading it a frame later and it still worked, but it's definitely not going to always work
the safe container threw an exception
sometimes it lingers, guess when the temp memory space isn't exceeded or smth. hard to say what the logic is as we don't have the source code for it
or rather, the data lingers because it's not overwritten
I mean why wouldn't it linger, it's in the virtual address space of the program that allocated it. As long as nothing wrote over it it won't change
Is there a reason unity doesn't publish the source for stuff like the alloc, free, and scheduling stuff? Because it's part of the engine source code?
Awesome, thanks! ๐
Are you aware of a faster way then this?
This is working now, but just checking if there is more to be gained.
Depends a lot on how you have your project set up. Ideally you aren't using any monobehaviours and are running all your code in jobs with burst enabled
how is it fast to read from blob reference? Can i use it like normal component data, or should i cache data from blob to read it faster?
Well currently I'm doing it this way because as far as I know, jobs can't change values in my VFX Graph, and can't change the Texture2D I am using for positions. But maybe I am wrong about that. And the VFX Graph has so much overhead that giving all the Fireballs their own Graph is way less performant then doing it this way.
https://gdl.space/uzemebicik.cs
That is currently the only script in my scene.
I do the same thing to instance my vfx (from positions stored in texture) ๐ works well
You do it in a MonoBehaviour as well? Or do you do it in a Job? Is that even possible?
@oak sapphire If I can remember correctly, I do all the calculations in burst but had to set pixels in MonoBehaviour let me look
I am using a property binder to the vfx graph to assign the values
is that what you are doing, i know this is not what I was answering, pulling it up now
Yeah, I have exactly that. All my entities behaviour via the SystemBase ScheduleParallel method. And the Mono changes the Texture2D and the bindings with the VFX graph.
My question was about what would be the fastest way to do this.
But if you are doing the exact same thing, it will probably be good ๐
A blob reference is just a pointer to the memory where the data is stored
Yeah i remember testing it and it was really efficient , but I'm definitely not an expert on micro optimizing in jobs and burst
I would profile it first and see if it's even a performance issue
Yeah you should be good, looks like your texture isn't too large
If you do need more performance, there is a much faster way to write pixel data to textures
please share
You can write to the memory backing the texture by getting a native array to it's color data using Texture2D.GetRawTextureData
e.g. Texture2D.GetRawTextureData<Color32>()
You can then write the data in a burstable job if you like
oh duh, yeah that is much better than what I am doing
Just note that you aren't supposed to store the native array in any way, the intent is to use it immediately and not dispose it iirc
Depends on what you think a performance issue is.
Currently I have DOTSNET networking working with 1 million entities all updating the rotation and position, while being server and client.
I have an animation system working with 78.804 animated characters at 70 FPS.
And now I want to make those characters shoot VFX entities, and would like to get the most performance possible here too.
Then I will combine them and make a small game, that's my plan.
Yeah I just mean it really depends on the project. imo it's a performance issue if you don't hit the required metrics, e.g. 60 FPS or whatever your target is on the minimum hardware
I just mean check if it's actually an issue before trying to optimize it
yeah, of course, if trying to get product out in the most efficient/effective way, no point in fixing what isn't a problem. Sometimes the use case is "I wonder the absolute most efficient way to do x" which somehow makes it into my project pipeline when it shouldn't or isn't an issue. But still fun sometimes
any of you know what might be causing the componentdata to be unknown here? you all know why I might be getting "InvalidOperationException: The previously scheduled job Jobs:CreateRigidBodies reads from the UNKNOWN_OBJECT_TYPE CreateRigidBodies.JobData.PositionType. You are trying to schedule a new job CalculateGroundHeightSystem:Calc_Ground_Height_Job, which writes to the same UNKNOWN_OBJECT_TYPE (via Calc_Ground_Height_Job.JobData.__translationTypeHandle). To guarantee safety, you must include Jobs:CreateRigidBodies as a dependency of the newly scheduled job.
The discord recently started blocking large code blocks for some reason