#archived-dots
1 messages Β· Page 9 of 1
{
Value; // entity.index / 8 for example
}```
was best i could think of
but yeah needs unmanaged shard components
CDFE is really fast, it still has to do this every time return ChunkDataUtility.GetComponentDataWithTypeRO(m_EntityInChunkByEntity[entity.Index].Chunk, m_ArchetypeByEntity[entity.Index], m_EntityInChunkByEntity[entity.Index].IndexInChunk, typeIndex, ref cache);
m_EntityInChunkByEntity[entity.Index].Chunk could be totally cached if you access several comps of the same entity
same goes for archetype
before i start doing anything weird. i should improve on this in my CDFE extensions
when you know the chunk and archetype, it's nearly a direct lookup
i suppose this will be a cache hit on the 2nd lookup but still.
talking about the previous thing. chunk DBs woukd be great
can you design the system without the need to keep them referencing each other?
i could merge the data but that has (worse) performance implications that i want to avoid
hm this collisionFilter isn't working: BelongsTo = (uint) 1 << (team + 2), // offset the teamId, CollidesWith = (uint) (0xffffffff & ~(1 << (team + 2))), any clue what's wrong here?
should hit everything except the own layer
i think you might have a better time
using GroupIndex as team
unless you use GroupIndex for something else?
actually i guess it depends if you are doing actual collisions
i forgot we aren't so this works very well
i haven't figured out the groupIndex yet. i basically need a collisionFilter that either targets the other team or its own. does that work with the groupIndex?
If the value in both objects is equal and positive, the objects always collide. If the value in both objects is equal and negative, the objects never collide.
it's pretty useful
hm, yeah. the comment confused me for the longest time π it's more simple than i imagined. i'll test it out. still no idea why the above isn't working. the bitmask should be correct. π€
well, i still have no idea what the thing about positive or negative means
yeah, actually i'm still confused π
so what would be a collisionfilter to get the colliders from the other team?
does groupIndex interact with belongsTo/CollidesWith?
oh there's the code below for IsCollisionEnabled. that answers at least some of my questions
yeah just look at the code
i think the important part for your issue above is
(filterA.BelongsTo & filterB.CollidesWith) != 0 &&
(filterB.BelongsTo & filterA.CollidesWith) != 0;```
it must collide both ways
what is ScheduleByRef and RunByRef etc all about?
if you have really large jobs
can be a slight performance improvement
in general, i would not worry about them
i had a pretty big job struct at one point and i haven't seen any difference. no idea what it's really used for and how big a jobstruct is supposed to be then
is there a way to query for entities where a field on a component is a certain value?
nope
For what reason would _directiveSystem.Update(); not trigger the SystemBase.OnUpdate event? Or am I misunderstanding this?
typically system is not running. And once in a while I need to manually wake it up if since no queries are met. Trying to avoid AlwaysUpdateSystem attribute
Can't you just define requirements to run?
Oh wait
It must run
And call on update
Yeah I thought so to, but logs say different.
_directiveSystem = World.GetOrCreateSystem<DirectiveSystem>();
Hmm
I got my reference by iterating system's list
Maybe that can be potentially a case?
Allthough doubt
I don't know. This method is used by Unity in docs. Seems to be the norm.
OnUpdate won't run if you aren't meeting requirements to run system
such as system is disabled or there is no query with matching entities
{
// ...
if (Enabled && ShouldRunSystem())
{
// ...
OnUpdate();```
Hmm
Oooh
Now I get why my system's run
They didn't run because they are part of togglable system which simply stops updating them
So manual update worked like expected
is entitymanager slow?
things like creating entities, setting component data etc outside of systems
no
it's the fastest way possible for single entity
combine it with burst
using ISystem
and it'll be even faster
what if its not an ECS system
Yes they do World.DefaultGameObjectInjectionWorld.EntityManager
what I mean is
I have some code that executes scripts via reflection
EntityManager is the fastest solution for single actions
ik the reflection will take a hit to perf
alright awesome
and then entities.foreacch is fastest for multiple actions?
will using : ISystem on the scripts be relevant tho?
even tho they will just be calling functions that will call another dll
can burst optimize reflection?
no
burst only works with value types
and if you want some random bursted action
it'll only work with pointers
to those values
foreach is just job
behind codegen
what it does:
Creates IJobEntityBatch struct with your code
Grabs all relevant to query chunks, gets all components
And then runs your lambda code on those components
you can always iterate chunks manually btw
I do it sometimes, when I need precision regarding chunks
just take a look at examples of IJobEntityBatc
this is what Entities.ForEach under the hood
awesome thank you!
Is there anything like continue that I can use inside entities.foreach?
you can early exit the current iteration with return.. so like if (dist == toofar ) return; then it'll continue with the rest..
Hey, how can I change PhysicsMaterialTemplate of an entity through code? I want to change it physics once on trigger, but i'm not sure from which component can I get the reference to change it
well the template is just a bunch of properties, for example filter, which can be accessed and changed through the physics components inside jobs
which properties are you looking to change?
Filter, Friction, Resitution
This is old code but it shows how to change filter of a collider:
Ok cool i was thinking that exited the entire iteration
var relevants = relevantQuery.ToComponentDataArray<RelevantComponent>(Allocator.Temp);
var chunks = relevantQuery.ToComponentDataArray<WorldChunkComponent>(Allocator.Temp);
var entities = relevantQuery.ToEntityArray(Allocator.Temp);
for(int i = 0; i < entities.Length; i++)
{
chunks[i].val = 322;
is something like this valid or will I need to use entity manager to actually set the values of the component?
ToComponentDataArray is a copy
General rule of thumb in C#
To = copy
As = reinterpret (direct access)
chunks[i].val = 322;
also pretty sure that is a compile error as it's not ref returned
ah yeah i have to do new and assign a new value to the index of the array
there is no AsComponentDataArray so I guess I will need to use entity manager then or is there a way to get direct access?
you need ComponentType handles
oh wait
hold on
are you working with actual chunks, or?
confusing naming
relevantQuery = GetEntityQuery(ComponentType.ReadOnly<RelevantComponent>(), ComponentType.ReadWrite<WorldChunkComponent>());
}
protected override void OnUpdate()
{
var relevants = relevantQuery.ToComponentDataArray<RelevantComponent>(Allocator.Temp);
var chunks = relevantQuery.ToComponentDataArray<WorldChunkComponent>(Allocator.Temp);
var entities = relevantQuery.ToEntityArray(Allocator.Temp);
for(int i = 0; i < entities.Length; i++)
{
chunks[i] = new WorldChunkComponent
there is CopyFromComponentDataArray to write back
so would doing that mean the values written to chunks[i] will be reflected since I have readWrite on it
Because you can't call sceneSystem.Loadsubsceneasync in entities.foreach
oh is that what you're trying to do
just load it via components like I do?
this.CommandBuffer.AddComponent<RequestSceneLoaded>(batchIndex, entities[i]);
foreach (var section in resolvedSectionEntity.AsNativeArray())
{
this.CommandBuffer.AddComponent<RequestSceneLoaded>(batchIndex, section.SectionEntity);
}
// Unload
this.CommandBuffer.RemoveComponent<RequestSceneLoaded>(batchIndex, entities[i]);
foreach (var section in resolvedSectionEntity.AsNativeArray())
{
this.CommandBuffer.RemoveComponent<RequestSceneLoaded>(batchIndex, section.SectionEntity);
}```
I tried doing it this way but had no luck. Care to share some more of your code? particularly entity creation?
or are you just letting them exist from the world start and iterating over them?
I have a system that in OnCreate
foreach (var subScene in Object.FindObjectsOfType<SubScene>())
finds all subscenes then loads them (but not auto load, just creates their entities)
this.EntityManager.AddComponentObject(entity, subScene);
waitingForLoad.Add(entity);
if (subSceneLoadConfig.LoadingMode == SubSceneLoadMode.BoundingVolume)
{
volumes.Add(subSceneLoadConfig, entity);
}```
disables updating until the subscenes are loaded
so i dont need to add requireforupdate for all my setting files in systems
could I see the query you're performing before execcuting this code?
this.CommandBuffer.AddComponent<RequestSceneLoaded>(batchIndex, entities[i]);
foreach (var section in resolvedSectionEntity.AsNativeArray())
{
this.CommandBuffer.AddComponent<RequestSceneLoaded>(batchIndex, section.SectionEntity);
}
this.subsceneQuery = this.GetEntityQuery(ComponentType.ReadOnly<ResolvedSectionEntity>(), ComponentType.ReadOnly<LoadWithBoundingVolume>());
wont help much
this is my in range subscene system
if a subscene has the RequestSceneLoadedComponent that means the subscene is loading or already loaded?
yeah subscenes are basically just loaded when RequestSceneLoaded is added
and unloaded when RequestSceneLoaded is removed
alright awesome
are sections related to position in the world or is it sectioned off by some other data?
you'll have to very specifically add sections yourself
you probably won't need them
i think the only use i know of atm that they are used
is for HLOD
unity uses them to split that or something
wouldn't you get better loading speed if you had one huge subscene that only loaded sections relevant to you?
what benefit does that over having lots of subscenes
and only loading subscenes that are relevant to you?
so wouldn't doing this mean that the entire map is chilling in my ram?
ok
data is only loaded when you put RequestSceneLoaded
i have an extra script i attach to subscenes with a few options
that sets the mode to autoload (synchronized optional), load from volume (distance from player/s) and on demand which are basically just manually triggered from other sources
above code was from the volume path
thats a good idea, I might steal that from you
can I add arbitrary components to the subscene entities themselves then without messing up the SceneSystem?
yeah
Where are you getting AsNativeArray from?
it's just part of dynamic buffer
So each entity for each subscene has a ResolvedSectionEntity component and a dynamic buffer of them as well?
all converted in one environment = less total size of serialized subscene
not an issue for PC (mostly), but is a bit important for mobile
that's not always a good thing for memory
addressables is specifically designed to duplicate assets to allow unloading
So uh does this mean duplicate assets are duplicated in mem with subscenes?
havent dived into profiling memory that closely with subscenes because i haven't had to
noice brought my targetInfoSystem down from 2.2 to 1.2ms. all data is now local to the entity. CDFE writing was killing it.
didn't even realize it's that bad because a write is costly anyways. BUT a random write. ooof
ahh
yep CDFE is bad mkay
Thank you
oh and take a look at ITriggerEventsJob. i find this a bit easier to implement
Btw I think this might be a little dif then what I am looking for... I am looking for basicly OnEnter and OnExit
does not need to be actual events
What are your loading params? because this is not working for me. I add the RequestSceneLoaded component like in your code and nothing happens.
var e = sceneSystem.LoadSceneAsync(pair.Value, new SceneSystem.LoadParameters()
{
AutoLoad = false,
Flags = SceneLoadFlags.LoadAsGOScene | SceneLoadFlags.DisableAutoLoad
});
I suspect I need to get rid of the loadasgoscene flag but then nothing from the scene renders. maybe a problem with conversion if that is the case?
basically, unity.physics is stateless so it doesn't record or keep track of previous or future states, and so doesn't have OnEnter and OnExit etc.. what that means is you need to implement your own, in other words keep track of when a collision first occurs for OnEnter, then take note of when that collision stops happening for OnExit..
the unity physics samples has an example of a stateful onenter/exit system, where it uses 'events' to keep track of these things
it's kinda complex and not the fastest system but you can use it as a basis for doing that
so if you look here, this is the custom event ( implements ISimulationEvent ) they use with enum to store 'state' ie enter/exit:
https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/PhysicsSamples/Assets/Demos/2. Setup/2d. Events/Scripts/Stateful/IStatefulSimulationEvent.cs
just to point that out in addition to what Enzi linked above
I am fine with handleing all of that my self and planned to actually. I just need to know how to say are 2 things currently colliding yes no in a system
or better yet are any of the entities with Tag FooBar currently colliding with anything
structural changes are costly
keep it in mind if you have a lot of things that will collide and create trigger events
what ways are people using to destroy a lot of entitys π€
it seems a bit excessive to use an ECB to add a component to those marked for death and then another for destroying them
I think the only supported way is to use events tbh.. otherwise the physics system doesn't expose any of the collisions.. this is just my understanding so far though. Alternative is manually do collider casts and check the results. Afaik there is a way to register 'callbacks' during the solver phase which allow you to inject modifications to simulation behaviour, so i mean maybe that's a possible way, but i'd probably guess that's not very fast.
destroy by Query
yeah I still need to know which ones to destroy though
how do you figure it in the first place?
I'm currently just doing it immediately on health equals zero with entmanager
but that's not going to work well later for efficiency reasons
entity destruction pipeline is actually a good thing
yeah I guess I'm just trying to figure out where I want the bottleneck to be
do I have a destruction system that searches through all 10,000 entities to find the ones to destroy or do I do it another way π€
I mean
you could potentially make a pipeline for health changes
so anytime you change health to smth
you also check for 0
and if it is 0 you attach destroy tag
alternatively, you do queries based of Change version
which would make searches over 10k entities faster
yeah to be honest I don't want to use an ECB for that part because they are kind of slow
kind of
you don't always have entities to destroy, aren't you?
meanwhile doing 10k loop
on main thread
seems way worse
unlike doing 10k loop on one of 16 threads
yeah I guess I might try systemstate component with a boolean π€
that works too
having state component with data "dead" or "alive"
but
you will have to make some kind of random access for it
otherwise if you just ref it
you'll change version
no matter if you write to it or not
huh?
I wonder if ComponentDataFromEntity with write access changes version if you don't write to it at all
ChangeVersionFilter
you check whether chunk has been written on selected Component
if it wasn't written
why check chunk at all?
I've never used that, interesting, I might try that, thanks π€
@rotund token do you happen to know whether ComponentDataFromEntity affect changes filter of all entities, or only of chunk you read/written to?
ok that's weird its not even adding the Isystemstatecomponent π
yeah its weird a normal component adds fine in a IConvertGameObjectToEntity but not an ISystemstateComponent
dont think you can add a systemstate component in conversion
the problem with death states is structural changes and often some postprocessing. so a bool comp works quite well. the destruction can then be delayed and a change filter can trigger on death state comp changes
that also requires some good change filtering so you don't have to check the deathstate mitiple times for each frame
it just bumps the version of the chunk
it doesn't
no system state components in conversion
just add normal
no need for state
Well that's annoying
you are not the first π
not that I'm counting but you are the 4th who criticises that π
I'm pretty sure you can use system state components in conversion, just not incremental. You must rebuild your entire entity cache for the sub scene on every change if you use system states
Pretty sure. I saw the warning and I noped out real fast.
According to manual state components get removed before copying into active worls
They only exist in dst conversion world
How would one find where or how a structural change is coming from. I have one that I'm doing little if anything before yet it's giving an error when I call a GetComponentDataFromEntity using an entity pulled from a NativeList. I hardly even understand what constitutes a structural changes so I'm not even sure where to start since I've done a bunch of Debug.Loging to figure out if something is invalidated early on but nothing seems to be...
DankeschΓΆn, seems I just needed refresh my GetComponentDataFromEntity... ( ;-v-)
I will keep the structural changes in mind as I develop, not exactly something I normally have to think about :P
Hi. Is there any way to avoid dots TransformConversion which decouples standard Transform monobeh into several components (local to world, translation, rotation). I'm going to use hybrid approach and use standard Transform as entity component and just want to get rid of unused resources.
it's not avoidable but you can remove the comps at the conversion stage
just dstManager.remove
you cant avoid create/destroy but add/remove comps should be avoided. 0 is best
I have absolutely no RemoveComponent or AddComponent calls if that's what you mean. But even then, how would tags be used if you can't use Remove/Add component calls? I understand ftmp why ofc, but having absolutely none seems hard with larger scale and complex projects.
Add/Remove component calls for components that last for a while at least.
Would just completely recreating the entity be a better option in that case?
the short answer is, you don't use dynamic tags π at least not for now. unity will improve on this in entities 1.0 with enabled/disabled state for comps which shouldn't be too far off now
recreating is basically what happens. add/remove comps will memcpy the entity to another archetype/chunk
Interesting. If the new component will (theoretically) last for the rest of the game, would it be okay to add/remove components or recreate the entity?
Hahahahaha
That's in a GameObjectConversionSystem. Removes the default transform components from everything.
I've made it work in IConvertGameObjectToEntity monobeh. But thank you for pointing me to a more universal approach)
sure, very rare adds/remove are okay. the problem is that it will create a frame spike. if you keep it low enough all will be good
Ah, gotcha. So no mass add/remove but now and again for long-term is more okay.
Kinda. It depends. If you can mass add/remove for entire chunks, it's pretty cheap.
Rule of thumb is to avoid structural changes, almost at all costs. There are cases where it's preferred, such as when you can do so for entire chunks at a time.
just avoid changing state every frame
Always, always, turn on the profiler to see if what you're doing is having any impact.
Just multiply the expect number of entities by 100 or until you reach 50,000 to get decent measurable and comparable performance values.
yep, i agree with all that
so don't use comps as kind of event. that will bite you in the ass sooner or later
i say that because most, me included, start with that kind of approach
I've been using them as a RequireSingletonForUpdate<> and it hasnt been a problem, so far at least.
tertle, have you ever used amd uprof?
Can I prevent converting specific monobeh into component in ConvertAndInjectGameObject mode? I have a lot of binders which create an appropriate dots components and bind them to parent entity.
I have never heard of IEntityBinder
It is my custom interface)
Ah, you might need to call conversionSystem.DeclareAssetDependency(mo.transform)
system based events is clever design π
damn blob data is the bane of cache misses π¦
Isnt blob data stored linearly though?
yeah but access is random
Well, that's just random access
i don't really know why it's missing that hard. i access the same blob 250k times. you'd think it's in the cache
Cache is only 64 bytes wide. It cant fit much,.
cacheline, L1 is 32k more than enough that it should stay in L1 while the iteration is going on
It can fit maybe a struct (for 3D) or two (for 2D, which is why I'm wasting so much time on my own physic engine
the problem is that monobeh TransformHolder is also in the components list but this monobeh is used just for setup ECS components purpose and doesn't need to be existed in runtime, any idea how not to add them when converting GO?
Hrm, I guess you dont need the declare. Check the docs on conversion for all (most) the answers https://docs.unity3d.com/Packages/com.unity.entities@0.51/manual/live_conversion.html
I think the cacheline is shared among all applications. So even if your entire blob can fit inside the cache line, unless it's pretty small, other applications are taking up it's share as well. Unity editor itself is a hungry app.
i've profiled in a build but sure, many things are running
nope
might surprise you but i actually barely profile
hehe, well, just want to say it's a great tool and worth a look when you are on amd
i just try to write my code in a way that i know is fast
when a system is done i have a quick look at unity profiler to make sure it meets my expectations and needs
and then i move onto something else
hm, i think i want to memcpy a blob to test something. is there already something in place?
no idea how to get the actual size
this looks good
sum of sizeof the structs used to make it * their counts.
Sizeof just gets the size of the struct, not the actual size of the array
If blob asset header was 2 ints, sizeof will return 8.
I think that might work
nice skills π
yep that's the problem. it's a lot of counting, BlobPtr, the struct if it exists. BlobArray, the elements, etc...
Gonna be fun, good luck.
that's why i posted the above code. length seems to be stored in the header. they need to know when serializing
I give up. Im just gonna copy paste Unity's BVH.
They clearly know what they're doing.
is there a reason why you had wanted to create your own?
Unity's physics is not stable due to supporting 3D collisions. 2D collisions can be stable when sliding across each other and circles are geometrically accurate using radius and pi, rather than a cylinder's mesh.
stable as in vibrations, not the code issue.
Even if you lock rotation and lock the Z axis, the generic math optimizing 3D triangle mesh collision solver results in poor collision realism.
Unity's BVH construction is brilliant. Far beyond anything I can code. But once I nail it down, I'm going back to trusty Box2D and pulling their collision solver.
Box2D had the original physics BVH construction but singlethreaded and not quite vectorized as Unity's. So I'm basically copy pasting Box2D and trying to merge in unity's BVH. And why? Because unity fired everyone working on 2D so they wont do this themselves despite being incredibly easy to do so.
In 3 or 4 years they'll probably do it and when that happens, I'm deleting my physics folder and transferring to a Unity supported platform.
physics is scary
It's still a good educational opportunity. Knowing how to construct a BVH is pretty key for any graphics programmer... despite not being one or entering a field remotely close. But still nice to know as a hobby.
I have spent the good part of a year implementing isosurfaces in dots but havent needed BVH
yet
It's a black box in many engines. Take a moment to peak inside and you'll learn a lot about how to design your game that works with the physics engine instead of unknowningly against.
Im just hoping DOTS physics can handle stuff rolling down the hill, calculate hit for weapon swing
Probably... should. It's a very good 3D physics engine.
the parts I dont want to think are the time it takes to load a collision mesh
It does make some questionable choices in the quest for stateless deterministic but still good.
how can 2 profilers show timings for a path that's not even executed? π
Well, if two profilers are saying a path is executing, maybe it is.
Well, for one, Unity's BVH singlethreaded builder phase is a lot more purple and VP* than mine. So props on them.
Hrm. Well first run of the copy paste code didnt work so well. It uhhh, hard crashed unity.
@viral sonnet Cries in inferior comp. Copied line by line from unity.
hehe
so I think I figured out what's happening. the code paths are very similar so burst just merges them and aligns the jump. for some reason the pdb or whatever doesn't get that though and it's always highlighting the line if (targetTeamId == ...)
i'm now questioning if these tools currently are wasting my time ^^
Personally, I dont use any of the per line or per operation timing tools. I just stick a profiler marker before and after a job. Measure the performance over 100 frames average on play before a change, then measure again after. The difference should logically be the result of the change then.
i am months past this point π
I wouldnt know specifically what the change did to result in the performance increase or decrease, just that it works or not. Simple enough for me.
now I'm more into which trade offs are for the best
i think i can make some nice optimizations to CDFE π fingers crossed
not sure how to do it right now because this damn data i need is private ...
{
return ChunkDataUtility.GetComponentDataWithTypeRW(m_EntityInChunkByEntity[entity.Index].Chunk, m_ArchetypeByEntity[entity.Index], m_EntityInChunkByEntity[entity.Index].IndexInChunk, typeIndex, globalVersion, ref cache);
}``` curious, they are looking up the archetype of the entity when the chunk already has the archetype*
does it hugely matter though?
it's an indexer not a hash lookup or something
but yeah this is only done in the cache version
it's done as you say for normal lookup
sheet, i need a better testing ground. i just realized i've brought this down to 1 CDFE lookup to get the target stats ptr.
performance test it is π
what the hell, GetComponentDataFromEntity is internal in EntityManager?
how am i supposed to get this in a performance test then? i'd need a systemState
as expected, it's not too big but it's something. 1mil entities, 4 lookups
I don't suppose anyone knows what Solver.ParallelSolverJob is in the profiler
because I have shedloads all over the place
yeah I think you may be right I turned on flow events and that seems to indicate it
that was working at some point var hitEntity = closestHit.Entity; Debug.Log($"hit {hitEntity}"); now it outputs hit Unity.Entities.Entity what happened?
Maybe try HitEntity.toString()?
that's managed. i mean it worked, like it was written. pretty old code
ToFixedString works. weird. must be something new in 2021.
having a really bad day with weird shit InvalidOperationException: The previously scheduled job Broadphase:PrepareStaticBodyDataJob writes to the Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] PrepareStaticBodyDataJob.FiltersOut. You are trying to schedule a new job HybridTargetPicker:HybridTargetPickerJob, which reads from the same Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] (via HybridTargetPickerJob.JobData.collisionWorld.Broadphase.m_StaticTree.BodyFilters). To guarantee safety, you must include Broadphase:PrepareStaticBodyDataJob as a dependency of the newly scheduled job. what's up with that? previously it complained about writing to collisionWorld where I forgot the [ReadOnly] tag so explainable. this one though. no idea what this is about. it's a simple raycast. collisionWorld.CastRay(input, out RaycastHit closestHit) what's that about writing to collisionFilter?
and I register the system protected override void OnStartRunning() { this.RegisterPhysicsRuntimeSystemReadOnly(); } usually that fixed weird dependency problems
and that's why i hate automagic stuff. it failed me. the job was scheduled with no dependency -.-
Here's a semi-completed IJobEntity example using aspects in the current dev: https://github.com/Unity-Technologies/DOTS-training-samples/blob/dots-training-2022-07-eu-group4/Original/JumpTheGun/Assets/JumpTheGun/Scripts/Systems/BoxPositioningSystem.cs
I am 80% to the point of writing my own roslyn code gen to make a IJobEntityBatchGen that passes in NativeArrays instead of ref variables.
It cant be that hard, right?
what would be the difference really?
less having to write GetNativeArray and then linking up the GetComponentTypeHandles
they use TransformAspect, not as ref but writing back?
guess you could copy the IJobEntity implementation
The aspects have the RO / RW barriers on the struct property itself.
Yea. Dont know where the source is for the roslyn gens itself though
Shouldnt be that hard to just put something together though.... shouldn't... But i just dont like having to open up and then compile a second project just to get a gen spinned up.
just add it as a package then
source is mostly here com.unity.entities@0.51.1-preview.21\Unity.Entities\SourceGenerators\Source~\JobEntity
Nice. Give me a sec
oh my god
im dead
and there's a base IJobEntity.cs at com.unity.entities@0.51.1-preview.21\Unity.Entities
i've setup quite a few times pointers to some comp for fast access without lookups. this current one i'm setting up. it's just not working right. i only run the code with DidOrderChange but then it's not working. when i run every frame it's okay. now i thought, okay, the other entity goes through some structural change I'm not aware of. just flip the direction. same thing. π¦
i dunno about this codegen. i'm really fast with copy/paste so in like 99% i don't care about it π
Yea, but just looking at the ease of IJobEntity but sad about it's performance
Also, this is why IJob is not burst schedulable:
there's a performance hit??
Just doesnt play well with burst.
ahem
it is bursted for me
Impossible. Show me the system
I think...
It's literally using typeof() and (object). Both are managed.
Things like the mem calls are not reliably recognized by burst. You need to do them yourself. And you cant separate for loops to maximize vectorizations.
Like these two for loops are separated. The first is recognized by burst as just 2 float4s and is combined into a single VP operation per line. The second requires a conditional and thus doesnt vectorize. IJobEntity does not allow for this type of coding since it only passes in the ref of a single element.
i don't know why they bother so much with codegen. someone on the team must have a real knack for it
Code gen is great. Cuts down on the boilerplate. Which is GetComponentTypeHandle and then GetNativeArray
They just need to offer a code gen'ed IJobEntityBatch that is basically IJobEntity but walks back one step.
IJE is great for the casual coder who just wants some performance but not all the performance.
how would it look like?
casual coder and dots ... haha
Instead of the ref and in of a single struct, it's [ReadOnly] or not NativeArray<Component>
Or pointers and then BatchInChunk.Count for length.
Unity is coding for the 12 year olds, and the 45 year olds who have been using OOS for 30+ years.
ugh, don't really get why reference values are a problem
You cant do mem operations (memCopy, memClear, etc) and if you know for certain that it's a multiple of 4 or 8, you cant manually vectorize.
why would you want to do mem operations xD
I'd guess it's like the latest thing you want to do
and that's what Unity wants to avoid devs from using
by providing other tools
MemCpy, MemClear, MemCpyStride. All orders of magnitude faster than just a for loop set equals to if Burst fails to recognize.
And burst, despite how amazing it is, is not really that good at recognizing array wide operations if it's embedded inside a lot of other code.
can't you just do &yourValue in job?
Yea, but that doesnt stop the rest of the Execute(ref yourValue) from occuring.
And that results in calling MemCpy over and over again. Along with the need to pass in the batch count which, if you're using any subdivisions, can not be guarenteed.
I think you're just micromanaging nanoseconds
Memcpy has clear benefits in the milli and even centi-seconds compared to a for loop set.
Manual vectorization is in the nanoseconds sure, but the mem operations are very powerful
and you are not stopped from using them
Yes, but I want a code genned version, that is the entire conversation.
teh fk is going on. the pointer to the comp is moving all the time! WHY!
structural changes?
not even a single one
The chunks themselves might be a bunch of managed arrays that Unity calls fix on before passing around.
no, that one is fully unmanaged
I doubt it though but that's the only reason why the pointer is floating around
the only explanation that is more likely, i'm dumb π i'm logging other entities
and yeah, of course it must be a structural change. the first setup that happens has a wrong pointer. some form of structural change must happen. the 2nd time the pointer is set, it stays constant
what i don't know now, why isn't orderChange picking this up?
maybe it changed for other chunk?
wdym, other chunk? that shouldn't matter, right?
ohh i get it ... i'm skipping any ptrs that are not null even when a order change occured. today isn't really my day ...
working fine now π
welll fuck, my copy pasted BVH builder doesnt work.... gotta comb line by line without reference to figure out what went wrong
oh god π good luck
I kind of always assumed that structural changes can invalidate any chunk pointer, even not ones that were targeted by EM
not sure if it's true
it's true π i have no idea why i assumed i can skip ptrs that were already setup.
question about principles - if a system behaviour is performed not every frame, but only when it's "called" (an entity the system queries, with a certain command/event component is created temporarily for a frame or so), should it be a system ?
shouldn't it be a function that can be called by some "supersystem" that would otherwise create those event entities ?
the IJobEntity seems to be this sort of function while not being a system itself
Ehhhhhhhhh, it really depends.
damn it, I hoped for a definitive answer
Systems and scheduling of jobs is cheap, to a point.
as soon as something isn't exact, my brain won't stop bugging me
Is this an event based off an entity existing (RequireSingletonForUpdate) or is this an event firing off a component returning true?
Then you'll need to look at these event formats: https://forum.unity.com/threads/comparing-different-approaches-for-events-in-dots.1267775/
Yea, I agree. For a single frame or two, a singleton and structural changes is not appropriate.
If it lasts for seconds at a time, instead of frames, then you'll want a singleton driven system update. Otherwise, consider those approaches in the forum post.
thanks for the link, maybe I'll return later if I won't find the answer, or when my brain comes up with another petty problem
you have started with one of the more complicated questions to solve π
Ugh, i think im gonna stick with singlethreaded BVH building. It's about 1ms slower for 10,000 entities (3ms total) and it gets worse from there compared to unity's parallel BVH builder but mine works and I dont want to debug why my copy pasted Unity's version doesnt.
huh, why is that different?
Yep
so i've made a performance test now. getting the targetInfo from a local comp or in a cached pointer when the comp is on a foreign entity. surprisingly the difference is hardly measurable. i run with a sampe size of 500 and it fluctuates a little. in a blind test i wouldn't be able to say what's what
usually this is a lot more but i think because the entity and its reference are created at the same point, they are aligned quite well
snd i have no idea if the cpu anticipates jumps with the same offset
To create those entities you simply use entity manager or buffer
Huh that's a good info
For systems with single action
You can actually just use stream
For super fast iteration
And avoid any structural changes
The only question would be how to get that native stream reference
spellcast with ptr ~2.74-2.78ms``` found it odd to have different timings than my tests i did some time ago. turned out my editor was already at 13gb π now the tests are much more than what i expected
and @robust scaffold that's what i meant with trade offs. the rpg data layout lives in a whole different world of complexity. it's gain some, lose some and pick the option where you lose less. the targeting system had an ugly rat tail of data. just yesterday i gained 1ms in 1 job but lost more than that in another because of it π
mem leaks?
uhm, no. maybe π the editor ran for 3 days or smth
Differences in floating point mode, maybe? https://docs.unity3d.com/Packages/com.unity.burst@1.7/manual/docs/OptimizationGuidelines.html#floatprecision
oh that reminds me of the pipe dream FloatMode.Deterministic: Reserved for future, when Burst will provide support for deterministic mode
Will you really enjoy the performance cost
The differences I posted is because I did a dumb and off by one error
guess not π no idea where it's really needed. cross platform multiplayer games?
Well, unity physics has no FloatMode.Deterministic tags (yet) so maybe?
They advertise it as cross (PC) platform deterministic already so it's probably not needed for now
im trying to load/unload subscenes by adding components, I got some reference code from @rotund token but am unable to get it working. Anyone see where I went wrong?
when the game enters play mode the first thing that happens is all subscenes are loaded but not opened.
foreach (var pair in streamingManager.worldGrid)
{
var e = sceneSystem.LoadSceneAsync(pair.Value, new SceneSystem.LoadParameters()
{
AutoLoad = false,
Flags = SceneLoadFlags.LoadAsGOScene | SceneLoadFlags.DisableAutoLoad
});
}
Then later I attempt to actually open the subscenes up so they will be visible in the game but it does not do anything.
Entities.WithAll<ResolvedSectionEntity, CellComponent>().ForEach((Entity e, int entityInQueryIndex, ref CellComponent cell) =>
{
var bufferHolder = GetBufferFromEntity<ResolvedSectionEntity>();
var has = bufferHolder.TryGetBuffer(e, out DynamicBuffer<ResolvedSectionEntity> buffer);
if(has == false)
{
Debug.LogError("No buffer on entity");
return;
}
if (IsChunkRelevant(currentCell, ref cell) == true)
{
ecb.AddComponent<RequestSceneLoaded>(entityInQueryIndex, e);
ecb.SetComponent<RequestSceneLoaded>(entityInQueryIndex, e, new RequestSceneLoaded()
{
LoadFlags = SceneLoadFlags.NewInstance | SceneLoadFlags.LoadAsGOScene
});
foreach (var section in buffer.AsNativeArray())
{
ecb.AddComponent<RequestSceneLoaded>(entityInQueryIndex, section.SectionEntity);
ecb.SetComponent<RequestSceneLoaded>(entityInQueryIndex, section.SectionEntity, new RequestSceneLoaded()
{
LoadFlags = SceneLoadFlags.NewInstance | SceneLoadFlags.LoadAsGOScene
});
}
}
}).Schedule();
is there a component I am forgetting to add or something?
Its adding the components in the foreach loop but adding the components isn't loading the scene x.x
Finally fucking nailed down why my math wasnt working. NAN propagation from a -INF multiplication by 0.
Hi there. How can I prevent specific monobehs from adding to entity in "ConvertAndInjectGameObject" mode?
off by one errors, one of the two big problems in computer science, along with naming things and cache invalidation
Ok so what do I do if I need to add a component that unity created but has defined as internal?
afaik there's a stop comp for it. can't remember the name. btw. that workflow is soon deprecated so best to think of something else
huh? which one do you need?
After debugging why adding a component to RequestSceneLoaded to subscene entity and section entity I figured out I need to add a RequestGameObjectSceneLoaded
which is defined as internal so I am unable to use it
is dots source posted anywhere so I can edit it?
various packages are in Library/PackageCache
if you want to edit you'll need to copy it out of there and edit your manifest to point to it using file local scoping
awesome
is there somewhere I can request this to be made available to us so I dont have to edit this file everytime ecs updates?
It's already deterministic on same platforms so cross platform is like the main use
Heading home atm have a look soon
Unless you already solved it
we use the asmref trick btw. to have access to internal stuff
I think I may have. In order to get the scene to load with LoadSubSceneAsync I have to use the loadasgo loadflag. Which means I need to also add a RequestGameObjectSceneLoaded component to the scene entity
Ah hmm not sure about that flag
I am not even sure why I have to use it
I have a subscene with plane in it
it should just be converted to an entity shouldnt it?
it's certainly getting harder to argue why I split the entities
this is with 0 code changes but just less chunk capacity
Thx. I've just started diving into DOTS and this approach seems very comfortable for managing data in the scene. I know that in the future everything will be as a DOTS entities but for now, I need to use some stuff that actually works (AnimController, NavMesh etc.). Can you point me out a better way of doing such a thing?
too much to explain https://docs.unity3d.com/Packages/com.unity.entities@0.51/manual/conversion.html
animations will be a bit painful. as there's no dots animations we still have to rely on gameobjects. fortunately hybrid components are helping out with this
what that means is that you can put an animator component on an entity
You can also bake the animations to a texture and use a shader to play them
You can specify chunk capacity now?
I havent had much luck personally with hybrid components that rely on other MB components. Like tilemap renderer which needs a grid and a tilemap component.
Actually, you shouldn't) I've read this article a few times and came up with a solution to use ConvertAndInjectGameObject. The thing that bothers me is that each monobehs convert into entities even if it is derived from IConvertGameObjectToEntity (using ConvertAndInjectGameObject). But seem you are right I shouldn't rely on this stuff right now.
only to a certain extent π one has a physics body + ltw/trans/rot, the other doesn't
try to split the object in what you need as MB and what you need as entity. then you can use subscenes and needn't worry about how it converts. you can easily link them then
best thing to do is that the entity has full control and spawns the GO/prefab.
the way I see it, is that the Go is just the visual representation
and beware of subscenes. MBs you put on GOs in a subscene will work fine in editor but won't in a build
yes, this fixes my problem but may create a tons of boilerplate code for creating data on the fly.
not necessarily, 1 system can handle this
Do I have to do anything special to get the objects in my subscenes to convert to entities?
nope, just put them in there. you can see the converted entity in the entity hierarchy
yes I do
they are rendering if i manually load them
with the buttons in the editor
but if I loadsubsceneasync and dont use the LoadAsGOScene flag it wont work
All I see is the scene and scene section no entity to represent whats in the scene
window -> dots -> hierarchy
Yeah I am there
would plane be the entity its making?
or the original game object?
the entity, if you click on it the inspector shows you the comps
the go will be gone
it's just for authoring in the editor
that should work. what are you using on the GO?
just a regular plane but reimporting hybrid renderer is what I am trying first
i don't think reimporting changes much but try your luck π
so how does the converted entity look?
Idk i guess I had wrong version of hybrid renderer installed or something cause uninstalling and then installing 0.51 made it work
now it gets converted and renders
and loads without the loadasgo flag
yep everything working now lmao
stupid editor bugs kill me everytime x(
is it fine to just remove a component without checking if it first has one?
is there a way to read from a dynamic buffer on an entity in entities.foreach().ScheduleParralel?
yes, with [NativeDisableParallelForRestriction] tag on it
hm, i'm really not too sure where this started that a high chunk capacity is so important. it is maybe for simd jobs but in non-simd it seems to hardly matter
oh, in case the DB is on the entity itself you don't need the tag. just put the DynamicBuffer<T> in the foreach lambda like any other IComponentData
Ah yeah I was trying to do GetBuffer and it was complaining about it
thank you
i was thinking of something different earlier, the tag I was mentioning is when you want to lookup and write to buffers from other entities via GetBufferFromEntity.
Awesome thank you this will be good to know for future use.
Do dots colliders interact with gameobject colliders?
nah
So you can't load your world via subscenes then spawn in a monobehavior vehicle to drive on the colliders generated? rip :/
nah, not without converting the vehicle colliders/bodies to dots
Will the physics behave mostly the same if I do that?
uhhhhhhhmmmmmmmm
most likely not by default
most vehicle prefabs will have scripts that apply physics torque etc etc so that won't work off the bat, without converting to dots systems
the basic colliders, joints and rigidbodies may or may not convert to something similar though
i doubt unity.physics conversion has a conversion from unity wheel collider etc tho
I dont use wheel colliders
I use raycasts
but yeah what I am asking is
if the addforce/addtorque calls will result in the same behavior from the body they are applied to
like if I add a force at a point on a cube with built in physics then add a force, will I get wildly different results if I do the same thing in dots physics?
in theory it should be similar but in practice it tends to be different especially once you introduce joints
I am not using joints either so that helps
there is a vehicles example in the physics sample though
are you just using raycasts to position the wheels manually around the body?
Raycast suspension, basically i shoot a raycast from the top of the wheel hub on the car downwards and apply some math to find wheel position from there then add force upwards from the ground to raycast start point
then I apply all my friction logic
how do you then make the wheel follow the car body without a joint
ah so the wheel isn't a rigidbody
no
just the main car body
just the car itself
the only downside to this is you have to calculate wheel friction yourself
I think so too, just hoping the feel of the cars dont change too much
what i've found with joint setups is it's possible to achieve similar results it just take s lot of tweaking
i think in your case it should be simpler, less tweaking as you just have the car body, might work right off the bat
any docs on how to actually do this I can't seem to find anything
no one really does it - in the sense i've never seen the feature used
but all you need to do is add the component by the same name
note that Issue was right and you always need to have section 0 open
and sections can't reference each other
except every section can reference section 0
my idea was to create a vehicles subscene and load/unload the ones I need by section at runtime. Then I could reuse the same system that is loading/unloading the world to stream in assets in and out as needed
haha, so i've merged everything now. my main caster archetype, physics (ltw/trans/rot) and even stats. it's not slower on the main jobs and some jobs don't even need to run now or are a bit faster because of less random access. chunk capacity is at 32 now
merged the jobs or merged into single components?
or you mean those were separate entities before
yeah seperate entities
so yeah, it hardly matters how big the chunk capacity is. i mean, it shouldn't be <16 or smth but even then. probably there are reasons when an entity is so big and splitting has quite a few downsides with questionable gains. a factor would be that the whole intro of an Execute chunk path gets called more often with less chunk capacity. those are mostly in the <1ms range. shouldn't matter too much.
To get really micro-optimizing, think: do you really need full float precision? You can pack 2 halves in 1 float. That's double the numbers for the same space. If you just need a general value, consider cutting down to normalized bytes. That's 4 numbers in one 32 bit float. Although at that level, you have to check the PCs you're targeting as some of the newer ones dont have advanced mathematic operations for vectorized bytes like division.
Check out some of the fancy shaders on shaderlab. They can get really creative on the bit precision of floats to squeeze as much data throughput during the CPU - GPU transfer. Every bit counts.
That's Unorms (byte floats). Half is pretty decent for good enough numbers. About 6 digits of precision closest to 0.
Math comes with a handy conversion to half precision as well: math.f32tof16() and the reverse of it as well.
is the burst compiler just for jobs/DOTS stuff? i've just started using 2021 after being dedicated to 2019, and the URP template comes with burst, not allowing me to remove it since it's a dependency.
i would like to remove it if i can, but i'm not sure what packages depend on it?
Idk if its cause im in the editor or what but this isn't true, my monobehavior rigidbody is colliding with the entities box collider
these are all the non-dependency packages i have installed.
pretty sure it's converted
what do you mean?
these 2 physic systems don't collide with each other. so the conclusion is the monobehaviour gets converted to an entity with dots physics colliders
nah im just dumb apparently the check box in the hiarechy means the subscene is loaded as a gameobject scene and not just that its loaded
so ofc it was colliding
Burst is integral to Unity. DOTS is built on burst, not the other way around. Nearly every package, DOTS or not, will be using it.
So no, you can not uninstall it. It's like asking to uninstall Mono and IL2CPP because you want to use Microsoft's NET.
If you're not using burst, just ignore it. It's optional.
removing burst is pure blasphemy!
word
i figured it wouldn't be core because it's in the package manager, which implies it's opt-in?
they even have a built-in section in the package manager for stuff which is assumed to be included in every project
afaik it's built in now. but you can update it
Unity is making nearly everything a package but yes, it's core. NativeArray is core and there is no reason for a NA to exist without burst.
same as urp or hdrp and so on
Is it possible to update a compute buffer in parallel using DOTS/Jobs?
I'm making a clone of the gmod LIDAR thingy in Unity and currently my main performance bottle neck is updating the buffer that contains the points for the dots that appear when raycasting on the environment
Rendering performance is fine even with millions of points maximum, but the CPU grinds to 60 FPS (from 1000+) and below when having to update the buffer
is there any way to remove the jobs menu at the top of the editor at least?
Actually yes. That's how I'm conducting my rendering systems right now. Just pass a NativeArray to SetData() on a compute / graphics buffer and it will mem-copy to the GPU.
Although Jobs wont let you get around GPU upload speed. You need to get creative on bit sizes like I was talking about earlier. Use halfs, use unorms, dont use floats, etc.
Do you have the jobs package installed? remove it thats why you have a dependency to burst
Not really. Just ignore it.
last i checked urp templates didn't depend on jobs or burst but idk
Yea, not my URP either. Jobs is only though Entities.
how do you use f32tof16? it returns a uint which is still 32 bits?
half value = (half)f32to16
It's only using the lower 16 bits of the uint. The upper 16 bits will be 0.
ah i see, thanks
It mirrors HLSL shader code, which does not have a ushort equivalent. Only uint. So you can just << 15 and stick in another half into the empty space.
probably a dumb question, but is it possible to just have the Job System without having ECS etc or are they hard dependencies?
you can have just jobs
DOTS is built on top of Jobs. Jobs + Burst is the foundational system. In fact, I highly recommend working and understanding Jobs and Burst without DOTS first.
does setting the internal buffer capacity of a DB only works with the tag or from code too?
tag
if (capacityAttribute != null)
bufferCapacity = capacityAttribute.Capacity;
else
bufferCapacity = DefaultBufferCapacityNumerator / elementSize; // Rather than 2*cachelinesize, to make it cross platform deterministic```
TypeManager needs to set it up during initialization
in theory you might be able to reflect into type manager
edit the s_TypeInfos array
and adjust the capacity after it initializes
and before anything else is loaded
hm too complicated ^^ guess i'll stick to a code gened constant
Hrm, i dont know if I'm reading the source of rewindable allocator but I think it clears before returning a new NativeArray.
the Block block = default; I think indicates that the block memory is being cleared.
Is there a way to create an entity that is a copy of another?
I found EntityManager.CopyEntities but seems overkill for just one entity
I had that same question a while ago. IIRC, check inside Instantiate. That copies an entity and all it's components.
If you want to copy some components and not others, you need to make a custom instantiate.
Is it inefficient like GameObject.Instantiate? If its something that is going to be done frequently will I need a pool?
I believe you can pass in a NativeArray<Entity> and it'll very efficiently populate the entire array up to it's length with copies.
Alright cool.
No need for pools
If your entity is fully unmanaged instantiate will be as fast as memory copy
what makes an entity managed?
Managed components
ok
Like sprite renderer
what about 3d renderer?
so its unmanaged then?
ah
Idk about managed comoinents
And hybrid specifically
Which are sprite renderers and companion links
Maybe internally Unity pools them somehow
Maybe not
But since it's usually naked spirte renderer
I'd guess it's not nearly as bad as normal go instantiate
Today's 7 hour debugging session lesson: Safety provided by native arrays is actually good.

