#archived-dots
1 messages ยท Page 62 of 1
i see.. is this in the entities manual?
There is baking for the old collider + rigidbody stuff to convert but if you do it this way you will miss out on a bunch of configuration options
though it is generally suitable for basic colliders or quick prototyping
tysm
I'm still unsure sometimes what the "correct" way to implement certain operations is. For example:
I spawn an object, and need to run some post processing operation on it in another system. Do I do this by:
- creating a job that runs on entities that are missing a user component for that specific operation, e.g.
MissingPostProcessingOperation, updates the value, and adds the component with an ECB? - doing the operation immediately and sync-ing it via netcode?
- use change filters to make the system not run unless required?
- use an
IEnableableComponentto avoid the structural change from the first solution?
one way - make an event system that reacts on spawn requests
and does it on main thread
instantiation part
and then assigns all values in job
I wonder if the sync point is worth it if the number of events is low per frame
why would it be a sync point?
You are instantiating entities on the main thread
I use LateGroup
for such things
all main thread stuff is there
all scheduled stuff inbetween
I like this approach but for a lot of things I don't know how many entities I need until I actually do the "set component" part
i went from
- creating a job that runs on entities that are missing a user component for that specific operation, e.g. MissingPostProcessingOperation, updates the value, and adds the component with an ECB?
to this- doing the operation immediately and sync-ing it via netcode?
to this (and the above)- use change filters to make the system not run unless required?
i'm phasing out on initialization structural changes
and command buffer system usages
i'm trying to get as close to 0 entity command buffer system usage as possible
i've come around on doing structural changes on main thread as long as they're infrequent
and initialization is generally infrequent
it's a lot more deterministic and robust
I need to spawn and delete a lot of entities all the time so I'm not sure how well that would work for me
And like I mentioned I don't know how many there are before doing the calculations
even then you can just do it close to the ecbs on main thread anyway
You mean just running the job in parallel, then completing it?
And then spawning everything on the main thread?
just doing it in burst in isystem
(assuming minimal logic)
it really depends what you're doing
It's probably my most computation heavy part ๐
Ideally it would start running early after a structural change
well if it's computationally heavy you should be doing it as early as possible and using an ecbs probably to initialize
but why do you need to do a second pass on it?
once created
why can't you do that at the same time
What do you mean by second pass?
I spawn an object, and need to run some post processing operation on it in another system. Do I do this by:
The "post-processing" I meant earlier?
the original question
ah
That's not related to this, the first question was just more in general. The "computation heavy" thing was just an example of why the mentioned approach probably wouldn't work in some cases
But you are actually right, it would work in this case since I recently refactored it to this:
so the second part would just run on the main thread
instead of populating an ECB
It just reads all spawn commands from native streams and then writes them to an ECB
I have some things that aren't 100% clear regarding change filters since I haven't used them much though and would like to use them more:
- if I spawn an entity with a certain component, does that mark the chunk it was spawned in as changed? (I would assume so)
- if I have a single job that uses a change filter and writes to the component, and only that job ran last frame (bumping the change version), will the job run again next frame? (I would also assume so)
hmmm
I just figured an interesting approach
make some kind of stream, where you can write data in this fashion:
entity, typeIndex, componentData, typeIndex, componentData, typeIndex, componentData, typeIndex, componentData
so when you parse it you get entity index as header, then typeIndex, you figure how much more bytes you need to read and you know component type you need to set
and any amount of components can be passed this way
That just seems like an optimization for ECB
Kind of
I'm sure you can make it a lot faster if you remove some of the features it provides so you have more assumptions you can make for performance optimization
could be interesting
I just don't use ECB if I need faster ๐
I also implemented my own kind of ECB for queries
where I pass query as parameter
and enum of what to do with it
Doesn't ECB provide the same interface?
Not when I implemented this
Seems only the non-parallel version supports it, which kind of makes sense I guess
is there any resource that gives the low-level explanation of the Baking and Authoring process? i feel like most guides/videos skip over that..
doubt, even unity manual is meh
allthough
check out Turbo
iโm just creating authoring and baker scripts braindead
think of it this way
Authoring
is immutable data
you only assign it in scene
it must not contain any code
yet u can control it from the inspector?
all fields should be public
you create data from inspector
that's the purpose
for example, reference to another GameObject
this will be valid data for authoring
in Baker
you process that data, either into temporary container or into ready component
okay makes sense
if data is temporary, then your next processing layer - BakingSystem
in which you convert your data into runtime data
one thing i noticed is that Systems are always alive even when there is no authoring component attached to the game object
yes, that's how ECS works
some systems will not be in release build though
so not much to worry
i see, so in a way they are like static classes
no
Each system belongs to world
world is not static as well
you can have as many
wondering is there a good way to get systems to interact with ui toolkit stuff, like perhaps storing a pointer to the ui on a component?
You'd have to pin it and access it on the main thread only
(at that point you might as well just store a reference)
oh true, i keep forgetting references are a thing lol
๐
in all my old code i used to just use pointers, the day i found out about references i was so happy lol
Is this a different language from C#?
You generally can't keep pointers to managed types in C# without pinning them
it was c#, infact that is the only c family language i've used... I just got used to pinning pointers due to one of my early unity projects involving nvidia flex...
It's still useful sometimes in ECS, you just can't burst the methods that use the pinned references, but you can still easily schedule things in parallel as long as they don't touch unity main thread only methods
fascinating, thanks for the info!
oh, I can share one
I'v been developping it for my own projects lately
but it's WIP still
cool
If you do attempt to do this, I recommend not accessing GCHandle.Result a lot, instead e.g. accessing a collection or function that does the work for you. I had some performance issues with this on il2cpp, I never figured out why though
Maybe this was also changed in more recent versions, it was quite a while ago
i dont even know what GCHandle.Result is lol, but ill keep it in mind should i ever stumble across it
It's the managed reference behind the pinned pointer
oh ok fascinating!
@late mural https://github.com/bustedbunny/com.bustedbunny.mvptoolkit/tree/main
all right, I published it
hmm
I need to make a proper readme
otherwise it's useless
๐
oh cool!
Anyone else getting a lot of missed commands for ticks on server side when running in editor?
I even put my command slack to 10 and still getting missed commands from what I'm seeing.
I have a component that has multiple properties in. I brought it into an IAspect. The IAspect has methods in it I'm calling one from my ISystem through a job but, the Execute is not being called/
all right, I made readme, so now there's basic instruction on how to use it
On this note it seems my server is only running update on each 4th tick ๐ตโ๐ซ
Currently running into a weird issue where LineRenderers added to a prefab aren't rendering when spawned by ECS, but 3D primitives render without issue.
Although they're not rendered, the LineRenderer GameObjects are visible in the Entities Hierarchy.
Basically just added the LineRenderer at the end of this tutorial:
https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/EntitiesSamples/EntitiesTutorial
It does render properly if I manually drag the prefab into the scene though.
Any ideas as to what might prevent it from showing up when spawned as an Entity?
Not sure if you can have Debug.Logs in burst compiled code now(?), but are you sure it's not running? Do you see the entity with component in inspector?
you can
in a limited fashion, but it's fine
do you even have a single entity that matches that aspect?
hold let me do what your saying
is there any performance benefits to setting IComponentData structs as readonly?
doubt
In fact I have a feeling it won't even work
but maybe it will
now I remember
sob
Anyone knows how to change the Value of a DOTs Singelton? (like doing it in the editor)
the only way to do smth in inspector - is subscene conversion
Oh wait, let me be a little more specific. I have a PlayerGenerator generating entities and I want to change it from a UI Gameobject
then you need to figure out a way to tie your UI logic and World data
Yeah accessing Data works, but I have no idea why I how to get a SytemHandle for GetComponentDataRW or why SetComponentData not works.
var prefab = _entityManager.GetComponentData<PrefabComponent>(GetPrefabEntity());
text.text = prefab.Count.ToString();
slider.value = prefab.Count;
Ok, but why does SetComponentData doesn't change anything.
This Code does not produce any Errors, but well doesn't work:
var prefab = _entityManager.GetComponentData<PrefabComponent>(GetPrefabEntity());
prefab.Count = (int) slider.value;
_entityManager.SetComponentData(GetPrefabEntity(), prefab);
I get a very similar errors in 2022.2.0f1 and ECS 1.0.0-exp.12, Entities Graphics 1.0.0-exp.14
This is not supported when rendering with a BatchRendererGroup (or Entities Graphics). MaterialID (0x0) MeshID (0x2) BatchID (0x1)
However this error doesn't seem to actually break anything as far as I can tell. Did you find a solution for this exception?
Sentry also tells me that there was this error but everything seems to have run fine. ๐ค
Loading Entity Scene failed because the entity header file couldn't be resolved: guid=e16b810eef924d9c922185003659a43f.
it works well, and helps the compiler a lot to not generate redundant struct copies on function passes (but as for perf, if your struct is smaller than an int, then not much of a difference)
Looks like the Baker overrides the Values. The Inspector in Runtime mode shows the the right value. but my system gets every second frame the value from the Authoring Monobehaviour. Changing the Value of the Component directly does not change anything, Changing the Authoring in the Inspector works as expected
there is in attribute for same thing, but I get what you mean
easier to mark one struct as readonly as opposed to adding "in" to EVERY function call ๐
i don't think that's the case. would need to look at the burst assembly. i'd say readonly structs are passed as value when not declared with in or ref
but yes it's not possible to make every struct readonly, you need to split out the modifiable parts into a separate struct
thing is the only time we ever use the function call is within the authoring script
yeah if its in authoring scripts then frankly I dont care about perf ๐
This example is bad though. The in keyword is only useful when the argument you are passing is larger than IntPtr.Size
int Foo(in int a, ref int b)
{
a = 42; // This would be a compiler error!
b = a; // This is fine because b is passed by reference.
return a;
}
exactly, thats why its an complicated subject, agreed
TL;DR: burst figures it out ๐
another good blog: https://devblogs.microsoft.com/premier-developer/the-in-modifier-and-the-readonly-structs-in-c/#performance-characteristics-of-the-in-modifier
if burst is figuring everything out, then should i just stop gaf about everything
https://learn.microsoft.com/en-us/dotnet/csharp/write-safe-efficient-code#the-out-ref-and-in-keywords this one is better imo
yeah, thats why I think its a win in the end if you consistenly use readonly structs and in as much as possible when dealing with large structs, its definitely worth it
agreed
for example, "config-like" structs describing large swathes of data such as terrain or player data, etc is perfect for "in" but not for readonly structs...
big structs are written in one job and read in another. how should that work? i've not seen one line of a readonly IComponentData ever
so it was fun to learn about data-oriented programming (ECS + Burst + jobs) and realize this simple fact that its hard to segregate data ๐
split the big ICD up into several smaller structs (aspects help in this) and you can mark some of them readonly for some gains if you simply dont modify the values and copy over the entire struct
e.g. dont do comp.x = calcVar;
just do var s = comp; s.x = calcVar; comp = s; #or something like this
thats what the "NativeArry: a note of caution" part of the unity blog post alludes to
a ref will be faster here, instead of copying redundant data
a small readonly comp thats bigger than an int being passed to tons of recursive functions is definitely a good spot to do this
that's the oldschool way of changing data with ComponentLookup and it was slow as hell until they added GetRef
again, if you have a large struct and is only modifying one small field, then its a good idea to split it up
yeah IJE was so much easier to write this kind of code, agreed!
there's no need to split it up when you just ref it. splitting up is only a good idea when the data access can utilize SIMD
heap allocation..
what?
again, theres tradeoffs everywhere
a reference type is heap allocated and therefore slower
uhm, no? a ref is a pointer to (usually) unmanaged memory in DOTS case
isit? are we talking about the same ref?
you need to write data back anyway. all you do in the above example is allocating a struct on stack. change the value and copy the struct back to the address. the same thing can be achieved with a ref that writes the single value back to the correct memory address. saving the stack struct copy. which is slow especially when it's a bit bigger.
Enzi - I think youre correct but you missed one point in the blog - https://learn.microsoft.com/en-us/dotnet/csharp/write-safe-efficient-code#avoid-defensive-copies
if you dont have readonly structs, the compiler generally HAS to generate defensive copies, thus killing all benefits of "in"
not only killing, its worse perf-wise
like I said, its complicated - if you have a "simple" IJE that uses ref to ICDs that arent readonly, its fine
i'm not talking about in though. thought we left that topic with your example of writing data back
but for a IJE that passes the ICD to tons of functions, which might be recursive, etc etc
it definitely is bad
the ICD needs to be readonly
and about in, the burst blog post says it will figure it out. there's no reason to compare compilers that aren't even used
in is just readonly references
burst is C# eh ๐
you are posting MS docs while we have Mono and Burst
the Unity blog post alludes to this very topic in the "NativeArry" section, thus my point about Mono/Burst still using the same C# assumptions
anyway, i don't know why we are talking about writing data back and it's all about *in * and readonly
okay Enzi, u are right
"In nearly all cases, as long as the instance method does not modify the state of the struct, Burst can deduce this and remove the defensive copy:"
can't talk about 2 different things at once ๐
haha yuppie!
I think its easier to simply adopt the "readonly ICD" mentality and make it explicit which ICDs are modifiable
so you dont end up with cases where Burst fails to deduce that you dont need the defensive copy...
and its good programming practice imo
agree, idw to have to think about Burst vs .NET compiler
i'll just write everything the .NET way. shouldnt go wrong
not saying otherwise about declaring readonly. the actual usage of it is very small though. as i said before, one job writes another reads. what to do now. there's a reason burst dev team figured out defensive copies.
also readonly ref exists
what does this mean? when you say one job writes, do u mean it mutates the struct? or creates a new struct? there's a difference.
simple example. one job writes to LocalTransform.Position - another reads from it
I think wins is on to something, the subtle difference between mutate/overwrite can make/break performance
but to be honest if you simply figure out the job dependencies then burst/unity will DTRT ๐
if you really really want one job to be as optimized as possible, then the right answer is as always: profile and test!
too much mental overhead for me haha
enzi is right, magical code that DTRT most of the time is preferred to trying to figure this out ๐
thus the fun part with unity ECS compared to UE
i am still thinking about this. If LocalTransform is a struct with a non-readonly member Position, that's quite the costly write.
what are you implying here?
he means just write code that is always fast in every scenario
that youre correct - simply not worrying about this will do the right thing most of the time
but if you really want the max speed, you definitely need to worry about this ๐
there's literally no disadvantage in writing performant code. your users will thank u for every % of cpu ur app uses less.
in my case, I have dynamicbufs that I convert to NativeArrays and pass it around everywhere - thus the careful usage of readonly ICD structs that I dont modify - simply overwrite via commandbuffers
i was a driving force to get us Refs for ComponentLookups. otherwise there's a high chance you'd still have struct copies on every lookup. you are highly underestimating how much i looked into performance optimisations that goes far beyond some usage of keywords. anyway, you can have a honest discussion or continue in bad faith
oh yeah definitely I didnt realize you helped a lot with Refs! that was great stuff
is that why u made Entities.Exposed?
I was complaining that pre 0.50 entities was a mess when trying to figure out long-running jobs
and when I came back to 1.0 things started looking better
yes, i figured others might find it useful too
mmm that looks interesting
so instead of hacking entites asmref I can use EE and add my own crazy stuff?
yes, it's easier to setup. though the asmref trick is also straight forward
for some reason I dont like asmref hacking as I still dont have full control of the source
(sorry to derail the convo) so to use EE, just use latios and replace all uses of Unity.Entities with Unity.Entities.Exposed ?
Entities.Exposed just gives access to the new stuff. Unity.Entities is still needed. latios isn't required but can be used.
gotcha, makes sense! I've been wanting to add a few of tertle's awesome stuff without going through asmrefs
i think he has isolated his packages so you just have to add them to your project without doing any asmref stuff yourself
yeah but he has some code that extends EM, and thats what im really after
e.g. I want to getLookup a unmanaged SCD
should be just a matter of using his namespace then
if you just want to use this file, yes. otherwise, import the whole package in package manager
the internal folder has all the asmrefs setup
Burst is definitely not even remotely close to C#
but still it does the same thing you write in C#
There's still no way to allocate persistent memory outside of the main thread right?
no idea, but maybe try the world allocator?
That'll also be gone in the next frame
ah, yeah TempJob only
Maybe some weird threadsafe pool (if thats even possible when using the job system) of the containers you require? I don't think i'd use that approach though
I'd still need to allocate if the pool is empty and something requests an entry from it
I think I can work around it with dynamic buffers in this case though
is there a way to get a singleton entity easily without using SystemAPI but having access to SystemState?
I'm making a constructor for a struct, but cant use SystemAPI in it
Why not pass it the singleton
i guess, but the whole point was to not have to
public CastData(ref SystemState state)
{
state.EntityManager.CompleteDependencyBeforeRO<OverlapStore>();
var overlapStore = state.EntityManager.GetSingleton<OverlapStore>(); //Doesnt exist
var worldTransforms = state.GetComponentLookup<WorldTransform>(true);
var circles = state.GetComponentLookup<OverlapCircleShape>(true);
var rects = state.GetComponentLookup<OverlapRectShape>(true);
OverlapStore = overlapStore;
WorldTransforms = worldTransforms;
Circles = circles;
Rects = rects;
}
You could create a query from the entity manager and get the singleton that way
You can pass it an EntityQueryBuilder
I haven't tested for the initial alloc but resizing in jobs works fine for Lists and HashMaps
var castData = new CastData(ref CheckedStateRef, SystemAPI.QueryBuilder().WithAll<OverlapStore>().Build());
guess that works fine
Weird that GetSingleton doesn't work but the query builder does
The initial alloc doesn't work
Only Temp
what native container do you want to use?
I was just asking in general
it would, just that i need to do state.EntityManager.CompleteDependencyBeforeRO<OverlapStore>(); before
state.EntityManager.CompleteDependencyBeforeRO<OverlapStore>();
var castData = new CastData(ref CheckedStateRef, SystemAPI.Getsingleton<>);
ah okay, i think it's locked to MT for tracking. also would open a big can of worms if it were allowed
Is that an issue?
yeah i've got systems writing to the singleton
No I mean why is that an issue, completing the dependency
because i need it?
Then complete the dependency and use SystemAPI to read the singleton
you can declare RW intentions in OnCreate for singletons and setup proper dependencies. no need for completion then
yeah but then i've got to remember to do that other line when creating the struct
I'd rather have the logic contained in the constructor
You've always been able to allocate persistent in jobs
Wait really? I tried it earlier and got an error
might not be burst supported? was it a burst error? I've never tried
I only tried a native list constructor with persistent though iirc
No it compiled fine
^
From memory you probably can't generate safety handles for it
But you should be able to just malloc yourself a nice block of memory
man, I recreated a wheel (binding for UI toolkit for localization) ๐
๐
it only took a day, but at least it works
I hate the way it works though
but I hate doing codegen for Unity more than I hate the way it works ๐คฃ
The managed function Unity.Entities.World.get_DefaultGameObjectInjectionWorld() is not supported
for the line:
EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
You should not be using this in a system
Using SystemBase or ISystem?
You have direct access to em via state
ISystem
yeah, state.EntityManager
Also look into SystemAPI if you are looking for functions in EntityManager as that is the way to go now for systems. Can't use it in Aspects though
I"m using it inside of a IAspect. Should I not do that
u can pass EntityManager from ISystem into ur IAspect
IAspectMethod(state.EntityManager)
guys, is IAspect just some glorified wrapper interface with 'useful' helper functions
no
Aspect is way to combine multiple components into 1
it's all going to be multiple components under the hood
but you now only have to make 1 field
instead of 10
yeah but can't i just build my own class that combines these components
Aspect is a struct
and burst compatible
and you are literally creating your own aspects
i see
Unity codegen does boilerplate code for you
you are free to do everything without codegen though
just be ready for tons of boilerplate ๐
๐ญ
@rustic rain yeah you're correct that Burst is technically a different "language" than Mono/C# but as a newbie to DOTS it's nice to make the same assumptions and be pleasantly surprised that I don't have to do as much work to accomplish awesome stuff
well, Unity is made with unsafe codeblock assumptions mostly, so... ๐
@tawdry mulch yeah I learned this the hard way and is slowly adding aspects to make IJE and stuff much easier to maintain as opposed to having 30 ICDs in the Execute() function
even without burst some things just won't apply
true, its sometimes hard to read docs/blog posts/etc and get my head around the differences, especially when its old code the docs/blogs are alluding to...
e.g. C# 7 stuff when Unity is moving towards C#11 in 2023, etc
I had to clear my head of pre-0.5 entities stuff and old non-burst-compatible code ๐ฆ
Do you need to dispose of blob asset builders when they are allocated with Temp?
In the examples they do but i'm wondering if that has changed now?
Well i tested it and got no errors so i presume its fine
Should be fine
what is the benefit of dots
write code that runs fast and is easier to maintain
tertle have you ever declared an icomp struct readonly?
good question, i don't recall
i make a lot of readonly structs but i don't recall if i've ever done it on icd
probably not as i don't tend to use constructors no icd
yeah same here, i see a few occurances now in aspects which makes sense
though it's funny if you read: readonly RefRW<T>
pointer doesn't change. ok ๐
so basic question but is the baker the only way you can add components and mess with conversion
for example you can't just use [GenerateAuthorComponent] to add a tag anymore
Anyone else using IInputComponent with InputEvent? It seems to be completely broken for me...
Setting the input once reads the IsSet value as true 300+ times over a few seconds until it swaps back
the true / false is whether or not the system updated on the server or client
I've read the docs on it like 5 times now and I still can't find what I'm doing wrong
where is the docs for reference, I'm curious I haven't heard of inputcomponents, is this a new way to use the input system
It's a netcode specific thing
oh right, yeah I'll probably stay away from that for now
is there something wrong or are you just confused by the occurrence of the logs?
It should be true once on the server and possibly multiple times on the client as it rolls back and predicts
not 300+ times
By using the InputEvent type within IInputComponentData inputs you can guarantee one off events (for example gathered by UnityEngine.Input.GetKeyDown) will be synchronized properly with the server and registered exactly once. Even when the exact input tick where the input event was first registered is dropped on its way to the server.
registered exactly once
300+ is a bit much. what's the framerate and ping?
It shouldn't matter
is the server/client mixed in this log?
true is the server in the screenshot above, false is the client
The entire point of InputEvent is to register it exactly once when pressed once on the client
output the tick to get a better feel what's going on
You don't want to jump 300 times if you hit space once and your ping is bad
Give me a sec
It will flood my log though
300 is indeed a lot. i was having like 10-15 predictions if i remember correctly
That's fine. It should still only ever run once on the server
That's the important part
seems okay to me. true at 103. maybe the log is getting spamed so much that additional predictions are happening
The first message is from the client pressing it
The other ones are reading InputEvent.IsSet on the client and server
was scrolling down a bit
It's running multiple times on the server
does it run in fixedUpdate?
It runs in the PredictedSimulationSystemGroup, like the docs say
also helpful, color coding Server/Client
Yeah I normally do that but that doesn't translate well to notepad ๐
true dat ๐
that should be standard by now. logs without any color is so hard to read
It's really frustrating since it's a very useful feature from the code generation it provides, but it just won't work for me no matter what I try
can you show the job that reads the inputevent
I can't see anything wrong with it
mostly i just wanted to check Simulate
I think something is legitimately broken though, this is the readout from count
it's overflowing
there, I did it
can you post the gather/process input systems?
sure, one sec
wild guess, is the code gen failing?
ffs, I can't drag the file in here without explorer imploding...
might also be unity using almost 19gb of ram >_>
not sure if this is the file you meant
I also feel like either my or unity's code is leaking memory somewhere... can't wait for leak detection to work properly again
not the code gen'd ones. yours. but at least we can rule out that codegen is failing
This is the part that writes it, which runs in GhostInputSystemGroup
I posted the job that reads it earlier
this is the system
looks all good :/
yeah, absolutely no idea what is going on
also, this doesn't really seem terribly useful for finding native memory leaks
let's give up on last gen consoles
did you ever find out what was leaking? ๐
I'm having a bit of trouble trying to get the third person Rival system to work with netcode. I've fiddled with knobs enough to get the orbit camera to match mouse input, but I'm not currently sending that input to the server to simulate since it doesn't seem necessary (at first glance, at least. I'm new to DOTS/Netcode). Is it worth having the server simulate all players' orbit camera systems, or should I find a way to sync only the characters' "forward camera" rotation for server simulation uses?
Unclear how far I should deviate from the standard package contents
(I wish there was an included 3rd person netcode sample as well as the first person one, it's been relatively tricky to know all the areas to change and how to get me this far)
oh nothing was leaking
we just had high memory usage
Well mine is increasing over time, so something is up
I feel with the amount of tracking unity does on their allocators and the fact that only persistent allocators can really leak I feel like there should be more information I could be seeing...
So if I simply use a job without anything else, it will run without causing my game to stop just like a coroutine?
What do you mean without anything else?
If you schedule the job it will run until it is complete or forced to complete
I was trying to create some code which would work in the same manner
Like a background task
And I want to launch it from a non-MonoBehaviour
The jobs run on worker threads, so not on the main thread
Are jobs the only choice?
You want to run something as a background task?
Yes
You don't have to use jobs, you can also just use Task.Run
Jobs will be much faster though
I thought they were faster only in batches
And several times slower on 1-2 iterations
Isn't it so?
They are faster because they can be burst compiled
Even in case when there is only 1 iteration?
Why would they be slower than normal threaded tasks?
I dunno? Saw it in some benchmark in the web
Do you have a link?
There's no reason afaik why they would be slower than normal c# threads, even without burst
Lets just trust you
Just benchmark it if you want to know
Jobs manual is a good place for start
That's burst
This is what I get for a simple 10! function on job vs task
and that's without burst
Can you show the code?
public struct TestJob : IJob
{
public NativeReference<int> Result;
public void Execute()
{
Result.Value = Factorial(10);
}
public int Factorial(int a)
{
if (a == 1) return 1;
return a * Factorial(a - 1);
}
}
What if you change code not to have recursion? I think the gap will close
What about task code?
It's the same code
.
bruh
seems fishy though, odd that the job is 4x as fast
I guess there is a lot of work engaged in creating a thread
But Unity already has them created
guess it's a mono thing. tasks in .net 6 would fare a lot better i think. anyway, that gap is huge and that's what we have access to
@viral sonnet do you know what the point of the code-gened increment function is for InputEvent?
I don't understand exactly what they are doing
I feel like it's reading the wrong input event for a tick and keeps doubling until it overflows
@zenith garden it's also even faster with burst on
Don't wanna be toxic but it was obvious
I mean yes, it'd be an issue if it was slower. I thought you were interested in the difference
Thank you
not 100% sure as i was using a different solution back then but also found the suggestion to count the input. what i think happens is that it's counting and only applying input at count 1 or something. the code from Set and IsSet would clear that up
Set just increases count, and IsSet checks count > 0
I understand the point of the decrement system, since the count needs to go back down to 0, I don't understand what the increment system is for though
hm, that's unexpected. how and where does the decrement system run?
for it to work it must be precisely 1 at the tick where the input was taken
the counting is a fix for the case when you have UpdateInput (key is down) - UpdateInput (key isn't down anymore)/Prediction
so on frames where input is gathered but prediction isn't running
I'm not sure, the jobs are called CopyInputToCommandBuffer and ApplyCurrentInputBufferElementToInputData
the first one does increment, the second decrements
ah it in/decrements with the count from the previous tick
This is where it seems to start breaking, it reads 1 from the current value, and 1 from the previous tick, adding them to 2
this keeps happening until it overflows
that seems already like an error when the input is only hit in 1 tick
yeah, I have no idea what is going on
The weird thing is, if I do this, it works
one hit on the server and 11 on the client
It seems like the incrementing / decrementing stuff is just broken for some reason
i just found your problem. missing input = default
But then count would be 0?
Entities.WithName("GatherInput").WithAll<GhostOwnerIsLocal>().ForEach((ref PlayerInput inputData) =>
{
inputData = default;
if (jump)
inputData.Jump.Set();
if (left)
inputData.Horizontal -= 1;
//...
}).ScheduleParallel();```
eh, shit happens ๐ yes
now it works ๐ฅฒ
\o/
thanks for helping me figure it out @viral sonnet , I felt like I was going crazy ๐
something like this should also work right? I wrote a custom version before with an incrementing counter that just checked greater than since I could never get this to work
basically, the payload data will be what the client set it to the frame the input event was triggered
hm, can't say just from the struct. T is your input data? i feel like every input needs its own inputEvent
It'd go in an IInputComponentData
then e.g. command.DidACoolMove.Set(6);
seems good
InputEvent only supports bools?
looks like a good solution then if you need something else
Yeah I felt that was a bit odd, since you often need to include context when the player does something
what's the usecase?
e.g. using a specific ability
ah, right. yeah
It doesn't seem to actually work though, at least not consistently
the last number is the random number that was rolled on the client
It didn't work the first time, but worked the second time
Seems about 50/50

hm, i guess the problem is on one frame you Set it and the data but on another the payload would be lost
you'd need to make sure the payload is not overwritten
It's weird though since it seems to be an intended approach. I asked this a few months back but then never got InputEvent working so I didn't follow up and wrote my own version
when i was working on my rpg netcode prototype i expected ability spaming. cooldown and the spellcaster handled it. though you are on that 50/50, check if there's data on the DidACoolMove when it's set or if the data is 0 for you. i'm pretty sure as the whole workflow is expecting inputdata to be overwritten
yeah, i think server should work, yes?
You can see it in the above screenshot, it's set to 0 on the server, even though it was set to 6961 on the client
Note that if the server is lagging it will jump ticks if you have not specified it to be allowed to run multiple ticks to catch up which took me some time to figure out why weird shit was happening in editor x)
Weirdly it's also set to 6961 on the first prediction step, then to 0 on the following ones
It still shouldn't read diverging data according to the unity post I linked
This is what I have set
@viral sonnet I guess the "correct" way to do it would be to only reset the value once the count variable returns to 0
Or just keep the value set to what it was set to last (not overwriting it with the default)
or never reset the payload at all. not as easy as = default though ^^
Yep that's what I meant with the last message ๐
Are you running your system in GhostInputSystemGroup?
Yes
I guess something like this would be easy enough
Or even better, move the reset part to the IInputComponentData
Alright, that seems to always yield the correct value, as expected
Thanks again for the help, I'm off to bed 
good night o/
public class TestLauncher : MonoBehaviour
{
private readonly string _couroutineName = nameof(Coroutine);
private int _x = 0;
private float _startTime;
private Stopwatch _sw;
private void Start()
{
_sw = Stopwatch.StartNew();
for(int i = 0; i < NumberKeeper.Count; i++)
{
StartCoroutine(_couroutineName);
}
MyJob job = new MyJob() { Stopwatch = _sw };
for (int i = 0; i < NumberKeeper.Count; i++)
{
job.Execute();
}
}
private IEnumerator Coroutine()
{
_x++;
NumberKeeper.IncreaseNumber();
if (_x == NumberKeeper.Count) Debug.Log("Coroutines: " + _sw.ElapsedMilliseconds);
return null;
}
private struct MyJob : IJob
{
public Stopwatch Stopwatch;
private int _x;
public void Execute()
{
NumberKeeper.IncreaseNumber();
_x++;
if (_x == NumberKeeper.Count) Debug.Log("Jobs :" + Stopwatch.ElapsedMilliseconds);
}
}
}```
Am I doing it correctly?
there is little point to this test. coroutine is mainthread only. IJob is not burst compiled
Gonna compile it with burst, but how do I go about the Stopwatch?
keep it outside the job
you are also just calling execute. that's not scheduling a job
you are just calling a method
I am supposed to do it otherwise?
Do I schedule it multiple times in a loop or how? If I use .Complete then, won't it let me pass because one of the earlier calls just ended?
bruh
It doesn't say anything about launching it multiple times
well you wouldn't. but for the test case you can add the JobHandle to a list and then iterate over the list calling .Complete
{
MyJob job = new MyJob();
JobHandle[] handles = new JobHandle[NumberKeeper.Count];
for (int i = 0; i < NumberKeeper.Count; i++)
{
handles[i] = job.Schedule();
}
handles[NumberKeeper.Count-1].Complete();
}
private struct MyJob : IJob
{
public int X;
public void Execute()
{
NumberKeeper.IncreaseNumber();
X++;
}
}```
The code is so now, any idea why it doesn't work?
what is numberkeeper?
It isn't even in Burst yet
you should have an error here
i don't think you can access statics in jobs (bit fuzzy on this, i rarely use non-bursted jobs)
your scheduling isn't correct
you're not queuing jobs, and you're not running them all, you're only completing the last one
^
Even though I schedule a job it doesn't get to work if Complete isn't called on it?
You always need to call Complete on a JobHandle
job's don't start working until JobHandle.ScheduleBatchedJobs(); is called
or you call complete
(or one that is at the end of the chain of handles)
this is usually handled for you and you would rarely need to manually call ScheduleBatchedJobs
When is it called?
Somewhere in Unity's code?
every system calls this in AfterOnUpdate
Why would every system do it? Like Mecanim, does it?
system as in ISystem/SystemBase
/// <para>By default jobs are only put on a local queue when using Job Schedule functions, this actually makes them available to the worker threads to execute them.</para>
/// </summary>
[NativeMethod(IsFreeFunction = true)]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void ScheduleBatchedJobs();```
if you aren't using entities then as vertx said usually a Complete() on a chain will execute them or or you'll need to call this yourself for background work (but all jobs need to have Complete() called on them eventually as a finalizer, ideally not till they are done with their work)
What do you mean as a finalizer?
Think of a job's state as invalid until Complete has been called. The resources could be in a weird state or it might not have run to completion in some way. It tells Unity that you want to read from the job's resources.
In your code above you're not chaining the jobs, ie. you're not passing the previous job handle into the next
and you're not running complete on all the jobs. You would use JobHandle.CombineDependencies if you wanted to combine all the handles into one Complete call
Chaining would be for jobs that are dependent on each other, and combining dependencies is when they can be run in parallel
So both will work for me, right?
You're using static resources if I'm looking at this correctly, so you'd want to chain them? Though I have not paid attention since the start. It seems a bizarre setup
A benchmark setup
what are you benchmarking though?
The code doesn't really seem job appropriate, so I'd think this benchmark would be pretty meaningless
Benchmarking how it affects performance if I start doing my background tasks by Jobs
And they are usually launched only once
So I am trying to start the job only once
Something like this
As far as I understand, jobs only really become beneficial when you have your data in native collections, and they become great when you're bursting that, getting benefits from Unity Mathematics.
If you're just looking to run some logic on a thread, then jobs is not that.
I want to end with it at least.
MyJob job = new MyJob();
JobHandle[] handles = new JobHandle[NumberKeeper.Count];
for (int i = NumberKeeper.Count - 1; i > 0; i--)
{
handles[i] = job.Schedule(handles[i - 1]);
}
handles[NumberKeeper.Count - 1].Complete();```
The job doesn't even get executed once, any ideas why?
your handle logic still looks wrong
When I pass a handle into Schedule, the returned handle requires the passed one to be completed first, right?
JobHandle handle = default;
for (int i = 0; i < NumberKeeper.Count; i++)
{
handle = new MyJob().Schedule(handle);
}
handle.Complete();```
I dunno, it doesn't execute with your code either, just tried to schedule-complete a single one and it didn't work. Perhaps I need to add something else? Because my scene is empty besides the GO with the script
what are you expecting to happen
At least my debug to say that it took more than 0ms
But values aren't changed either
At the moment of the debug
Which values are you looking at?
private struct MyJob : IJob
{
public int X;
public void Execute()
{
NumberKeeper.IncreaseNumber();
X++;
}
}```
The X
It's 0
It will never change outside of the job https://docs.unity3d.com/Manual/JobSystemNativeContainer.html
Which is why this example used NativeReference
Gonna try with NativeReference
There is no such type in Unity.Collections, perhaps I need to download full ECS to add it?
As the red line suggests I have Unity.Collections
But appears you are talking about something else
is it possible to destroy all entities with a certain component, or should i just loop through all entities that have the component and destroy them one by one?
ooh thanks a ton!
its very efficient as well
nice!
really struggling to workout how to structure my game's logic, cause i have chunks i want to generate, so logically i have a chunk generating system, in charge of generating the chunks, and also randomizing the seeds, but then i also want to have a ui with a reset button, so when you press the reset button it removes all chunks, and then randomizes the seed, but then if i have a ui system, then i have to duplicate the seed randomizing method, which doesn't seem very good, but then if i merge the 2 systems it really feels like i then have 1 system doing too much, I'm having similar issues with my player's logic...
Why seed randomization is even an issue?
Just let player write it
And then get hash from string he wrote
but then how will the ui tell the player to re-randomize the seed?
With words? ๐
how?
i suppose i could store the seed randomizer as a helper method on the component that holds the seeds?
how to enable leak detection in 1.0?
Preferences, entities I believe?
and in preferences...?
๐
its under jobs in preferences
RequireForUpdateWithSystemComponent to SystemBase and ISystem to help explain that system components won't normally partake in queries without explicitly mentioning it. Does this mean we can somehow grab those entities that get created for each System?
yes, why not?
I'm having trouble with my SystemAPI.Query not picking it up. "system components won't normally partake in queries without explicitly mentioning it" makes me think those entities are hidden or something
use EntityQueryOptions
ok an important question... I am using assets and other things that I dont think have been tackled with in DOTS (like notworking libraries and such things), would dots work or will it make my life miserable?? I am afraid to use it still
I recently found out that theres a unity ecs called "Svelto".
Anyone ever used that ? I actually see no reason in using it since its way more complex than ANY other ECS i have ever used.
I mean look at all that boilerplate code for creating a world and an single entity ( theres even more code required, but couldnt fit it all inside the screenshot )
Networking libraries which are for Gameobjects I would not try to use with DOTS if you are going full DOTS.
(essentially would have to have a gameobject for each entity to use the networking, bit pointless for performance then)
If your game is built with gameobjects then the hybrid approach only really works if you can easily separate a system off and not rely on the normal unity functions
If you build your game with entities first as the "base" and use gameobjects, only when needed, on top then i think thats the best hybrid approach
(this is generally the case since not everything you want is DOTS supported so having companion gameObjects can be helpful e.g 2D tilemaps)
Thats just my opinion, others have more experience
How would I create an entity from a prefab in a baker? Do I have to use CreateAdditionalEntity and copy the prefab over the top?
you can't
basic question but how do I find whats in an entity's buffer in the new 1.0 without clicking on the entity in the scene(its an empty object so cant find it)
I'm used to using the old entitydebugger and I can't seem to find the entity in the entities heirarchy nor components nor archetypes, I mean I can find it in some of them but I can't then click on it to get the detailed inspector view
entity hierarchy
or through components window
in the Entities Heirarchy I just have a bunch of generic Entity(100:1)
type specific component name
you do c=ComponentName, e.g c=WorldTransform
Theres also a SetName function on an Ecb or entity manager
cool, that works thanks
can you use SetName in a baker ๐ค I presume you'd have to get the entitymanager of the bakerworld or whatever
to be fair, unity is hiding a lot of the same code but i also don't see the point in using it. svelto has been around before unity ecs hit so there's kind of a history. i was also turned off by the complexity back then.
I've never tried but i think you can do this _State.Ecb.SetName(_State.PrimaryEntity, "Name"); and it should work
Though be aware that there is a limit to the amount of entities you can give names (or at least in 0.51 there was, i'm not aware if that has changed)
https://hatebin.com/fkeqcrvovf
Is this a good idea to put an IComponent and ISharedComponent into a single authoring class? Or should I keep them separated and use an IAspect instead?
it's normal, nothing extraordinary. But IAspect relevance here is pretty unclear
OK how do I declare an ISharedComponentData like I do with IComponentData using RefRW<IComponentData> ex.:
private readonly RefRW<MoveComponent> moveComponent;
private readonly RefRO<AttackSharedComponet> attackSharedComponet;
public readonly partial struct ShipAspect : IAspect
{
private readonly Entity entity;
private readonly TransformAspect transformAspect;
private readonly RefRW<AttackComponet> attackComponet;
private readonly RefRW<MoveComponent> moveComponent;
private readonly RefRO<AttackSharedComponet> attackSharedComponet;
private readonly RefRW<MoveSharedComponent> moveSharedComponent;
}
I'm very very new to this...
not sure if shared comps are supported by aspects
well I guess I'm not using shared comps then...
are you aware that a shared comp acts like a groupBy?
Guys can you help me with NetworkSample pleases, I have two open editor in first one I start via ClienServer button in second editor I choose client in play mode tools and choose join. Have an error on client.
Don'd understand how server start via FrontendBootstrap scene.
#if UNITY_SERVER string sceneName = "Asteroids"; #else string sceneName = "Frontend"; #endif
this code just load Asteroid scene, but where start server code?
I remember there was a youtube video on explaining DOTS using the Boids example. It's old but still relevant. Does anyone know what I"m talking about and know the link?
Google is not helping...
iirc it was a unite stream, not 100% sure though
What specifically are you struggling with?
Just wondering but is there a max size for the native containers?
native array used to be limited to 2GB
i dont recall if that has been lifted or not
length datatype is still int, right? (yes it is, not even uint ๐ - always wonder why we are still stuck with 32bit element counts
i never had problems in gamedev with it but ML matrix calcs tend to get huge
that was one reason to ditch c# emgucv because i just couldn't get around all the restrictions from arrays ๐
Is adding a WithChangeFilter to a query not a thing?
ahh you've got to make the query first, can't do it with the builder
March 23, 1:00pm (San Francisco) - Mike Acton demonstrates best practices for component design to achieve a high degree of parallelism, minimum synchronization, and high performance. He focuses on data layout and uses common examples in games (e.g. spatial queries, logic updates, large hierarchical transformations โ both static and dynamic). Dis...
I don't suppose anyone knows what the process is for instantiating an object that has a bunch of physicsbody's as children
What do you mean?
they are un-parented in the conversion process so when I instantiate the main parent object it doesn't instantiate any of the children
Why are they unparented during conversion?
because physicsbodys are it says it right in the inspector, I guess for efficiency's sake
Also, the parenting doesn't matter, instantiating uses the LinkedEntityGroup buffer to spawn "children"
If you can add the things you want to that buffer during conversion, they should also spawn
well the children in this case don't instantiate I've checked
Yes, because they are missing from the buffer
By the way, are you sure that having a physics body as a child of a physics body is even supported?
well it kind of worked in 0.5, although I don't really have a child of a child physicsbody strictly, the top parent is just an empty gameobject
so I guess the only way is to add them all manually to the LinkedEntityGroup
That is what decides what gets instantiated when you instantiate a prefab
that's going to make it a bit more complicated because I was trying to just make a simple prefab buffer where I store all the prefabs to be instantiated
now I have to figure out specific cases for complicated objects like above
well that's it I'm already storing them in a buffer, so I'm going to have to have another, either on the buffer or maybe I will just treat all the physics body's as completely separate and store them in their own buffer ๐ค
^
You just want all of your prefabs in a buffer?
yeah
Why do you need an empty game object parent for the physics body?
well its easier to move them around in the scene view that way and I figured it would just work to instantiated the children too
Why do you want to move them in the scene view if it's meant to function as a prefab
well for testing purposes at least
If you want something to spawn immediately for testing just put it in the scene directly. The un-parented physics body will still have the correct world position
that's the object and every part of it all the items and shelfs etc has a phsysicsbody
And you want the entire thing to be a prefab?
yeah there's like 100 plus items there
You can try adding it to the linked entity group and see if that works
I don't think having a physics body as a child of another entity is supported
well it does work if I have the object in subscene, the object collapses as you would expect
Yes but I assume moving the root entity will not move the children since they have been un-parented during baking
yeah I came up against that problem before(0.51) where I had to manually move every single item to where I wanted
but this time they aren't even instantiating
I guess because the baking process is different now
@pliant pike adding them to the linked entity group works for me
It spawns all of the physics bodies
yeah thanks, it's a bit more complicated than that for my scenario
I'll probably just put them into there own separate buffer would probably be quicker to just instantiate them all from that
this error is really frustrating, I can't work out what causes it (other than something to do with the entity subscene), it happens randomly when i open my project sometimes, and crashes unity upon exiting safemode, does anyone know anything about this error message?
i don't think anyone can help you here with grpc
i dont even know what grpc is lol
i had to google it too. i know of rpc but not grpc. i don't think it's core to unity. any plugins that come with it? look for files named grpc
ill look around thanks
can't see any files anywhere named grpc in the project itself, in the actual unity engine there are a few dll's with grpc in the name though
Can i use NativeList<float4x4> for GPU instancing?
i can`t pass it to Graphics.RenderMeshInstanced
can i use Graphics.RenderMeshInstanced from jobs?
No
It has to be main thread call
Is it safe to use Burst like this?
i`m accessing local variable Material and Mesh
Burst is not compatible with managed data
Do you really need custom rendering?
yeah, i`m creating a custom tile engine
and it can render many grass objects
i`m not using ECS
the fadtest way - brg
Batch renderer group
Do you recommend using BRG or Indirect rendering for the grass objects? (Graphics.DrawMeshInstancedIndirect)
what would the equivalent method be in ecs for Quaternion.Angle()?
Never used either
sorry was away... reading it now
ah I think I got what you mean... yes I think I can do that and if I need communication between the dots classes and the game object classes I can use an action... does that sound good?
i dont understand why the dots developers make Aspects associate automagically with the entity just because it contains fields similar to the component data. itโs so jarring and confusing.
is it possible to use managed singleton?
I believe Aspects help to maintain bigger projects where number of components is quite big, and correlation between components is not that obvious. Also they are kind of bridge between classical OOP and DOD which again helps in maintenance
Yes, there is SystemAPI.ManagedAPI.GetSingleton method. For now "SetSingleton" is missing but I think it will be added in release version
wow, thank you! Never really expect to meet one static class inside another
The only purpose of aspect is to reduce boilerplate when writitng systems
You are not meant to use them anywhere else
is there anyway to create a blank native array of something? (worked it out!)
No real need for a SetSingleton of managed comps. ManagedAPI.GetSingleton already gives back a reference type. So changing the values would already change the value of the singleton.
ManagedAPI.GetSingleton in many ways is therefore closer to SystemAPI.GetSingletonRW than it is to SystemAPI.GetSingleton
If you actually look at the implemention of EntityQuery.SetSingleton you would see that it in fact is just doing GetSingletonRW().ValueRW = value.
Thanks, good to know
hm
that gave me an idea
of having managed components without tying to entities
just have a list in World and be able to pass reference from within any system
less chunks to waste
I am really annoyed World doesn't have any events callbacks though
forces to implement systems, just to get callbacks like OnDestroy
to clean up
just checking to make sure im correct, when creating a component, bools default to true right?
default(bool) = false
fascinating!
NextInt(min,max) is exclusive right?
pretty sure it is
ok, so if i do 0,1, it will always be 0? Thanks a ton!
yeah, it should also say in your IDE when you hover over it
doesn't for some reason
if you open the function source it should say in the comment
fascinating
is it necessary to put the [BustCompile] attribute on both the job declaration and the Execute method itself? (IJobEntity)
no job needs the attribute on anything except the struct
in the samples, it's in conjunction with #if directives though so, maybe it's a workaround for burst or something..
How would i use WithAll in an IJobEntity.. for example previously in an Entities.ForEach i'd do something like this:
Dependency = Entities.WithAll<MyTagComponent>().ForEach((Entity e, ref MyComponent componentData) =>
{
}).Schedule(Dependency);
I know i can pass a custom query to an IJobEntity inside Schedule like job.Schedule(myQuery, state.Dependency) but wondering if there's a similar way to the above, without including that component in the Execute() parameters
IJobEntity supports attributes as its alternative
[WithAll(typeof)]
[ChangeFilter()]
etc
Ahh okay thanks.. so like this:
Yep
I wonder if the docs should have moved away from using SystemBase and focused on ISystems.. they seem to switch between both i'd have thought it would make more sense to just focus on using ISystem but have an explainer section for SystemBase
I agree. Pretty sure the only reason you'd want to use SystemBase is if you want to store a managed reference. I use them if i want to access the main camera for whatever reason and cache it to a variable.
Also for UI systems
I think the docs should move away from using Entities.ForEach.
Also Input sampling (:
tbh i don't really like Entities.ForEach (compilation times) or the idiomatic foreach i just use jobs everywhere and use Schedule when you can't do ScheduleParallel
if the foreach supported Schedule i'd use it more
Definitely would be simpler and a lot clearer to just have one focus and run with that, rather than kinda mixing different approaches within the docs.. they can still have the information about SystemBase and ForEach etc but keep it separate to the main thrust of the Manual section of the docs.. it's just confusing.. was exactly the same problem previously with the conversion workflow, mixing info about runtime conversion and authoring approach with subscene conversion.
can put it on Managed comp and still use ISystem to process input
if i have a native collection that is a field of an IComponentData ( using for public system data ) i don't have to dispose this manually?
you have to
But how about ManagedAPI.SetComponent?
Same thing as singletons. You get a ref. So writing will write the values
Oh yeah one more thing. I notice that if u put IEnableableComponent at RequireForUpdate on OnCreate(), it will still update the system even you disable IEnableableComponent. Is that expected behavior or it's bug?
Would this be the correct way to create/dispose a system singleton component ( that holds a native container )?
are you sure? Bottom of this doc says it shouldnt https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/systems-entityquery-filters.html
Well if it's a singleton which exists at all points in your game and doesnt get destroyed until the program closes then you wouldnt need to dispose?
๐ค Then dots team needs to fix it
it will leak in Editor though
humm, i havent had any leak warnings from doing it that way
do you have domain reload?
yeah, that could clean it up
guess you could clean it up in a [RuntimeInitializeOnLoadMethod] when the domain reload if off?
uh actually no as the entity wouldnt exist
humm, guess i would need to do it in a OnDestroy
yeah, because you are not always going to have 1 world per application
in multiplayer you have multiple worlds
Expected
Any plan to change it in future? I can't completely stop system update without that.
but what if you only want to disable a few entity's
Enablable components are not query functionality
meanwhile such checks are done on queries
in order to do such check each system will have to load chunks and check it's enabled state hash
which will slow down everything
Issue has exactly the right explanation. Additionally it would force syncing, causing even further slow downs.
In anycase. Nothing stopping you from having your own Utility.ShouldRun in your OnUpdate it's not far from what RequireForUpdate does.
And at least if that's the route you go down you would be aware of the cost.
btw, is there some kind of way to check whether World has had ANY structural changes?
I got an idea for custom SystemGroup implementation, which does not allow any structural changes inside, BUT does almost all updates inside burst compiled
since all queries will be same inside this group
basic question but how do I set a bunch of prefabs in a baker system
I need them to exist in the subscene somewhere so I can get them in a query, but then I don't want them to exist in the scene after that
if I try and destroy them in the Baker system I get the error The primary entity for the GameObject SI_Prop_Shelf_Isle_Preset_Items.026 was deleted in a previous baking pass. This forces to rebake the whole GameObject. Consider using BakingOnlyEntityAuthoring instead.
its over 300 items so I can't really manually drag and drop or manually reference them all ๐
neh mind I may be able to do it in a normal baker if I loop through and get all the children objects in it ๐ค
Hi everyone, I have entities graphics 1.0.0-pre.15 installed.
I have a subscene with a cube auto-loaded. However the cube isn't rendered. Any ideas?
Here is the sub scene. Is there anything I'm missing?
Do you have any SRP setup as well?
I'm using URP 14.0.4
Yes TestSubScene has the cube in it
what happens when you press the tick box next to the name on the subscene?
That opens the subscene and the cube becomes visible but that is something different
if you can see it in game when subscene is open then it could mean something is wrong with the subscene
I mean you should see it if it has been loaded. So what is this outline? Are you sure this isn't some render debug setting you've enabled?
The outline is shown because I selected the subscene.
Also the entity should look something like this if you check in the entity hierarchy inspector
Hmm, it looks like the subscene wasn't actually loaded(?)
contrary to the information here
is it scene view or game view?
for scene view you need to tick some option in preferences
It's scene view. The cube isn't shown in the gameview either.
then subscene is not loaded is probably
But I enabled 'Auto Load Scene' on the subscene ๐ค
Any errors in the console when you tick/untick the subscene checkbox? (the checkbox in the hierarchy view)
No, but I have another idea what the issue could be. Perhaps auto-loading isn't working because I'm manually loading some other subscenes. I'm taking a short break and then I'll try fixing it again.
I just created a new empty scene from where to test this subscene problem further.
When the subscene I'm loading is empty I don't get any warnings but when I put a cube inside the subscene I get this warning.
```The referenced script on this Behaviour (Game Object '<null>') is missing!````
and when I double-click the warning this is all I get.
Were you able to find the cause of this warning? I think it might be causing me some issues.
I had that Loading Entity Scene failed because the entity header file couldn't be resolved: guid=5b6967bf99878714ab9b019f2db397f7. after build. So I cleared entity cache, deleted scene and global dependency caches. Still gave me the same error. So I closed unity, nuked Library, opened. But now when I build it says Use of possibly unassigned field 'Joint' it seems that something broke after nuking Library. Nothing about my scripts was changed in between all these attempt to build successfully...
I have a this gameplay logic where if a player walks over a specific trigger they create and become part of a crew.
The way I have this set up currently:
TriggerJob adds to ecb a new entity with CreateCrewRequestData that contains requested player to.
SpawnCrewSystem that creates a Crew and adds an ActiveCrewData to the player entity to connect them to crew with ecb.
This requires the logic to use two ecbs on the same frame to not cause a double trigger bug.
Although this is not a frequent event I would want to know how other would think/deal with such issues?
Instead of using an entity with CreateCrewRequestData, you can simply store a DynamicBuffer<AddToCrewRequest> that lives on a singleton somewhere. Requests are added to this singleton buffer, and processed by a system later. You could also use a NativeQueue instead of a DynamicBuffer if you want
So you'd end up needing just one ECB, for creating the crew entity & adding ActiveCrewData. The latter structural change can also be avoided if you make your entities always have a ActiveCrewData from the start, added during baking (if crew is Entity.Null, it means it has no crew). Whether or not this is a good idea depends on if you need some logic that updates only on units that are in a crew
Ok, so this time I would like to ask if there is a way to modify a radius of a physics shape of an entity via code?
Here's an example:
CapsuleCollider* capsuleCollider = (CapsuleCollider*)PhysicsCollider.ColliderPtr; // cast to the type of collider you have now (could be CylinderCollider, BoxCollider, etc...)
capsuleCollider->Geometry.Radius = 1f; // edit the Geometry of the collider
Thank you for the input! : )
Regarding the buffer approach, this would require a system to always be running & checking though? But maybe the overhead for this is neglectable.
Regarding having empty ActiveCrewData I've considered, but you would still need to run through an ECB to update its entity reference form the newly created crew, but I understand the benefit of not doing structural change there : )
this would require a system to always be running & checking though?
Yes, although since it's only one buffer length check per frame for the whole game, I wouldn't worry about it
Since joining a crew sounds like a fairly rare occurence, I actually think your original approach might be preferable still. In order to avoid triggering this 2 frames in a row, you could do:
- During fixedStepSystemGroup, the trigger is detected and the
CreateCrewRequestDatagets scheduled to be created via ECB inEndSimulationECBSystem - A system after
EndSimulationECBSystemprocesses theCreateCrewRequestDataand schedules the crew entity &ActiveCrewDatato be created via ECB inBeginSimulationECBSystem
So you're re-using 2 existing ECB systems, and all changes would be done before a new physics update has had time to run.
Another option:
- have your ECBSystem where the
CreateCrewRequestDatais created - create crew entity & add component on player immediately in bursted main thread system, while we're at it
It throws a lot of errors when I try to use it
Add unsafe to the method where you're doing this
You might have to also enable "allow unsafe code" in project setting, or in your .asmdef if you're using one
Well, after that I'm still left with "Cannot modify the return value of 'CylinderCollider.Geometry' because it is not a variable"
could anyone guide me through how to create a subscene via code? i've tried:
EditorSceneManager.NewScene, SceneManager.SetActiveScene, add GOs, EditorSceneManager.SaveScene, EditorSceneManager.CloseScene, new GO with SubScene, AssetDatabase.LoadAssetAtPath<SceneAsset>. -> scene is closed and i'm getting tons of ecs errors.
@frigid crypt oh my bad, try this:
CapsuleCollider* capsuleCollider = (CapsuleCollider*)physicsCollider.ColliderPtr;
var capsuleGeometry = capsuleCollider->Geometry;
capsuleGeometry.Radius = 1f;
capsuleCollider->Geometry = capsuleGeometry;
Check here, there is paragraph "Modify physics collider" https://docs.unity3d.com/Packages/com.unity.physics@1.0/manual/physics-collider-components.html
Thank you for more input!
So I can use the existing ones for sure. I don't like putting something after "end", so I would either use initialization system group (Which I doesn't feel fit naming as well ._.) or a new group (which I am using right now).
Can you elaborate what you mean with having the ECBSystem where it's created? Do you mean to use the update of an ECBSystem and create & playback an ECB myself?
I just mean: pick whichever ECBSystem you choose to use in order to create your CreateCrewRequestData, and then add you main thread bursted system that handles the rest right after it
Still can't see anything that would allow me to change the radius (or size in general)
@signal phoenix i didn't know you worked at unity. that's awesome! remember when you wrote your own physics engine poc before dots physics came around ๐
Is the new unity entities system API not slower compared with the previous one ?
foreach(var (position, velocity, ...) in SystemAPI...){ // <-- Here is one struct being created and returned for EACH row
}
It will create and returns one struct with other structs for EACH single row.
Furthermore enumerators are... slow since get_current will mostly not be inlined.
Atleast those are normal c# problems, so is it slower compared with the old API ?
i have a perk buffer, each element stores a description and a cost, whenever something needs a perk it picks one at random from this buffer, so now im wondering how would i store the perks behavior? As a list on the element, where each index in the list represents a variable, and what to + or - from it, or is there a better way to design this sorta thing?
that's why SystemAPI.Query supports RefRO/RW. it's not slower. I think it was said it's a bit faster than Entities.ForEach().Run() but not by much. enumerators are not slow per se. they are slow when the element is returned by value. also, all this can be burst compiled.
and SystemAPI.Query is code gen'd so it's pretty optimal for what it is. that said, it's not a job and stalls mainthread so it's not great to begin with and not a true substitute for Entities.ForEach which can be scheduled single or parallel
hehe, hot take from JBlow
Today, nobody even attempts to write graphics engines, so programmers needed to find a new way of ratholing on an engine and failing, while maintaining plausible deniability that they were doing cool work; they converged on ECS as the new, more-tractable method of self-sabotage.
๐
Indeed, just use the off the shelf ECS option ๐
yeah i think ECS is a big team effort. maybe even more complicated as an engine itself because results are not as tangible (right word?)
although i wasn't aware, nor do i believe, that it's actually a new cool thing to build ECS on top of engines. unity, unreal have one. maybe all the godot devs builds ECS. ๐คทโโ๏ธ
(of course there are more engines but those verge on the edge of obscurity in todays climate)
Can i use IJobEntity with multiple components?
Transform and another component? how?
You can pass any number of components in Execute
If that's not the problem, you'll need to explain the issue a bit more
at first glance that looks fine
do i need to call dispose like this?
is it efficient? allocating a list for every entity
looks so heavy
ok first issue
you can't use TempJob within a job
you can only pass it into the job
you should be using Temp inside a job
and if you are Temp you don't need to dispose it
it's /ok/ but it's not the most efficient thing allocating per entity
if you want to make it more efficient, you can allocate per chunk instead
