#archived-dots
1 messages Β· Page 201 of 1
still on the fence if it is easier to build a new one from an archetype or instance the old one and remove everything relevant to rendering
it sounds to me like the data might be better elsewhere - e.g. a separate entity, hashmap or something.. but I wouldn't worry about refactoring unless it becomes a bottleneck
yeah makes sense. thx for the input
How to mock DynamicBuffer? I'm using Add which does not override any interface.
@acoustic spire tbh I wouldn't bother with mocking, especially not dynamicbuffers since you should be able to assume things like this always work
Just trying to reuse my ecs functionality in editor scripts. All I need is to replace dynamic buffer with managed collection since DynamicBuffer is strongly tied to entity manager and ECS.
Or mb I should try to get access to editor world and reuse the entire system instead.
ah I see, thought you were talking about unit testing
dunno what your setup looks like but could you just make an overload that takes a collection instead of dynamicbuffer? or use buffer.asnativearray
Does NativeArray from DynamicBuffer reflect changes to the buffer?
DynamicBuffer is dynamic though. Can't really just replace it with fixed size array. It looks like would be better to create either wrapper structs around Add or just manually tick a temporary world in MonoBehavior
yeah it should reflect changes
but yea ticking an editor world is a good idea too (in general, dunno bout your use case), should even be builtin already, defaultworldinitialization.init with (true) for editor world or something if i remember right
tho that one doesn't manually tick
What's the difference between Job dependencies and UpdateAfter/UpdateBefore?
Job dependencies determine the order of jobs, UpdateBefore/After determines when systems OnUpdate methods are executed on the main thread
i know this question is subjective but... what should I use for animation character when using dots? I tried kinematica, and although I got it working, it seems that it doesn't play nicely with other animation stuff. or I'm misunderstanding things... What animation packages/components are people using with dots with success?
maybe these rigs and contraints just work on kinematica I dunno... gotta try it I guess
I hope i can use kinematica one day but in my mind it's still early tech
yeah it doesn't even build with latest packages anymore. I've created my own fork to deal with it. apparantly there's a decent motion matching package on the packagee store that's a bit more fully featured....
ANimation samples were updated with skinned meshes examples, but according to thelebaron, it's not finished yet #archived-dots message
I guess I want to choose the correct underlying unity tech before I go too far into packages though
It sure can be hard to tech-lock when underlying packages are evolving as much :/
so theres also the basic gpu animation package as well that joachim open sourced on github if you need like 100k characters with zero animation blending. afaik they wouldnt support physics ragdoll setups either
you can use mecanim which is tried and trusted but obviously doesnt really scale too well and means mixing gameobjects
could mecanim do dozens or maybe a few hundred characters?
or you can use dots animation which has a lot of rough edges, notably no visual node setup(at the moment but its coming, eta unknown)
dozens yes, hundreds eh not sure? maybe?
dots animation looked very incomplete and was hard for me to find information on issues
pick your poison π
is mechanim synonymous with the gameobject animator and rigging? or does it use that? or how are those related?
yes
yeah mecanim is the current gameobject workflow. i think its the name of the company unity originally bought and then integrated to what we know as animators, animator controllers etc
ah ok
i mean kinematica uses some of those components
I wonder if maybe I can indeed mix and match what kinematica is doing and mix that with rigging (IK, etc)
I guess I'll just have to try it and see if it works
yeah. did they say for how long?
I guess it really needs dots animation packages to be finished before they can continue...
id assume they need to align it more with dots animation
I guess that probably means years...
I think this was the one I was looking at before. not sure if anyone else has tried it: https://assetstore.unity.com/packages/tools/animation/motion-matching-for-unity-145624
what kind of game are you making anyway?
just fps
i saw that a while ago, really impressive for a one man job
I wonder if it supports rigging constraints and IK
Works with most IK systems straight out of the box ***
probably better documented than kinematica
i might have to try this... I dunno
w/e well thanks for the overview @safe lintel I think I understand more now
How does that change the usage? Why would I use UpdateBefore/UpdateAfter when scheduling jobs if the job order is always determined with dependencies?
Job dependencies are a completely separate thing from ECS systems. You can micromanage how jobs are scheduled within a system or even between systems by passing around job handles if you want. Typically you can just ignore them and dictate how your game behaves based on the order of systems. Obviously if you have a system that spawns entities then a system that destroys them, you're going to have very different results depending on which one runs before the other.
Unity uses job handles internally to manage dependencies between systems if two different systems read from/write to the same component. But it has no way to know what logic you're going for just from that.
For example: If I schedule a job that moves some entities, and then immediately after schedule another job that moves them differently, they are guarenteed to run in the order scheduled, and the latter job will be dependent on the former because both write to Translation?
Are you talking about jobs scheduled in a system? Two jobs in the same system? Two jobs in two separate systems?
If they're in separate systems and they're both writing to the same component I'm not sure the order is defined in any meaningful way. It might just be based on how the systems are named for all I know.
Wow, that's something that isn't very well mentioned in the docs.
If they're in the same system then yes they will run one after unless you mess with the job handles yourself.
So I need to pass the handles to guarantee inter-system order, and not just UpdateBefore/UpdateAfter.
I mean...what would you expect it to do? How do you expect it to know what order you want those systems to run in if you don't tell it?
No.
Then I don't get it.
But if you don't specify the order of the systems, how do you know which one gets scheduled first?
Probably by name right?
I specified in the question that I schedule 2 jobs 1 after another. If I schedule a job that moves some entities, and then immediately after schedule another job that moves them differently, they are guarenteed to run in the order scheduled
I guess that statement is correct then?
If they are in teh same system yes.
What if they are in 2 systems, and 1 runs after the other?
Then yes
oh that, yea if you change name it changes ordering (tho dunno if it's actually related to name or just triggers a change), but it'll be the same ordering for the entire runtime
Wondering if someone could help me with question
when coverting an GO to an entity I dont see a scale component data
i see the Local
LocalToWorld , translation and rotation
so i need to do something so see scale
or do i have to set scale through local to world
I'm pretty sure the default conversion never adds the Scale component. NonUniformScale is added if scale is not (1,1,1), otherwise it's just Translation/Rotation
I imagine you would have to manually add scale or nonuniformscale for the transform systems to process it properly
if you want scale from the LTW matrix, you can grab c0.x, c1.y, c2.z (which is the diagonal of of the 4x4 matrix) if the Scale/NonUniformScale components aren't added
See @worldly pulsar's msg below (I forgot about that case)
You can't if the matrix has any rotation in it (e.g. rotation matrix for 90 deg around Z has c0.x = c1.y = 0)
just add the scale component π
Why are we unable to call SetSharedComponentData with an EntityQuery on a entity command buffer?
Only SetSharedComponent can take in an entity query
Can't believe there's still no easy scale authoring in the inspector tbh.
Just to confirm:
nativeArray[0] = 0;
nativeArray2 = nativeArray;
nativeArray2[0] = 1;
nativeArray[0] == 1 (?)
nativeArray2 = nativeArray;
nativeArray2.Dispose();
nativeArray still valid?
'nativeArray' won't be pointing to valid memory anymore since you disposed 'nativeArray2' which points to the same memory as 'nativeArray'
okay cool
does anyone have a code example i can look at for adding a component to a child entity using Entities for each
currently im doing this
Entities.ForEach((..... ref DynamicBuffer<Child> c) => { EntityManager.AddComponentData(c[1].Value, new MyComponent{Value = 1.1f} ); ...
as .Run() no WithoutBurst() and WithStructuralChange
Im in tiny it impossible to see why its failing ...
you're making a structural change though
What's the error you're getting?
If it's not showing up in the console try running your game from a terminal. As idiotic as it sounds that's helped me track down a few obscure problems
Since it will show the exception in the terminal at least
From command prompt (or whatever terminal for your system) in your build directory, run the exe
so buid to standalone then run the game?
Yeah
ok let me try that thank you
do yo see any isues with the code above
can i pass a buffer in like that ?
I don't see an issue with it assuming you're using WithStructuralChanges and assuming that index is valid
I mean you should probably be passing your buffer as in if you're not writing to it but that wouldn't cause an exception
In Tiny you should always be building to standalone for debugging by the way, the editor can attach to your game when you use build and run and give you exceptions (usually). Plus build times are way faster than other targets
How do I conditionally dispose NativeArrays in a struct my job uses? I have a 3x3 kernel of chunks with most of the allocation being persistent, but if I'm on the edge of the world I JobTemp allocate some empty arrays (because null isn't allowed). I'd like to only dispose of the JobTemp arrays.
I don't think there's a built in way to tell how a native container was allocated. You need to track it yourself
How do I get dots
https://github.com/Unity-Technologies/EntityComponentSystemSamples samples best place to start
the pinned message has more info @jovial bobcat
Whats this new .WithFilter i see mentioned on the fourms?
It lets you specify a list of entities - the query will only accept those entities as valid (assuming they also match the query)
I haven't tried it, I think I read it's not working right yet
NativeArray
whats the use case for it? I'm struggling to see uses for it
i guess optimisation? i could have my own way of tracking entities that need to update and feed that into it
Exactly
hey guys just found out about this discord after months of scratching my head, are the devs on here at all or just users?
just users i thnk
like once in a blue moon a dev might say something here
im working on networking for a rts game π and then eventually a rts too
what sort of network stack are you using? we tried with unity netcode but didnt go so well
yea not netcode, im stealing some bits and aiming to use unity.transport
retro fps
is dots useful for fps?
well, i think so otherwise this wouldve been a colossal waste of time π
i mean it could still be a colossal waste of time
π
the thing we found is that ECS makes it possible to have zillions of things which is great, but syncing zillions of things over the network was extremely challenging, and actually we are limited by users upload rate, like lots of people have 8mbps upload rate in europe, so you got to fit everything into that
my brain isnt powerful enough to do networking unfortunately
yea im coping planetary annihilations tech so i dont need to sync everything, and its wayy easier then lock step
PA did the stream of curve data right?
we looked at that but didnt work out with our goal of 10k units
so we are lockstepping just small parts of the system (unit movement and firing) and everything else we stream out (eg bullet should die, hp should reduce)
but costs a ton of memory on the server
i remember reading a while ago that eventually they wanted to support the lockstep model but id assume any meaningful sample for that is still ages away
we did some math on working out how to send out unit-pathfinding-changes for 10k units and it was most of our upload budget already
hmmm what are you sending? as you dont need to send it all at once, just for the units near the player and only there next 1-5 seconds of movement
"just for the units near the player"
well with a minimap that is nearly everything
we have a flat map (a square not a sphere) so assuming you have good intel you need position updates on everything
yea minimap is annoying, havnt touched on that yet
do you have a link to your project i can check out?
na nothings open or public π its WAYYYYY early
we are here https://www.sanctuary-rts.com/ in case you wanna take a look
its nice to have some people to talk to about ECS
but for minimap i was planning something like a quadtree, where where each grid gets set to a color depending on number of units and thats all thats synced
well less as its only changes
and its not a quad tree, its a fixed grid sorry
so basily ill be syncing a low res map grid, and then only changes to that grid every X (1 second)
kinda like a heat map of unit count ?
yea basicly
if thats enough that sounds good
yea it depends on what info you need
in that it would only be friends/enemies
but ill also want something like events (being attacked here, aily pinged here ect
those should be fairly small i guess
yea hoping so
honestly just building all the networking is alot right now, but when i get a bit further along im planning to open source it
tho im not sure if i could.... as i plan to copy code from unity.netcode.... i should check that license
we were heavily inspired by some stuff from there too - they way they bootstrapped in client/server worlds was handy
my early versions worked really well, but the inbuilt delay was annoying as, i will need to cover that by client animations and probably make it dynamic in some way
yea its pretty good, just not for rts π
what delay?
the server needs to run a tiny bit ahead of the clients, (about 200 ms seems best to deal with network lag, but lan could run fine at 50ms) so when you tell a unit to move if your looking for it you can see the delay
is that really netcodes fault though? i think you'd run into that issue on any network platform ... my ping (from aus) to europe is 300
no that was coded in on purpose, the curves only work if you have the next curve ready to go in time on the client, otherwise it looked terriable
tho some of it was a mistake, as i had the server updating only every 200 ms,
only some things should be at the low server tickrate
what's a good design pattern for "fake nullable" native arrays? i've got a 3x3 kernel of chunks that I use to update my voxel world, but if the kernel is off the edge of the world I need some way to know, a valid placeholder array, and a way to dispose of the placeholder array. i tried creating an "empty" array and passing that to the kernel constructor so it can replace chunk data with the empty one if it's out of bounds, but now the safety checker is complaining about multiple jobs having access to that empty array. i can't really mark it as read only because it needs to fill the place of read-write arrays.
Okay, I tried [ReadOnly][DeallocateOnJobCompletion] on the "empty" array and just allocate it during the job, but now I get aliasing The writable NativeArray UpdaterJob.kernel.se.field.data is the same NativeArray as UpdaterJob.kernel.empty.field.data, two NativeArrays may not be the same (aliasing).
it sounds like you need some sort of flag to process or not
i honestly dont know the answer for fake nullable arrays but cant you just have a bit flag to check to see if you should process edges or not?
The issue is, if there's no valid data to fill one corner of the kernel with, what do I fill it with? I can't leave struct members uninitialized...
fill it with default?
And then, if I allocate an empty array for each out of bounds chunk, how do I conditionally dispose of the temp arrays on job completion?
Default: The NativeContainer UpdaterJob.kernel.se.field.data has not been assigned or constructed. All containers must be valid when scheduling a job.
honestly no idea without understanding the complete code
i would still have a bunch of flags/bools and check those
but im definitly not understanding the whole thing
My brain can't make it past the word "kernel"
lol
{
public ChunkData center;
public ChunkData n;
public ChunkData ne;
public ChunkData e;
public ChunkData se;
public ChunkData s;
public ChunkData sw;
public ChunkData w;
public ChunkData nw;
[ReadOnly][DeallocateOnJobCompletion]
public ChunkData empty;
public ChunkKernel(VoxelBuilder terrain, int i, int k)
{
int max_chunk = FIELD_SIZE / CHUNK_SIZE - 1;
empty = new ChunkData(Allocator.TempJob);
center = terrain.chunks[i, k].data;
n = (k < max_chunk) ? terrain.chunks[i, k + 1].data : empty;
ne = (i < max_chunk && k < max_chunk) ? terrain.chunks[i + 1, k + 1].data : empty;
e = (i < max_chunk) ? terrain.chunks[i + 1, k].data : empty;
se = (i < max_chunk && k > 0) ? terrain.chunks[i + 1, k - 1].data : empty;
s = (k > 0) ? terrain.chunks[i, k - 1].data : empty;
sw = (i > 0 && k > 0) ? terrain.chunks[i - 1, k - 1].data : empty;
w = (i > 0) ? terrain.chunks[i - 1, k].data : empty;
nw = (i > 0 && k < max_chunk) ? terrain.chunks[i - 1, k + 1].data : empty;
}```
this should give you an idea
Trying to pass empty arrays into a job that you just end up disposing doesn't sound right though
it's painful but necessary since you can't nest nativearrays
{
public NativeArray3D<int> field;
public NativeArray3D<float> field_density;
public NativeArray2D<byte> field_heightmap;
public Vector3Int mins;
public Vector3Int maxs;
public int writeCount;```
{
public NativeArray<T> data;
public int width;
public int height;
public int depth;
public NativeArray3D(int width, int height, int depth, Allocator allocator, NativeArrayOptions options = NativeArrayOptions.ClearMemory)
{
this.width = width;
this.height = height;
this.depth = depth;
this.data = new NativeArray<T>(width * height * depth, allocator, options);
}```
Is this using ECS?
no, just jobs
I found [NativeDisableContainerSafetyRestriction], but it doesn't seem to travel down to the nativearrays in the chunkdatas and I still get aliasing errors
AFAIK the safety system will try to prevent you from having a struct with two native arrays that point to the same location in memory in a job. In this case I guess that would be the ones you're assigning your empty array to
Even if you use that attribute on all your chunkdatas it errors on you?
I would have thought that if those were causing the safety issue that putting the attribute on the container struct would have stopped it. Of course that might be a really really horrible idea depending on what you're doing with these arrays in your job, but I guess that's a different issue
Does Tiny support shadergraph, the dice doesnβt mention it specifically
Yeah so it does appear to be what I thought
You could try adding that attribute to your arrays in the struct itself, really though I think you should just rethink the structure of your data. The ChunkedList I linked, or maybe a NativeStream or NativeMultiHashMap
No idea, it seems like atm they just expect people to get by with standard or unlit
yeah, I trust that my code is safe so I'm just putting the attribute in all the dimensions of nativearray
I had an alias issue too interesting enough today
thanks for helping me!
I gave up and split into 2 jobs
Well in this case they are aliasing but it doesn't really matter for what they're trying to do
Just the safety system is being very protective
I thought I would throw something on chat sice Iβm away in the helped end but never helping
One day
it hurts D:
oh okay
Aka disposesentinels
how do I do that?
Jobs->Leak Detection->Off Jobs->Burst->SafetyChecks->Off
Just remember to turn them back on. Unless you don't make mistakes
If I want to try the ECS Visual Scripting, which version should I choose? Seems the 0.5.0 version is weird compared to the versions in youtube tutorials
I think the dots visual scripting was put on hold while they develop bolt integration
Latest version was drop 11 I think
But they aren't actively releasing it or keeping it up to date with new versions afaik
im really need some advice debugging here
in accessing children of an entity prefab. but keep getting a scrip error
.ForEach((Entity e, DynamicBuffer<Child> c, ...
What's the error
You can just do l.Value.Equals(gridPos)
yea that i should do for sure
but it not the error
errro is when i intoduce the dynamic buffer
Uh, can you be more specific
Why aren't you passing your buffer as in or ref?
Did you try running your game from a console?
yea
Same exception?
It could be because you're causing structural changes before you access the buffer. All dynamic buffers are immediately invalidated from structural changes. If you move the Debug.Log(c) to the top does it still error?
let me test
Either way don't pass your buffer without ref or in
I'm surprised it would even compile with that
Right. So the solution is to access your buffer before structrual changes or just use a command buffer
ok let me test that... thank you
Ok that worked , thank you
The latest versions of the ECS graph are more like OOP graph.
I had to downgrade it from 0.5.0 to 0.2.3 and downgrade all ECS packages to early preview versions in order to get it work. That just sucks
Yup they are focusing on gameobjects for now. I guess the plan is to integrate dots support down the line
So it won't be two separate things, you will use one solution for both ecs and gameobjects. Thats the long term plan afaik
I am trying to sort a dynamicbuffer and copy the first n elements into another dynamic buffer. What is the best way to achieve this?
I am currently trying to intepret the source buffer AsNativeArray then use Sort and then used Slice to get the first n elements from it. But AddRange does not take a NativeSlice π¬
Maybe AddRange(mySortedNativeArray.GetSubArray(0,n)) instead of using slices?
myNativeSlice.CopyTo(myNativeArray);
oh you want a buffer
myNativeSlice.CopyTo(myNativeArray);
myDynamicBuffer.AddRange(myNativeArray);```
?
@warm osprey didnt know about GetSubArray. Thought thats what slices where meant for
@sleek idol guess that would also work but GetSubArray seems to be more direct
Can someone tell me how to deal with disposing several NativeLists created in OnUpdate() that are needed in a scheduled job? If I dispose them at the end of OnUpdate(), isn't there a chance they might be disposed before the scheduled job concluded? It's for implementing a resizable pool. So first I need to check the Entities that are still "free to use" (which is what I put in the NativeLists) and then I use those in the subsequent job (or if too few are free, instantiate new ones).
Pass Dependency into Dispose
You can use .WithDisposeOnCompletion in ForEach as well.
Hey, I read the following in the Entity Queries doc today, but I'm not sure how this is supposed to be used. Can it be used with Entities.Foreach or we have to manually iterate chunks? in the later case, what's the most straightforward way to do it?
Do not include optional components in the EntityQueryDesc. To handle optional components, use the ArchetypeChunk.Has method to determine whether a chunk contains the optional component or not. Because all entities within the same chunk have the same components, you only need to check whether an optional component exists once per chunk: not once per entity.
https://docs.unity3d.com/Packages/com.unity.entities@0.17/manual/ecs_entity_query.html
I just had a weird case where .WithDisposeOnCompletion doesn't work in a job using WithoutBurst().Run() π
Because there's no jobhandle in that case
When you use an EntityQuery, you can pass the EntityQuery to an IJobChunk job. For Entities.ForEach it is implicitly constructed with using the WithAll<>, WithAny<>, WithNone and via the ref T and in T params of the ForEach
I guess that makes sense
@coarse turtle thanks. Do you mean that if i use Entities.Foreach, the filtering is automatically done on the chunk? what if i want to make my code less verbose and not execute a portion of the job code based on the presence of a component for example (without having to duplicate my foreach)? do i need to use a cdfe?
Probably you'll need a ComponentDataFromEntity, IJobChunk is pretty forward because you can do chunk based logic.
var data = GetComponentDataFromEntity<A>(true);
Entities.ForEach((Entity e, ref T a, ref U b) => {
if (data.HasComponent(e)) {
// ...
}
})Schedule(...);
// As opposed to
struct JobChunk : IJobChunk {
public void Execute(ArchetypeChunk chunk, ...) {
if (chunk.Has(SomeChunkType)) {
...
} else {
...
}
}
}
Basically what id like to do is: Entities.Foreach(Foo f, Bar b, Chunk theChunkImIn){ if(theChunkImIn.HasComponent(...)){ } }
yea OK
@zenith wyvern wanted to avoid that, bc code is the same for the most part
Essentially equiavalent to the branch inside an IJobChunk
Static functions can help a lot in those cases
But yeah, you're going to pay a heavy cost using a cdfe inside a foreach
Not a big deal for small entity counts but it adds up fast
I get the static functions idea, I thought about it, but from a readability standpoint, that's not ideal...
at least in my case
thanks guys!
ive got another one maybe while Im here, do you know how does the registered queries on SystemBase behave with system inheritence?
I've got something like: MySystem : SignalSystem, and SignalSystem : SystemBase.
I've just noticed having one GetEntityQuery in MySystem completely overrides any query (GetEntityQuery, Entities.Foreach...) that got registered in code defined in the inherited system SignalSystem. That doesn't affect GetSingleton, HasSingleton (at least)
Any info?
maybe use a RequireEntityQuery in your MySystem class in the OnCreate overridable method? I don't tend to use much inheritence with Systems
RequireEntityQuery would make the system run every frame, which is precisely what i want to avoid
i mean, this is not accurate. It's just bypassing everything, this is what i want to avoid
I want the system to run only when either one query from SignalSystem or MySystem is valid
currently, if i have no query in MySystem, it will run only when one query from SignalSystem is valid, but if i add any query in MySystem, it will only care about that one, and not about the queries from SignalSystem anymore
You can use EntityManager.CreateEntityQuery to avoid implicit system queries
@zenith wyvern I do for queries that I know shouldn't trigger the system by themselves. I just wanted to control when my system is running with registered queries, but bc of that inheritence problem, its harder
You could have an array of EntityQueryDesc in SignalSystem. In SignalSystem you add it's EntityQueryDesc in OnCreate. In MySystem, you execute base.OnCreate(); and then add your MySystem EntityQueryDesc to the EntityQueryDesc array. Then you use that array for RequireForUpdate(GetEntityQuery(EntityQueryDesc array)). This way, the System will Update if either one of the EntityQueryDesc returns something.
@warm osprey thanks, that's a good idea. I've though of some ways to fix it, and this is definitely one of them. I'm just unsure of what's the current behavior with inheritence... that's my question
do blobs move? if I keep a reference to a struct in a blob, will that reference become invalid at some random point later? or does it stay in place until I dispose?
Blobs stay valid until you dispose them. I don't think they serialize automatically though, you need to handle that yourself
thanks. I think i got writing and reading down. not sure if anyone knows: does netcode just magically transfer blobs if I send a ICommandData with a blob asset reference field? or do I need to write special things?
I plan to transfer my randomly generated level data to the client so it can lazy load things as needed
π€ Didn't try to send a BlobAssetReference yet. If not, you can write your own serializer anyway
can't you send the seed and re-random-gen the level on the other side ?
if you can reproduce result 100%, it will be way cheaper π
Im curious if anybody has a nice solution for planning out systems? Like a special type of flow chart or sth.?
I've thought about that but there's some downsides with my specific project
versioning is an issue. it's easier to just send a quick blob I think. It won't be much data
It's kinda covered in the best practices guide. Basically you break down all your reads and writes and plan your systems around that https://learn.unity.com/tutorial/part-2-data-design?uv=2020.1&courseId=60132919edbc2a56f9d439c3#
Thx @zenith wyvern thats a good starting point
I am currently trying to approach it more from a flow perspective though
Like following one Component (in the current case Buffer) through systems and how they manipulate it
I think its mostly about planning out the order of systems. Not sure if the sheet from the best practice guide is helpful with that
Probably a good request for that best practices thread on the forums
You can use the entity debugger to get a nice visualization of system flow, but obviously that only works after they're already written, so maybe not so helpful during planning
Good idea will ask about it there
I want to build some mesh data in a job and update the mesh on the main thread. How do I know when the mesh is complete? Should I give the gameobject a handle to my job?
How do I access a job struct after it's been completed?
use nativearrays to pass around data from a job
okay
To check if a job is complete on the main thread you have to store the job handle and check IsComplete every frame
in tiny there is this method
World.GetExistingSystem<ProcessUIEvents>().GetEntityByUIName("Name");
so my question is this, want to just have an enum w names ,
how do i get my enum to string
ToString is not implemented on System.Object for the Tiny profile. Please override ToString in the derived class if it is required.
is the error message
i really just want a good way to store my names and reuse.
typing them our everywhere is leading to many mistakes
So other than this https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/transform_system.html?_ga=2.201751506.2110640460.1613595122-900464242.1602472850
Is there any documentation explaining localtoworld? Like why the hell is scale only a float and not a float3 since you can scale in multiple directions? Why does it magically become a 4x4 matrix when you multiply a vector by a quaternion by a scale. How exactly are these numbers not just totally random?
NonUniformScale is a separate component. As for the matrix - it's a standard model matrix, there's tons of resources online about how it gets interpreted along with the cameraviewmateix inside shaders to give you your final rendered mesh
Nothing unique to dots
You can mostly ignore it and use float 4x4.TRS
Or just use the separate translate rotation and scale components
Yea - that's what the example I saw said but wasn't sure if I should understand the background or just go with it.
The transform system is pretty complicated. Personally I ignore it as much as possible and just use the simpler components
You mean the localtoworld system is complicated and you just use Rotation and Translation?
see NonUniformScale
There isn't really a localtoworld system, I more meant the innards of the whole transform system in general. Just the Translation/Rotation/Scale components should be fine for 90% of use cases
Yea I did actually see that later in the documentation when I was scrolling down. I'm not sure its ordered in a very good way and it just kinda dives right in without any kind of introduction. I guess that's just because DOTS is still experimental and mostly being released to users so the advanced users can test it
I've been complaining about that page for a year now, hahah. It really is a bizarre introduction but it does explain how the components are combined at least
It should NOT be entitled "Creating Gameplay->Transforms" for sure.
100% agree with you on that
is there a utils to create unique ids in tiny
@gusty comet make sure you click that blue button at the top of the page to view latest version, we are at 0.17 now
@karmic basin Interesting - I found it via google I didn't think it would link me to old versions. Thanks
you're welcome. They are pinned in this channel, and you can also bookmark with @latest to make sure π
Yeah going too faaaaast for Google β©
Speaking of staying up to date, how confident should I be that the examples in the samples repository are not outdated? Are they being pretty good about updating the old code as they depreciate old methods of doing things?
Or will I find "bad" ways of doing things in the samples repo?
They update it yeah
and even cross-packages: they also updated netcode and physics packages with release of 0.17
can't talk about animation package yet, I don't follow closely yet
I know the unity physics samples are not reading any inputs for me but I've just started to dive into what's wrong
var input = GetSingleton<CharacterControllerInput>();
Should I see an entity called CharacterControllerInput in my entity debugger? Because I don't and maybe that's the issue?
Ah I can find it - it's called "Entity 1" instead. Either way its not reading my input values so maybe a problem with the input system package
Just to make sure
CharacterControllerInput is a ComponentData
GetSingleton just tells to Unity you put it only on 1 entity
I guess it optimizes the query, (I didnt bother to even check)
Yea - it's basically a singleton entity. I don't know if its for optimization or if it's just to keep the code "neat" ("neat" in this case is more complex but "neat" for advanced users). Either way, I do actually have the singleton it is just not being assigned any values when I provide inputs. Input debugger is showing that my inputs are being detected so something in the code that updates the singleton to correspond to my inputs is not working for me
@karmic basin do you feel like help workshopping some multiplayer support in my jobs system with the new input system?
I am thinking of writing a blog post
So this is more a general ecs question, not dot specific. Lets say we wanna save our entities and their components in a relational database. We would have the problem that the database-id for each entity and component is different than their id on the client. So heres an little example, an Inventory{ Set<Entity>... } : IComponentData, as you can see our inventory references item entities by their entity-reference. Kinda makes sense and works. But if databases comes into play we couldnt do that anymore, so we would need some kind of assign each entity its database-id. So i came to the conclusion to give every entity an "Identity{ long databaseID }" and each component also includes such a databaseID referencing to its database table entry. This makes an entity look like this : Entity{ Identity{ id: 1231884812 }, Inventory{ id:9994922, Set<Identity> items }} as you can see we are now forced to reference "Identity" components instead of the item entities theirself. This way we would always need to query for the actual entity by its identity database id. Isnt there a smarter solution ?
Entities.ForEach((Inventory inventory) => { var entity = FindEntityByDatabaseID(inventory[0].databaseID); }) kinda sounds expensive right ?
Not sure I understood the question. If you're asking if I have some spare time to work on anything else than my prototype, unfortunately the answer is no. I can only find so few hours a week to make progress, I can't afford less.
I challenged myself to begin engaging in the open source community more this year... I'm still far away from at the moment :/
Fair fair π
I'm happy you understand π
It's even worse than that, entities don't retain id between worlds π±
I would bother with db id only when saving/loading, and inside queries I would use ecs entity id
depends on your game
Maybe I'm misunderstanding something but...why would you need a database? As far as I understand it Unity's ECS is already a database. If you need to reference something you just store the entity
I mean it's not an actual database but you can basically think of it that way
Yeah but I think he's talking about persistence ?
@karmic basin @zenith wyvern For example a multiplayer server, we need some form of persistence. And if there hundred thousands of entities in the world, normal serialization isnt the best option here. Yes i am talking about persistence ^^ And of course... what do you mean you would bother with the db only when saving or loading stuff ? Well i understand that, but the database cant reference entity ids on the clients... Therefore the idea with the identity component.
I mean to be fair you were never really supposed to share data between worlds. Worlds in both Unity and UE4 are horribly misused - there really shouldn't be more than 1 (aside from UI worlds) in an RPG style game.
And its kinda hard to only use the database for loading and saving operations. That requires some sort of automatic reference resolving. For example if you load an "Inventory{ Set<long> items}" component from the database, you would need an algorithm that converts this into an entity. So i thought the identity-component id is the best way so far
I mean that the client get the relations from your db, spawns entities in your world, then the rest of your client forgets the db ids. Until you save at least π€
"For example if you load an "Inventory{ Set<long> items}" component from the database, you would need an algorithm that converts this into an entity." Isn't that how serialization generally works in games?
You convert to and from your serialized format only when you specifically need to read or write to disk
Yes ? the way I see it, the spawner does the job of mapping the db id to let's say an Entity field
Trying to deal with your serialized format at runtime when you don't need to doesn't seem right
Hmm... alright, then you would need to write the queries and the algorithm for the convertation by yourself. I only know hibernate so far and that is using class mapping. So you could load in an predefined "Player" class and it constructs this class with stuff from the database using reflection. But in this scenario we would need to write another converter that converts this class into an PlayerComponent for the ecs. This also sounds strange, like double the amount of work
Yeah I would only translate when loading client (or room, or whatever zone) or leaving
Have you actually tested just serializing your whole world using SerializeUtility? If you compress the output it might not be as bad as you think
And it's very very fast
Its an general ECS question ^^ Im working with a java based ecs on the serverside. This one also supports json serialization but its not recommended for large amounts of entities.
How often do you need to persist state ?
Heres an example of how hibernate does it... I basically just tell hibernate to load the "Inventory.class" from that id and it constructs an class from it. Then i take this class and add it to an entity. But well... it references an database object instead of an entity... @karmic basin Every 5 minutes ^^
Yeah it brings you a Model, web-style π
I guess that's okay to add your own serializer for specific cases
And it works pretty fine... but well... its not that clean because i need to iterate over database ids instead of real entity-references. But having a "Inventory" class for loading and an "InventoryComponent" for the ecs itself is also weird due to the duplicated code
5 minutes is not scary, I thought you were gonna say each frame π±
Yes but you don't want your db to be coupled to your ECS system and your ECS to be coupled to your db.
( π€ Or just dump everything as-is in a NoSQL db ? haha)
Thats right :/ loose coupling is important. Im still a student and never worked in the industry, so i have no idea what the industrial standard for such things are. Do they really split it up into Database-Classes and ECS Classes and then convert the database classes to the ecs classes ? ^^ I guess i have the same problem with NoSQL aswell, because the entity ids arent real ids and change the next time i load the stuff back in
Do they really split it up into Database-Classes and ECS Classes and then convert the database classes to the ecs classes ?
You said it, "loose coupling is important". Allows more flexibility, easier upgrades, fine-tuning of platforms differences.... (I sure forget a lot of advantages). Of course like you said at the expanse of "double" the code.
Your model (what you call ECS classes but can be of any pattern) is your data representation at runtime. Your db, the persistent version.
Even the fields your data holds don't even match 100% between runtime and storing in db, if that helps you accept the differences more easily
Anyway Im' getting off-topic I guess
gtg eat, see ya
Can someone explain the syntax here?
#if UNITY_INPUT_SYSTEM_EXISTS
,
InputActions.ICharacterControllerActions,
InputActions.IVehicleActions
#endif
{```
if the UNITY_INPUT_SYSTEM_EXISTS is defined - then DemoInputGatheringSystem must implement the InputActions.ICharacterControllerActions, InputActions.IVehicleActions
so you would check the Scripting Defines in the Project Settings -> Player
I doubt that would be in project settings, I assume it's defined from a script in the input system package
yea there might be a line with #define UNITY_INPUT_SYSTEM_EXISTS
Basically it's a way to define your script with the possibility that the input package may or may not be in the project. If it's not there this script won't cause any compile errors
Or that's the idea at least
Yea I knew the whole #if UNITY_INPUT_SYSTEM_EXISTS thing I just wasn't sure what was with the ,'s and statements inside there
Oh I think I got confused by the spacing
That is because C# is not space sensitive
Does it make sense to prefer reusing entities instead of removing and creating them again for performance reasons?
By reusing I mean clearing dynamic buffers and altering components
@acoustic spire Probably not
mainly focus on reducing structural changes (adding/removing) components
It might make sense if you avoid all structural changes? or your changes are tag only with an EntityQuery thats very fast too
I dont thing its possiable to have 0 structural changes, but just not going crazy and adding/removing TONS of components from tons of entitys
@acoustic spire From what I've heard watching advocates of DOD and coding with Cache in mind in general is that your CPU is actually idle 90% of the time even at 100% utilization because it is always waiting for new cachelines (with OOP-style code). So I guess the most important thing to consider with performance is that all your data is coming in a predictable way in a cache line that can be used for multiple instructions and that how that information is processed is almost irrelevant. From what I understand when you change the archetype of an entity it will move it to be with other archetypes so shouldn't be a difference between new entities and reused entities - it still moves the data around.
if you can use an EntityQuery to select chunks of entities there are efficiencies there when removing or adding on whole chunks
@gusty comet Sounds right, the expensive part is when you change a archetype, that move data cost can get expensive
@keen spruce yea ive seen those new methods
havnt used them yet
Changing archetype is adding a new type of component, right?
yea
Or removing
but honestly i wouldnt stress too much about it early on
even if you code poorly DOTS will still beat GO's
and there are soooo many ways to optmize when you need it
if your problem is one that lends itself readily to DOTS
ie doing the same thing on a lot of instances of the same data
true, tho i find all my game ideas would work really well in dots
and i think most games have 'lots' of the same stuff
The word choice is basically that an Entity should not be thought of as a "container" of components because its not. The "archetype" is what kind of data the entity has an entry for - the entity itself does not hold data
sure, but some of the best performance optimizations come from SIMD data types native containers, jobs and burst so you can use that well enough in standard GO
Yea all your data is in an array and the entity is like 'i' in a standard for(int i =0; i>size, i++); Its just an integer
and ECS as a big sql database, each archetype = table, and each coloum = component
I actually find the whole ECS/DOD approach to be way more straightforward than the devs are making it out to be. The problem with DOTS right now is not that ECS is confusing its that their syntax uses EXTREMELY advanced C# syntax with lamda expressions all over the place.
same, i love the core ideas
the c# syntax isnt that bad at least compared to manual jobs
This kind of syntax is really only taught at graduate level computer science courses. Those who are self-taught or have only high school / early college knowledge have no idea what lamdas are
but it could be better
π I was self taught
and i had no clue what lamdas were for ages
but they arnt hard
I wouldn't call lambdas an advanced feature... like, all of LINQ is lambdas
the main thing you want is that the main heavy lifting code is working on sequential data and can take advantage of cache as much as possible so you hit main memory less often on the hot path.. most of the rest of the code isn't critical to performance because you only need a couple instances of random access
I mean I actually took a few graduate level programming courses when I was in college for mech engineering. They weren't even mentioned.
Of course, there's always been the ridiculous stereotype that Unity is for "entry" level game development and UE4 is where all the big boys are. I started with UE4 and quit because I got frustrated with all the handholding and Unity is WAY more complex if you don't just copy paste other peoples code (which is why Unity gets that rap)
Lambdas are a core feature of C#, they aren't that bad. But the way they use them, I can see that being confusing. You're just defining a function that gets analyzed and generated into a complicated job struct
Not very intuitive if you're just starting out
The best way to approach it is to just make it work as simply as possible and most code will not need to be optimized much at all.. whenever you see something is too slow start to optimize
I do think unity should expand/explain the code gen part more, Its very very cool, but its another magic black box that we cant really do much with
Being able to see the genned output in the inspector is as good as any explanation they could give
yea that helps
They should definitely do a better job of highlighting that feature for debugging/learning purposes
Yea that's the problem I have with the way the devs are handling it though. The devs are too big brain with their sample code it doesn't show a simple implementation of ECS it shows a really advanced implementation of ECS. If the whole point of using DOTS is that CPU speed is irrelevant when its not cacheing the data correctly (because it's always waiting for new cache lines) then why are they trying to make their actual system/process code as efficient as possible. It should be almost irrelevant as long as they set up their data correctly.
If they would add some documentation to the Unity Physics use case examples I think that would go a long way
i really dislike the physics implementation, dosnt feel like DOTS to me
like why cant layers and collions just be components
like you define 2 entityquerys for a collion mask
Probably still a big WIP - they want to get everything working on DOTS first before they make it look like DOTS
also the physics in dots is designed by physics engine experts not unity/dots experts
That's also true. I'm having the same experience with the Input System. It feels like they tied it into DOTS when they should have just remade everything minus the backends in DOTS. Maybe they will at some point but their first step is to make it so you can actually make a full game with DOTS first.
i trust the havok guys to know whats best, but you could ask em why layers arent components, theyre pretty open. i had never actually considered that before
you now the fun thing? Ive been remastering/porting a 2002 bullet hell game
and its as data oriented as it gets
there is a single array that holds every bullet
and a struct for boss, and other struct for player
and thats it
there is 1 single function that takes a bullet struct and updates its state. 0 abstractions, runs somewhere around speed of light
more than anything, DOD is coming back to the roots
do you need a Bullet class
and a HomingBullet subclass
and virtual Update
and a Renderer connected to the bullet
etc
fucks given = 0, just an array of 1024 of these
and its the entire game
in a way, DOD is about removing the bullshit, and focusing on what you need for your game
dod isnt about arrays and cache optimized stuff, but about removing abstractions and doing what you need, and then you can optimize it very well
I firmly believe DOD is just as easy to understand as OOP. I have no idea why the devs are trying to brace us for this new methodology it makes complete sense and isn't really more complicated than OOP. It's the syntax that's way more complicated - not the design approach itself
the problem unity has is that DOTS and ECS has no editor support
so its ultra-expert only
you need to roll your own renderer for ecs ffs
and input system
and physics
using ECS in unity is super stupid right now
you will end quicker if you just make your own engine
Even physics?
?? theres DOTS editor tools, hybrid renderer (yes its bad but works) and physcis?
Thought we had 2 physics engines to pick from
yes, and both are mediocre
for now
the renderer is also very mediocre and breaks constantaly (also for now)
the editor tools arent enough. You still cant click on entities in the editor
and conversion workflow is a disaster that should have never happened
?? you can click on entitys in the new entities window
I mean you make your own engine you're gonna have to make your own rendering system...and physics system...and input backends. Hooking Unity DOTS into Unity's existing architecture is a pain the ass but its better than throwing out the existing architecture.
Do I think it would have made more sense for Unity to split into two editors/engines? Yes. But I'm not ready to concede you're better off making your own engine...
and i actually thing conversion is good, works well for me
its easier to use SDL input that to find a way to use unity input in ecs
On input maybe. Rendering and physics no
for rendering thats the harder thing, but there is stuff like Filament
i dont mean split
im so far from being an expert π
i mean we are closing into 3 years of unity ECS
And lighting and particles and destruction system....
and Entitas in 2016 had far better editor support
and still has
i dont know why but unity just refuses to have proper editor support for stuff like hybrid
it would only take them a few days
interesting enough, unity is falling behind quite hard on ECS tech
the C library Flecs does the same that unity ECS does, but has far more features
I mean we do have the entity debugger which is a pretty good tool
I believe one of the reasons for DOTS they cited was they wanted to bring more of the code into C# so users can modify or reimagine it. It's essentially getting more open source which yes means more complicated
i dunno what they have been doing this last 2 years
seems like all unity does is spin in circles
when i started following the ECS stuff from unity when they first launched it, i wouldnt have ever imagined that 2 years later they would be at more or less the same spot
For me I'm stuck with DOTS. Unity w/o DOTS is not performant enough for open world games and Unreal Engine gets way too complicated when you step outside of the bounds of what it has prewritten for you. Their character controller is about 50,000 lines of code in C++ spread across multiple classes. If the character controller works for you great you don't need to worry about it but if it doesn't good luck. Cry Engine is even worse. Godot isn't quite ready yet...
What people do in unreal is that they shelve the entire game framework
gam framework is a relic from the 90s
na unity looks like any standard software product company to me
they have been growing super fast, so lots of new devs and tech debit kept growing
Leaders/marketing has expanded unitys targets (Movies, Architecture)
and core tech people have been voicing issues for ages, they finally got enough power to start changes but they cant just break things for everyone
best is to not use it
and run your own code architecture
in fact, its super widespread
i dont think you can reasonably compare flecs to unity's ecs, given someone of my ability can make something with dots right now but using some standalone thing would take me forever to decipher and integrate to other systems
basically every relatively big ue4 project just ignores BPs and the game framework
runs their game sim on just normal Cpp and hook it to ue4 for display
@safe lintel flecs ecs right now is more featured and advanced than unity ecs
many games do that in unity too
of course, it doesnt have the rest of the engine
what people are doing with flecs is to hook it to UE4
rimworld being a good example
you end up with a fairly similar environment as unity
Yep and UE4 is TOTAL CRAP when you take away blueprints. I can't tell you how many times I had to restart the editor because it doesnt sync with visual studio very well and it takes about a minute on a 3950x to compile a very basic project.
of an ECS lib not attached to the engine
Not to RUN the project to COMPILE it which you need to do every time you would just do CTRL S in Unity
opening times are a disaster...
there are some ways to sidestep it, but its mostly mitigation
no matter what happens ue4 (and ue5) will never get to the workflow of unity
tho maybe they are working on something
UE5 is a joke - it's just like a normal UE4 update they're not actually changing the editor at all
when they were demoing some fortnite dev tools, they had some live link stuff that would connect to a network game and perform edits live
and lots of leaks about a ue4 ecs
which i wonder what they will do
Its nothing like UE3->UE4 which was an actual new engine pretty much. UE5 is a marketing gimmick for a new version of UE4
it will be a bigger change
but more like 4-5 engine updates at a time
and big change in internals
Slightly - but it's not enough to justify calling it "UE5" like its some totally new engine.
i would say its definitely justified
quite a lot of breaking changes are being done
tho projects will be porteable
that does scare me...
the goddamn ghost from the 90s game framework still being a thing
I mean I think Unity had more justification with DOTS to call it "Unity 2" or whatever if they wanted to
I dont think it will ever be done. Project Tiny may be done by 2025 but it won't be 'done' then
not if they pivot it again
they did restart it like 3 times after all
kind of a shame, the idea of unity tiny is quite great
did they fix the samples?
last time i checked they were super broken
also conversion pipeline for tiny is such a mistake
sames have been kept reasonably up to date afaik
Pretty much only played with the racing demo, which was fine the last time I checked it
... the lack of play mode though
i remember when i ran it through profiler
Talk about lack of editor support
and found that unity (on tiny at least) has such a huge overhead "per system" of the ECS, that you can run an entire equivalent game-sim in Flecs in just the time it overheads in acouple systems
not being able to play it right in the editor is kinda my biggest issue for not really testing it out further
Samples are always going to be broken when they're constantly updating them to match beta changes...
about 0.2 ms overhead per system is insane
given that the bullet hell i talked about does its entire game state for 800 bullets in 0.1 ms
@gusty comet yet ue4 manages to keep all its samples and projects up to date
not really because they fix them evry time, but because they avoid code breakage
They're not converting from OOP to DOD
@safe lintel honestly, right now if you are doing 2d games, grabbing something like SDL and an ecs and just doing it in C will end up being more efficient
(if its a pixel art simple 2d game)
Unreal Engine has nothing on Unity when it comes to writing code. It literally takes minutes to compile and the debug support is AWFUL
debug support in unreal is lightyears ahead of unity
On literally anything else UE4 might have the advantage
its slow yes
but unreal debugging its not even close
you can debug the engine
on unity you cant
and ue4 has myriads of debug tools
that unity doesnt have
Oh god no debugging on UE4 is why I left UE4
nah, not for me same reason as flecs isnt for me either. learning a framework and trying to integrate it to other frameworks to complete something(also c/c++) is just out of my league. dots is kinda sorta there, i mean enough for me to have an fps going without being an expert
unity doesnt have:
network bandwdith profiler
replay system
high end logging system
debug draw system
screen counters in 1 line
many object inspector type things
Of course you cant debug the engine in Unity its not open source that's not really related to debugging your game though...
it is
for very simple gameplay things, ye, you dont need the engine
but when you have an engine crash
which is similarly common in both engines
in unity you can just cry
in ue4 you can attach VS and see why it crashes
Unity has never crashed for me, UE4 has crashed at least a hundred times
and then find what you were doing wrong
ive had huge issues when porting unity projects to console due to very bad debugging support
unity really isnt very stable on consoles
And I do so love t he bugs that you can't figure out how to solve in Unreal and then you figure out that your code is actually right it's just the editor needs to be restarted randomly sometimes to get everything to update properly
or when the original authors of the code didnt knew to program and do insane stuff
one of the reasons i was interested on DOTS unity is because they were saying that they would have the DOTS parts as "open source"
i cant take unity seriously due to the closedness
itsfar too much of a risk, and just breeds rituals of "praying to the machine" to hope something fixes itself
I'm not 100% convinced on Unity. I basically find everything other than implementing code to be way easier in UE4 than Unity. But the coding experience in UE4 is so bad I am willing to tolerate the headaches from Unity's other systems if it means I dont have to code in Unreal.
precisely that is one of the selling points godot is getting lately
right now godot is a tech disaster as the engine lead doesnt believe in "optimization"
but usability is good
will probably reach unity low end stuff fairly quick
Well base Unity (pre-dots) doesn't believe in optimization either
godot is slower than even that
ouch
dude didnt even implement LODs
or culling
had fancy PBR and dynamic GI tho
couse that sells the engine damn nice on twitter
Wait they really have PBR but no LODs?
they had dynamic GI but no LODs
Crossing that off my list of engines to try
even on the godot 4.0 refactor he focused on getting really fancy dynamic GI before getting lods
or culling
twitter driven development lmao
dude also shit-talks ECS and DOD
Yea I mean if you actually want to make a full game as an indie developer sadly your only real two options are Unity and UE4.
And they are so different from one another there's really no option if you're looking for something in between
if its a very simple 2d game, its possible to use your own engine
if you are good enough of a coder
by doing that you can reach the Ultimate workflow speed
making "mario maker" in your own game as level editor
but thats for pixel art type stuff mostly
Well yea I mean you can write PONG in java. I mean like lets say you're making a game like .... minecraft or terraria level. Where its achievable to actually complete the game as an indie but its not Pong
Though I think Terraria actually doesnt use an engine
neither does minecraft
Minecraft is also a very popular "first project" for people making their own engines
making minecraft on your own engine is actually easier than doing it in unreal/unity
as you can just render the voxels directly as you want, instead of having to find the proper way to send the meshes to gpu in your engine of choice
there is a dude on the Flecs discord literally making terraria/starbound
looks the same
what's the easiest way to get PhysicsWorld.CastCollider to ignore triggers?
I guess this doesn't apply to unity.physics
doesn't seem to work
the hits seem to have a rigidbody index even though they don't have a rigidbody on them
not sure how to tell if it's a trigger. Should I just get the collider component and check "istrigger" on it when the hit is added to the collector?
or maybe just check if it has a real rigidbody component on it?
thats for physx, let me see if i asked this question on the forums
I'm having trouble finding the answer for this for dots. so many results for the old physics
I get sub 2 second live coding compile times on UE4, I can literally change 1000 lines of cpp and it'll work without closing the editor, 100% of the time.
i think you can handle this in several ways and there may be a better way out there but here are my ideas:
you can set the layer of the collider to ignore colliders that are triggers(might be the easiest) so when you cast you dont have to do any specific checks
or query the material of the collider if its enabled for collision/trigger status when you get the collider
afaik that is not a thing in unity at all
ue4 vs unity in coding is a comparison of strengths and weaknesses. Neither side wins. Both sides have their ups and downs
@safe lintel how do I query the material of the collider?
like get some component on it?
ahhh i see this where the collider is created: var filter = new CollisionFilter { BelongsTo = 1, CollidesWith = 1, GroupIndex = 0 };
so can probably update that somehow
I guess tho I want it to trigger my triggers, but I don't want my character controller to have forces applied to it.
so I feel like the query is the right place for this, not the collider, but maybe I"m not 100% understanding
but I dunno how to query that
π¦
public static Material GetColliderMaterial(ref PhysicsCollider collider) {
Material material = Unity.Physics.Material.Default;
Assert.IsTrue(collider.Value.Value.CollisionType == CollisionType.Convex);
unsafe {
var colliderPtr = (ConvexCollider*)collider.ColliderPtr;
material = colliderPtr->Material;
}
return material;
}
public static void SetColliderMaterial(ref PhysicsCollider collider, Material newMaterial) {
Material material = Material.Default;
Assert.IsTrue(collider.Value.Value.CollisionType == CollisionType.Convex);
unsafe {
var colliderPtr = (ConvexCollider*)collider.ColliderPtr;
colliderPtr->Material = newMaterial;
}
}
public static void SetColliderMaterialCollisionEvent(ref PhysicsCollider collider, bool enableCollisionEvents) {
var material = GetColliderMaterial(ref collider);
if (enableCollisionEvents) {
material.CollisionResponse = CollisionResponsePolicy.CollideRaiseCollisionEvents;
//material.Flags |= Material.MaterialFlags.EnableCollisionEvents;
} else {
material.CollisionResponse = CollisionResponsePolicy.Collide;
//material.Flags &= ~Material.MaterialFlags.EnableCollisionEvents;
}
SetColliderMaterial(ref collider, material);
}
yeah should be able to query the colliders material if its a trigger or not, i dunno if theres a better solution and i havent looked at this code in ages
I guess I need to somehow get a PhysicsCollider for that
though setting up layers to ignore it in the first place might be the more effecient way
the collider case collector only returns a collider key. not sure how to get the physicsCollider from that :S
but how would layers work? I want the player to trigger the trigger, not stand on the trigger
if I set the layers so they don't collide, then won't it also not collide for purposes of processing the trigger being hit?
thought you said you wanted to ignore the triggers? im confused π
I want to ignore triggers for my ColliderCast, because my character controller is using the result to handle movement
but I need unity.physics to tell me what triggers it collided with so I can do things like open doors etc
how is this not just a simple bool
I'm so confused π¦
fuck is the point of a trigger checkbox on the collider if half the things just ignore it
probably many ways to handle it but could just do another cast specifically for triggers? and the have movement cast ignore triggers
ok
how do I get the movement cast to ignore triggers tho?
I have to update the collider material 2ce per frame?
are you casting with the entity's collider?
I'm casting with my player's capsule collider, yes
SelfFilteringAllHitsCollector<ColliderCastHit> hitCollector = new SelfFilteringAllHitsCollector<ColliderCastHit>(stepInput.RigidBodyIndex, 1.0f, ref castHits);
ColliderCastInput input = new ColliderCastInput()
{
Collider = collider,
Orientation = transform.rot,
Start = transform.pos,
End = transform.pos + displacement,
};
world.CastCollider(input, ref hitCollector);
so id make a component that stores a physics collider. in conversion, make another collider using the same shape parameters as your original on that entity and change the layer to only react to the layer that has your triggers, then in your system at runtime cast for triggers
though i dont know if this is the best way, just how I would tackle it π
ok I must be stoopid
how do I change the physics layer
is it just the layer at the top?
I've skimmed through like 5 youtube vids now reeeeeee
no, either using the Physics Authoring components or making a layer field manually in your authoring script and setting it there
I just saw this new component. ok cool
these authoring fields now make sense instead of being trash. thanks!
I dont suppose anyone knows how Unity chooses what systems to run say if you have two systems named the same and one is in a namespace?
I would hope that it would consider them as two separate systems and run both. but I haven't tested this myself
the whole point of namespaces is to have the same names. if unity doesn't treat these as two distinct types then something very unusual is happening there.
that's what I thought it might
it seems like its running the one in the namespace only
do you have "show inactive systems" checked in the entity debugger?
you could try [AlwaysSynchronizeSystem] on the system to help debug too
yeah I found that
I can see both systems in the profiler one's being run and the other is not
I don't really want both to run I was just curious
one probably isn't being run because no entities apply to it
(or because an exception was hit in another system before it got a chance to try and run it)
probably, but how is it picking which one to run first
the code in both is identical
in theory they should both be run
if you want to specify which one to run first you can use [UpdateAfter(typeof(whatever))] on your system
or UpdateBefore
but
I"m not sure the order is super deterministic. I think it's based on dependencies or something.... maybe it's alphabetical but... I wouldn't rely on it
if you NEED an order then use the UpdateBefore/After attributes to enforce the order
yeah I know, its just a curious confusing thing π
took me way too long to figure out CollisionFilter properties are masks and not just layer index number values

but got it workin. thanks again @safe lintel
So why do I need to SetSingleton every frame?
IE ``` protected override void OnUpdate()
{
if (m_BipedInputQuery.CalculateEntityCount() == 0)
{
Entity ent = EntityManager.CreateEntity(typeof(BipedInputComponent));
EntityManager.SetName(ent, "Input Singleton");
}
m_BipedInputQuery.SetSingleton(new BipedInputComponent
{
Movement = m_BipedMovement
});
}```
(which is basically from the UnityPhysics mine is just called a Biped and I set the name so its not called "Entity 0" in the debugger)
does m_BipedMovement change every frame?
thats the only reason to setSingleton every frame
also wrap EntityManager.SetName(ent, "Input Singleton"); in #IF EDITOR
Ah - the value should yes. I guess I thought SetSingleton was just making that entity the singleton I didnt think it was actually updating its data
sweet
how do you properly disable a system I've put Enable = false; everywhere and the only place it seems to work is in the OnCreate() π
and by the way I've found out it does run both systems if they named the same
Enable= false does work in OnUpdate, I've used it many times
I don't know it's weird I've got two systems named the same and one seems to work and one not it's confusing trying to figure out which is run, they both show they are running in the profiler no matter where I put the enabled π
why not rename one π
put a debug.LogError in one but not the other
the one I've disabled there is running harder than one I havent
yep its running the one I've put enabled = false, everywhere π
protected override void OnUpdate()
{
Enabled = false;
Debug.Log("This is ridiculous ");```
its hitting that, I even put a debug.log in the other system and it doesn't activate at all π
enabled = false will make OnUpdate not get called again but the code is already running
you'd need cs enabled = false; return;
setting a boolean can't terminate a function
ok yeah that's a good point
if you want it never to run then set Enabled = false in OnCreated
the other one probably doesn't run because there are no entities that apply to it
still I put enable = false in OnStartrunning() too and that didn't work
yeah I dunno the timing of that one
not sure where the enable check is relative to that
pretty sure OnStartRunning is triggered right before onupdate IF then entity query has started matching and Enabled has changed from false to true
if it's per frame it probably finishes everything in the frame before the next check of Enabled
sorry im guessing I have never used it
i used it like 2ce π
yeah onstartrunning I've had weird behaviour from that before
better to have stuff in oncreate which only happens once
like double the amount of entitys created if I've used it for that
yeah everry example I see uses oncreate
just a reminder onstartrunning is a bit like onenable, it might happen multiple times
it happens any time the entity query count goes from 0 to 1 or more
yea onenable would be the old equivant mb method
oh yeah you said that above, sorry didnt read π
np yeah I like to learn these things the hard way
(I dont really)
yeah I don't mind I enjoy it, otherwise I would have gave up ages ago
OOP I probably really would have, I hate OOP 
So there's not float3 '.size' function right? float3's don't have any functions?
what is size on a normal vector3?
it probably exists in the math library just under a different name
well unless im dumb theres no verctor3.size?
Thanks....I actually could not find an API on Unity.mathematics anywhere
Yea...the pins here seem to be better than google or the forums for finding info
haha yup
So am I crazy or is the movement component system in the examples actually a terrible implementation? It looks like they just took the OOP code and ported it to DOTS which is exactly what they tell us not to do. Is it just a proof of concept / here it works or is it actually how we're supposed to implement a movable character?
can you link it?
I mean for one thing they've got system code in the same file as their authoring / convert to entity code
ah thats way out of my league for judging π
I got the impression that was just thrown together for the dots fps sample. Not indicative of what you "should" do I think
Like the rest of that project it seems like they just mashed a bunch of stuff together to make the stage demo work
That's the impression I got but wanted to make sure
The single component with like 15 different pieces of data is a bit of a red flag
But hey, if it works it works
i feel like you need a lot of data for a character controller(so personally dont see it as a red flag) but tons of the other demos are/were really odd mixes of monobehaviours and dots and definitely felt hastily put together. this one is all dots though so i dunno if its that questionable?
Yea I have no idea whether I will ever wrap my head around writing code that responds to collisions without just using rigidbody and letting that do it for you
Before we had the charactercontroller which could do that but now that's been ported into c# through ECS and is implemented poorly so like...not sure what to do on that
Collisions are the one thing that is easier to work with (coding-wise) in UE4
I'm not sure how good this blog is but its the only thing I could find on this subject https://www.vertexfragment.com/ramblings/unity-dots-character-controller/
function toggleInfoBox(id) { $("#" + id + "-body").toggle(); } Overview Writing a Basic Character Controller Character Controller Component Character Controller System Building the System Skeleton Operating on Chunks Velocity from Gravity IsGrounded and Jumping Moving on the Horizontal Plane Player Controller Player Controller Component Pl...
seems pretty decent, looks like my 2d character controller
Dec 2020 too so not that old, should be up to date (which is rare)
yeah - there is an open issue for a collision bug so you'll prolly be able to accommodate it
I actually don't even have the input working with a fresh samples project. The singleton does not match my inputs
Basically copy pasted the code into my project and it worked. The input system backends are enabled so idk
im personally looking forward to philsa's dots character controller when he releases that. i ported ufps over to dots for my current solution but it has a lot of jank and could probably use a rewrite as it was the first thing i did with dots, though it pains me to think about redoing it all
Hi all, anyone know if its safe to save ComponentType in a buffer?
does the component type mapping to a type ever change/become invalid?
Yes ComponentType is safe to use in components and jobs/burst
Not sure when typemapping happens or how stable it is
im saving it at conversion
so during conversion i add some componenttypes into a buffer element and attach that to a entity
hopfully it will be safe
Does WithChangeFilter trigger on the FIRST frame if the entity is created from conversion (loading a subscene)?
https://ajmmertens.medium.com/ecs-from-tool-to-paradigm-350587cdf216 might be interesting for you
This blog is about Entity Component Systems. If youβd like to learn more about ECS, see this FAQ: https://github.com/SanderMertens/ecs-faq
I think I'll read that one toohttps://ajmmertens.medium.com/why-storing-state-machines-in-ecs-is-a-bad-idea-742de7a18e59
That title hooked me π
I'm interested in that answer if you happen to find it π
@karmic basin thats the author of Flecs
he manages to do, alone, more than the entire ECS team in unity
Flecs is quite advanced and has features for days
from my tests is also same performance tier than unity ECS, if not faster at some things
similar archetype-based ECS, but he has some pretty insane tech on the internals
for example adding and deleting components in flecs is much faster than in unity ECS
at no perf cost on the other operations
accessing the components of other entities (outside of iteration) is also much faster, specially if you use its "reference" types, which cache parts of the internal ECS state to accelerate the "entity.getcomponent" call
Yeah I saw that, though I'm not interested in switching to C/C++ atm
But it's great to see other approaches
Conversion world is included in release build or its results are "baked" in final scene? As far as I understand when a subscene is loaded it gets converted so conversion should happen in runtime anyway
It's converted at edit-time - i.e. before 'play'. The subscene is converted to a blob of data ready to load straight into ram basically.
@karmic basin flecs is C, so it has C# bindings
So that means that in release build there is no conversion right?
ive heard of some people using it in unity
tho i dunno how well it works vs unity ecs
definitely more featured and far more flexible, but i wonder about the overheads
correct
unless you do make use of runtime conversion
I've observed that at least with ConvertToEntity conversion "finishes" sometime in InitializationGroup. So it's possible for ChangeFilter to miss the first frame if you run it in InitializationGroup
If you're using subscenes it should work on the first frame afaik
this looks pretty interesting: https://github.com/dotsnav/dotsnav
you can use Debug.Log's in jobs right?
Jobs yes, but not with Burst since it will detect the message as a string which isn't supported
can you not use this in bursted jobs Debug.Log($"The celldudes positios is {comparisonArray.Length}");
yea, you can't use it. burst doesn't support interpolated strings - it will throw an error
it didn't throw an error so it must mean the job isn't running π
well, if burst is disabled in the editor it would run
I'm assuming you don't see the log message right?
yeah I've tried withoutburst().run() etc
hmm yeah it's probably not running then
its confusing I have the data being created in the components and yet the debug logs aren't showing
got some code you can show?
I dont think its anything wrong with the specific code but...
I guess the EntityDebugger can show you if your queries exists for the Job if you're using a ForEach
Entities.ForEach((ref CellData cooldata, in DynamicBuffer<FlowfieldVertPointsBuff> flowverts) =>
{
cooldata.cost = 1;
for (int j = 0; j < comparisonArray.Length; j++)
{
var tempobsbuff = comparisonArray[j];
Debug.Log($"The celldudes positios is {comparisonArray.Length}");
Debug.Log("Why isn't this displaying");
var tempbool = (flowverts[0].Float3points.x <= tempobsbuff.c0.x && flowverts[1].Float3points.x >= tempobsbuff.c1.x)
&& (flowverts[0].Float3points.y <= tempobsbuff.c0.y && flowverts[1].Float3points.y >= tempobsbuff.c1.y)
&& (flowverts[0].Float3points.z <= tempobsbuff.c0.z && flowverts[1].Float3points.z >= tempobsbuff.c1.z);
if (tempbool)
{
cooldata.cost = byte.MaxValue;
//Debug.Log("The values are" + cooldata.cost);
}
}
}).WithoutBurst().Run();```
what's comparisonArray.Length? I imagine if it has a size of zero, your log statement would never show
yeah it comes from the job just above
var comparisonArray = new NativeArray<float3x2>(colliderents.Length, Allocator.TempJob);
Entities.ForEach((int entityInQueryIndex, DynamicBuffer<ObstacleCollisionVerts> obbybuffer) =>
{
float3x2 tempfloat = new float3x2 { c0 = obbybuffer[0].float3verts, c1 = obbybuffer[1].float3verts };
comparisonArray[entityInQueryIndex] = tempfloat;
}).ScheduleParallel();```
the annoying thing is this code works exactly like it is but not in a namespace
i'm not sure what you mean by that
I'm basically trying to tidy up my code by putting it in a namespace
so I created a new script and put it all in there and deleted all the junk
while keeping the old one with all the junk just in case
o
yeah I guess I'm not too sure then, it could be a missing component in the entities, colliderents.Length is a size of zero π€
yeah in the new script the array size is zero but in the original it actually is 178
but even with that the values are getting set somehow from somewhere else maybe, I can't think of where else π
the code is identical too, I just copy pasted the code over(while deleting commented out code) except its in a namespace
maybe I should send a bug report π€
but then its probably a bug only I would be to stupid to encounter
you can try the step debugger in your IDE and step through the code to see what's going on
it's usually kind of flaky when I use it and never help that well but I guess I could try
What's workaround for storing HashMap in a component? I need a hashmap per component
When we serialize entities in dots... their structure and values are getting saved into a binary file right ? So what happens if we load those entities back into our game BUT we wanna change their structure as well ? An great example is an MMO... we define our first version of our archetypes and entities, players play and their entities get saved. Now a few weeks later we wanna publish an update and many components and initial values changed. How do we update those old entities to their new version ?
UnsafeHashMap can work. You'll need to dispose the memory when you destroy the entity
And i think this update issue is a pretty common one... we often change the structure of entities. So how do we update those old serialized ones into "new" ones ?
Yup, compiler lets it be. Thanks
it sounds like not baking entities would be a way to go. You could have the minimum components on the entities baked and then have a runtime system to bulk add new components to those entities @stone osprey
@coarse turtle Can you explain that a little more ? ^^ Like we check all entities upon loading if they are "old" and if they are old we convert them into their new types ? Or did i missunderstood that ?
well my thinking is -> you pull your data from wherever and you construct a collection of components -> add them to the entities (I think there's batched apis for EntityManager, but I forget which ones you use)
you're not baking data if your archetype is going to change. But let's say you bake the entities initially with xyz archetype, but change it to abc archetype, wouldn't you need a patch for your game anyways if the structure of those entities change to accommodate for systems that relied on xyz structure?
You can use interpolated string in jobs and burst as of the latest versions
neat did not know that
As long as they only reference local variables
So we basically never serialize any entity that is going to change ? Is that what baking data means ? This actually sounds pretty bad in terms of flexibility :/ But when we change their archetype and their values we should simply run some sort of query that patches the components that changed in the database/file ?
well baking data (entities) would just mean you're preparing the structure of the entities with whatever initial data they require
you can bake the entities and then do some manipulation on it, but idk how volatile you want your entity structures to be. So baked entities with components x, y, z can be come entities with components a, w, z through some system which changes the baked entities based on your new structure
imo, it sounds like you're circumventing an issue which is you don't know what structures your entities should be so I think it might be better to not embed the entities structure and just generate it on runtime. I do something similar where I just build the entities on runtime because data from an external source changes
Oh well... thanks :/ i see this is gonna be much harder than i thought.
I hate persistence... why cant we just call .save(); or .update(); on any object and it does all the boring stuff on its own
well if you wanna do like save you could probably just write the data needed to a structure you can understand
and if your entity archetype changes, have a system to restructure the components into something more tangible that you need now
well that said I have no experience with any MMO dev - so take what I said with a grain of salt and that's just my naive approach π
Player data will be saved on server though ? π€ So when you patch the server and the client to new version, you also prepare a migration script for your db (or save files, or whatever persistence source)
save file or db entry knows and keep track of lastClientVersion of course
and your patcher have methods for migrateFrom122To123(), migrateFrom122To235() to migrate from 1.2.2 to 1.2.3 or 1.2.2 to 2.3.5 in these examples
as much as any previous versions you wanna support
Welcome to Agile Software Dev lmao
it's pure hellfest happiness
Well that makes sense... so before each archetype change requires a script that updates all involved persisted entities. I actually have the feeling that this whole persistent topic comes way to short. We need more papers, examples or blogs about this whole saving, loading and updating of entities.
Yeah on Unity it's rarely talked about
Studios keep it for themselves I guess, and indies are just happy when they manage to get it to something vaguely right for their purpose ? π€·ββοΈ
BUT you can get inspiration from software dev world
where constant updates releasing is more mature
so before each archetype change requires a script that updates all involved persisted entities
Just to be sure we're on the same page here. You don't plan to do it at runtime, right ? Your patcher forces everyone to download latest client version, which connects only to latest version servers. So you mutate persistent data only once, when the server-side patcher runs.
You don't really want to support older live versions
Hope that helps
I don't suppose anyone knows how comes there's two SimulationSystemGroups run in the first frame?
I think that's what's related to my problem above
From same World ? Is that even possible ?
@karmic basin Yes it does, thanks ^^ And of course i would run the script before the version goes live and only on the server π nevertheless... json sounds great but i still cant decide between full serialization of every entity as json or some ORM mapping approach that saves the components in database tables
Or even if i just take a SQL database and use json fields :p
=> which kinda is NoSQL
end of one sim group and beginning of next in first frame unless I'm mistaken π
the two systems are in those separate sim groups
the ones that doesn't work are in the first group
maybe that's because the subscene converted entities don't exist yet
maybe I should stop relying on loading and starting things on the first frame π€
how do I define physics categories?
my stuff works fine without them being defined but... it would be nice to define them. google just keeps giving me results for non-dots physics π¦
You need to create a physics category names asset
There's an option for it in the right click context menu somewhere
got it. do I link to this somewhere or put it in my scene or?
It's an asset so it just sits in your assets folder and the inspector automatically links to it
Is it possible to make job work during multiple frame updates? E.g. for some heavy operation in background
yeah
any references how to do that?
pseudo code incoming
JobHandle myJobHandle;
Actual_Job actual_Job;
bool isSched;
void Update
{
if (!isSched)
{
isSched = true;
actual_Job = new Actual_Job();
myJobHandle = actual_Job.Schedule();
}
}
void LateUpdate
{
if (myJobHandle.IsComplete && isSched)
{
isSched = false;
myJobHandle.Complete();
//dipose natives here
}
}
sorry haven't touched jobs in a while
but hopefully you'll be able udnerstand
for native collections, you can use Permanent so it'll go over the 4 frame limit that TempJob has
not so difficult as I expected. Thanks
I'm confused... according to the docs, Debug.Log works with Burst if using string literals. But when I add a GetComponent call inside my ForEach lambda, I get an error. Anyone know why this isn't working? Is this a bug in Burst?
[UsedImplicitly]
public class MySystem: SystemBase
{
protected override void OnUpdate()
{
Entities
.ForEach(
(Entity entity) =>
{
Debug.Log("This is triggering an error");
var comp = GetComponent<MyComponent>(entity);
}
).Schedule();
}
}
Error:
error Assets\Scripts\Systems\MySystem.cs(13,9): error DC0002: Entities.ForEach Lambda expression invokes 'Log' on a MySystem which is a reference type. This is only allowed with .WithoutBurst() and .Run().
As soon as a I comment out the GetComponent line, the error goes away. The annoying thing is that this error prevents entering playmode, even when burst compilation is disabled.
have you maybe tried it this way Debug.Log($"This is...
yeah, still get the error
Instead of the extra isSched you could just compare if myJobHandle == default
I actually wonder if calling Complete on a default JobHandle completes instantly
or break
It's a known bug. You can work around it for now by passing in a ComponentDataFromEntity instead of calling GetComponent
Some issue with code gen, it should be fixed in next version
Got it, thanks!
yay it worked!
Wait, we can call GetComponent in Burst instead of passing ComponenData now?
@karmic basin @zenith wyvern Thanks for the answers guys, in my testing in seems to fire on the first frame, was having another bug which was making me think it wasnt
@whole gyro Very confused with that, why do you have a GetComponent Call inside a foreach?
Mmm, guys, pls help. I use ISystemStateBufferElementData to cleanup entities after they was destroyd. So to access this buffer i use WithNone<CommonComp>.Foreach((Entity, ISystemStateBufferElementData) => {}). But what i see in inspector is when entity destroyed it's instead of disappearing just got new component "Cleanup Entity". What is it? Why? π
@frosty siren I dont think the entity is destoryied, have you double checked the index and version? what used to happen is all other components would be destoried
It gets converted during codegen to be equivalent to passing in a CDFE
Has been that way for a couple versions now
oh cool
when ISystemState components not deleted from entity it wouldn't be recycled, so entity will have the same index and version, i guess
Yeah unity won't actually destroy the entity until you manually remove your systemstate component
But i do, well...try to do. But entity just look like this when i trying destroy it, and system can't access it
Are you trying to destroy the entity, or are you removing your component?
You need to remove the component
First i destroy it, then in system that uses ISystemState compont i do my logic and then remove ISystemState components, so entity can be recycled. All as usual
In a screen i attached Linked Entity Tag is still on entity, but it should be removed, cause this is common IComponentData
LinkDataElement isn't a state component?
If not then I'm not sure what the issue is, weird
it is
Then you need to remove that buffer before the entity will be cleaned up by Unity right?
i mean LinkDataElement is state component. And i need to remove it at "clean up" stage
I'm not sure what the confusion is here. Unity won't destroy an entity until all system state components are manually removed by you
The problem is it seems like unity is trying to remove it (some CleanupEntity component added, btw what to use it :)), but LinkedEntityTag is not remove being just IComponentData
Oh so you're saying when you destroy an entity with your state components it doesn't remove some other non-state components before your cleanup system runs?