Hi All, if I store a reference to an entity and that entity then changes version after a structural change does my reference also change or does it not refer to something that doesnt exist?
Entities can't change version
Structural changes don't cause entity version to change
The version only bumps when an index is reused when creating a new entity
So if I spawn an entity and store a reference to the entity somewhere then make a structural change by adding a new component to that entity, does the reference still point to the same thing?
Entity a;
Entity newEnt = entityManager.Instantiate(prefab);
a = newEnt;
entityManager.AddComponent<NewComponent>(newEnt);
Debug.Log(newEnt);
Debug.Log(a);
do these print the same thing?
yes
beware, doesn't work with buffer
instantiate entity in ECB will be index of -1
yeah I've come across that already
SetComponent fixes it
So if I store references to Entities, they will always point to the same valid entity unless I call Destroy() on that entity at some point in time
yes
Also do those entity references work properly if I serialise my game for save/load
can i worry about that part later or does the way remapping works mean I have to change the structure of how I store data now
well, from what I see
save load means you fully serialize your game state
meaning if it's done on hard reset
you'll have to recreate all entities
but they will be different
in order to fix it you's need to remap them
so if old entity index is 1:1
and new entity is 2:2
you'll have to go through all component data of freshly deserialized world
and look for all entitiy fields
remap it from old values to new
sure, but how do you know what Entity values point to which entities
when you save game
you save entitity indices to which saved data they correspond
once you started loading
every time you create new entity with that data you want
you make a hashmap
Entity:Entity
so now you have serialized data, new game state and hashmap
oh so when you serialise, you iterate through the serialised data and hashmap it
and then just remap after
at this point you simply go through all entity fields, read current value, find it by key in hashmap, write new value
yeah
sweet
ComponentType has a field HasEntityReference or smth similiar
so as long as I am keeping things clean ECS then it should be a worry later problem
yeah thats all good, I just dont want to have to rework everything to make saving possible
Thanks for the advice!
lets say i have 50 vehicles but only 3 of them are unique. it makes no sense to have data like gear ratios baseTorque etc on a component attached to each entity. Normally I use scriptable objects for this but they dont pair nicely with jobs. Anyone have any other suggestions?
Kind of what blob assets are for
its not the end of the world if you do replicate some of the data, ECS isnt a relational database after all, but blob assets is a good suggestion
Oh totally agree. In general I'd just dump it on components
More flexible in future
If you're manually setting a section of a subscene it appears you must set 0 first to something
0 must always exist and be loaded
Yes but if you dont manually assign something to 0 it does it on its own and messes up authoring scripts xd
er maybe I am just doing it incorrectly actually
public class VehicleAuthoring : MonoBehaviour, IConvertGameObjectToEntity
{
[SerializeField]
internal int id;
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var oldSection = dstManager.GetSharedComponentData<SceneSection>(entity);
var sceneSection = new SceneSection() { SceneGUID = oldSection.SceneGUID, Section = id };
dstManager.SetSharedComponentData(entity, sceneSection);
}
}
i have this attached to 2 game objects in a subscene
id is set to 1 to 2
but the entities are set to section 0 still
creating an empty gameobject that is manually set to section 0 does not fix this problem either
actually I think the problem is because they both use the same material
so its loading both of them to 0
am I the only experience constant problems with subscene import in 21.3.7f?
God any time i try to use subscenes i get issues
Any idea what this is:
The console that normally appears on the subscene mono seems to have vanished also, it was there before:
Where it normally has buttons for load etc
how are you creating the subscene?
Just right clicked inside my normal scene hierarchy and create new subscene
What issues
Cannot resolve header, basically some weird exceptions in conversion
which make subscene invalid
sometimes it's solved by clearing cache
sometimes by restarting editor
There's a script that you should attach for this not your own conversion
funny i just noticed your comment issue, seems maybe same as mine
i'm on 2020.3.34f1 tho
Clear entities cache seems to have helped:
Brought the log back etc
Really, REALLY annoying how these issues seem to plague the whole subscene/conversion thing
Im guessing its the SceneSectionComponent?
How you guys store blobs created inside subscenes, so that they can be referenced later?
I think the docs suggest adding refs to them to components, is there another way
How else would you access them?
Previously i was just creating them during mono/Convert ( ie not in a subscene ) and then storing the reference as a member of a system
like this basically
hmmm, is modification of companion link supposed to work?
var spriteRenderer = EntityManager.GetComponentObject<SpriteRenderer>(player);
_mat = spriteRenderer.material;
spriteRenderer.material = _mat;
I tried this
but it's still using default shared material
What are you doing with the blob later?
Just using to hold prefab entities and some init values etc
I take it this is more the intended usage:
interesting i wasn't aware this was a feature
I'm finding that my subscene+blob isn't being loaded in until after my spawner systems OnCreate method.. is the best approach to use [DisableAutoCreation] on Systems and then create/add them to the world manually to ensure correct ordering of things?
subscenes load async
they will never be loaded before OnCreate
because the scene system has to update to load the subscene
my personal approach is to create world/systems, disable simulation update, load needed subscenes for config, wait for subscenes to load, enable simulation update
systems can now access the config
my systems do no need the config in oncreate though
i might have a always update system use onstartrunning for the rare cases it did need to init something
but yes the alternative is to
create world, add subscene systems
load subscene
load your systems
hmm, thanks for the info
i am getting an error when i try and cache my blob inside OnCreate, saying zero singletons exist
but when i do it in OnUpdate it's finding it
maybe it's the component itself that is not yet created, rather than the blob π
yeah because world created, oncreate run, subscenes load, start updating
ah right ok i just reread your first two lines above
god damnit this is annoying π
ok i'll just grab it in OnUpdate and deal with that later
it's another layer of complexity i don't really need at this point
what kind of info do you need
only used for spawning anyway
Well i figured, i'll try and switch over to subscenes, as really it's what DOTS expects
well yeah, but not for literally everything
some things can be simply loaded as GameObject in a scene
or component to subsene GO
So i dumped my objects which convert and register prefabs ( and build blobs with prefab and init data ) into a subscene
oh prefabs
I store prefabs on entitites
and I don't save them on systems
I always keep them on entities
well it's swings and roundabouts i think
Entities.WithReadOnly(ltws)
.ForEach((Entity entity, ref Spawner spawner, ref LastSpawned ls,
in DynamicBuffer<PrefabElement> prefabs,
in LocalToWorld ltw) =>
{
here's how my spawning system looks like
very good
i'm building blobs from scriptableobjects, so that when i'm spawning a unit i can pull the prefab entity and any init data such as health, weapon, etc etc etc
but why store entities in blobs
besides
you should probably create blob in covnersion in this case
well an entity is just a struct, it's just a key really
instead of runtime
i am creating it in conversion
previously gameobject conversion but now trying it with subscene conversion
shouldn't be any different
I just don't get why you'd need reference to smth in OnCreate
well..
i thought, i'll grab the singleton component that has the blobassetreference, and cache its blob ref to the system, during oncreate
then i don't need to look for it any time the spawner system updates
hmm, I have similiar problem, but it's a bit different
I have a large amount of prefabs
which I need to store as prefabs
and then keep somewhere a database with map to those prefabs by string
and so I figured I could make an additional entity
yeah similar idea i think
during conversion
which will be picked up by some Initialization system
and this additional entity will keep reference to prefab
which will be a way to register your prefabs
in your blob
yeah
so i have a click to spawn unit right
currently, just for simplicity, you click, and it creates a 'spawn' entity with a component holding the string name of the unit to spawn ( previously i used a unique id but i'm simplifying this atm )
the spawner system then see's there is a 'spawn' component and runs
the spawner system has a cached reference to the blob holding all the prefab data..
it then uses the string name to pull ( from the blob data ) the prefab entity to instantiate, as well as any init data
so that's the idea
and then keeping blob asset reference on entity
to keep track of which prefab it was created from
for save/load
or spawning
or grabbing some kind of data from prefab
yeah it's just a way of basically having a similar system to scriptable objects that are so common in the mono environment
so you can have say ScriptableUnit, with a bunch of data about that unit
and you spawn the unit and apply all that data
but instead, in dots, converting those ScriptableUnits into blob assets so that they can be referenced by the spawner system
hmm
Is there any reason why entity would "stutter"?
It is dynamic but with PhysicsMassOverride to Kinematic
I change it's Translation
and on high speed stuttering is very noticable
high speed? simulation frame time too low/inconsistent?
nah prety stable at 110fps
but that's not the simulation frame time is it?
I update translation on frame update
take a screenshot if the timeline
where?
this is what i mean
it has to be a totally flat plateau otherwise you will see stutter. the brain is exceptional at picking those up
I don't get how it is relevant
_curMov.Value -= new float2(0.5f, 9.81f) * state.Time.DeltaTime;
this is how I manage my virtual velocity
and then
DeltaTime is sometimes higher and sometimes lower.
var em = state.EntityManager;
var tran = em.GetComponentData<Translation>(_player);
var deltaMov = _curMov.Value.y * state.Time.DeltaTime;
tran.Value.y += deltaMov;
em.SetComponentData(_player, tran);
it only moves consistent over time
physics ticks and simulation frame rates exist for a reason
but delta time exactly compensates for frame drops
I have used this approach hundreds times
and only now
it appears to stutter
i don't know what to say other than no, this is not how you'd do it. usually you split physic moves and interpolate to the current frame
think possibly because it's a kinematic physics body it would require fixedDeltaTime
this is the only way to got linear movement
point is, I don't care much about actual physics
all I really want is for it to update
every fixed step
collider position
there's an old article that explains this pretty well. i see if i find it
yeahhh, i think though possibly physics is interpreting what you change the translation value to during its fixedstep, whereas you're actually setting that value using delta
so it's kindof a clash of two intervals
i could be wrong though, but i'd give fixedDeltaTime a whack
you move an object with velocity -> physics. if you use dots physics for it is not relevant
yeah i'm just guessing that although it's kinematic, it's still trying to interpolate in some way
I use my own velocity
i know, still physics π
and it worked
4 times
in this exact purpose
on 5th it doesn't
only difference
body is dynamic
with override
cool found it, maybe it's relevant to your problem: https://www.kinematicsoup.com/news/2016/8/9/rrypp5tkubynjwxhxjzd42s3o034o8
can you test with a body that's not dynamic?
i'm not aware of any interpolation stuff going on
hm, no there's a smoothing option so just being dynamic can't really do something. why is it dynamic unlike the others?
possible cause of problems could also be that you change the translation by hand. that interferes with a dynamic physics object
best would be to use velocity then
welp
guess what
changed to static
no stuttering
kinematic stutters
dynamic without physics mass override stutters too
on static, physics doesn't do anything so setting the translation is okay. on every other option you want to set velocity. try it out. should be easy enough
and also give the interpolation a try then
I can't use velocity
because I need high fps translation updates
and velocity smoothing are dogshit
for my use case
bruh
at least I have backup plan
I assign collider to different entity which will be copied to main player entitiy
so I won't care about it's stuttering
but then I need it vice versa
because once player hits ground, I need it to be dynamic
oof
but I still don't understand why it happens
physics are supposed to be stateless
gave up trying to use subscene conversion with prefabs, it's just a complete pain in the ass
i've got one prefab that works fine i can grab the GetPrimaryEntity during conversion and store that in a blob
aaaaand another prefab that inexplicably doesn't work
just too much of a hassle
why are you trying to put all prefabs in one blob
here's how my system like this works:
I create some object in subscene
and make authoring component with GameObject[] field
where I assign all prefabs
then I reference them
and then in conversion I create for each object a blob with string identifier for it
it's double FixedString128