#archived-dots
1 messages Β· Page 7 of 1
I have to slot in the sprite renderer before light rendering but after tilemap rendering.
what is type of MainCamera?
There's no error so it should just be a IComponent
its a struct
What's inside the job?
oh
Maybe try instead making this camera position job a IJobEntityBatch where the query will require ComponentType.ReadOnly<MainCamera>(), and ReadOnly<LocalToWorld>(). Then in execute write to CameraLtW[0] the only value in the batch?
thats a good idea
Wait. GetSingletonEntity from state can not be burst compiled.
You must first create a query in OnCreate then use the query to get singleton entity, not use the state's version.
There are todos in the entities code that indicate they want to make entity query creation burst compiled, so everything from OnCreate to OnUpdate to OnDestroy all bursted.
This new project of mine with now 4 assembly definitions is possibly the best organized project I've ever made to date
how do i call createadditionalentity inside a conversionsystem?
Do i need to get the GameObjectConversionSystem from World?
var springEntity = CreateAdditionalEntity(gameObject);
its just a method in the conversionsystem
oh man im so stupid sry. my conversionsystem inherited from systembase
@robust scaffold ok so still had that error pop up with using cached not state query, but using the IJEB was a good workaround.
Hi, I am a beginner in ECS and DOTS world. Everywhere I see I am being marketed with high performance. However, I see different results than in YouTube videos. For instance we have the following video by Code Monkey: https://youtu.be/ILfUuBLfzGI
However, the results that I get are:
200 FPS in an empty project;
Only one Entity;
Burst - enabled;
Script: https://pastie.io/mqbouz.cs
What am I doing wrong?
There are quite too many checks in unity ECS
200 fps in Editor = 1500 fps in Build (at least for me)
Got it π I have another question, seeing the same script that I pasted, why I don't see 3d object in a world?
Do you have hybrid renderer?
It's a blank URP project
Do you have the hybrid renderer package?
how to check that?
that's a package
Yup, I see it there
https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/HybridURPSamples
Try going through these
just from assembly i can't see that the value is read from stack, right? like cmp byte ptr [rsp+B4h], 0h
or does the register type tell me something?
from my understanding this would be a value read from stack.
but this one isn't vmovss xmm1, dword ptr [r13+20h]. correct?
this is why i'm asking. globalCooldown is a ref variable and a comp on the current entity
pretty huge spike here
That seems quite extreme, just for a write operation
Is it a random access write? Because it might be a cache miss and the CPU is stalled trying to find the variable in memory
it's a ref from this var globalCooldowns = (GlobalCooldown*)chunk.GetComponentDataPtrRO(ref GlobalCooldown_WriteHandle); so, shouldn't be random
tick is an uint and a job parameter. maybe that's the issue
i'll just test it out π
Anything other than Execute should be a static function if the code is in a local to the job function.
execute calls private void MethodNew(ArchetypeChunk chunk) - shouldn't be an issue but hm, it's weird. maybe the measurement is off.
Me and Tertle a few days back were checking burst outputs of a method that was just private void and accessed the job properties directly vs a private static void that had the properties passed in from the parameters list. private void resulted in extra mov statements that copied values whereas the private static void did not. So always use static.
That might be the issue here
hm, can't make it static. so next best thing, using no method at all?
Yea
ok, let's see π
from the profiler timeline alone it didn't change anything. what it did change is that i can't see the code anymore in the profiler :/ only ExecuteInternal is visible
Huh, no clue if the profiler is right then
yeah, i dunno. it's a weird quirk of profilers. i have seen the same thing in vtune, VS and superluminal now
why use the entitymanager and methods like setcomponentdata in a conversionsystem instead of skipping the authoring component and just use the entitymanager within a regular system? like a spawnersystem or w/e
Conversion system bakes in the changes to component data before you even press play. Thats why they're naming it to "Baker". It sets the starting component data at compile time, not runtime.
Well, build time. Not compile time.
- The last one if for Tiny (RIP) and not in regular Entities. The others are system groups that you can reference to place your conversion systems in for sorting.
It's like EarlyUpdate vs Update vs LateUpdate vs PostCameraRender methods in a monobehavior.
ugh, get singleton results in a sync point
Yes of course, you need to complete anything that could write to it
Get singleton entity doesn't
And getting the data on a job
@rotund tokensir, could you tip me what API did you use to create mega mesh for your graphics system?
Do you mean my terrain?
I mean bursted creation of mesh
I realised I can make a 2d renderer like this
and I'm already half way through xD
I just use the new meshdata api
You still need to call ApplyAndDisposeWritableMeshData on main thread at some point
But you can setup all the data in jobs
If you mean my drawer for lines, I just used CommandBuffer (not entities) and built nativelists in job and passed them to this
no, I figured I try it this way
during conversion I create large RenderSprite shared comps
which contain material and large arrays of vertices, uvs and triangles
and per entity I simply add index of sprite
so during presentation foreach shared comp I grab indices for sprites
- their ltws
and then create a huge mesh
through burst job
and then I draw it all in one call
so basically meant to be: 1 atlas = 1 call
Oh my god unity, why did they abandon 2d dots...
i am staring at the source code of physics and ughhhh, this is pain
you'd be so bored if you had a full working 2d engine
what would you even work on!?
the actual game?!
I know right, kids these days, having everything handed to them completed. back in my day, we wrote BVH builders and SAH by hand
3d privilege, smh.
oh wow, check your struct layouts. i just optimized a 64 byte struct to 56 and gained a bunch of free performance
bad ordering of fields?
i thought rearranging fields was a thing?
got to group those bools/bytes!
c# default is ordered
{
public SpellOwner spellOwner; // size: 16 bytes -> 4 ints
public float* snapshotSpellStats; // size: 8 bytes
public float* spellStatsPtr; // size: 8 bytes
public void* spellBlob; // size: 8 bytes
public TargetInfo targetInfo; // size: 12 bytes
public byte sourceTeamId; // size: 1 byte
public AttackResult forceSpellResultHit; // size: 1 byte
public bool fromMainEffect; // size: 1 byte
}``` i have this now
best layout?
yes
just make sure bytes/bools are grouped - really only thing you need to care about
yeah got it.
do i misremember this that the compiler handles such a thing unless you have sequential or smth?
oh i see thanks
You can also take manual control via explicit layout. But it's a pain to calculate the offsets by hand
C#, Visual Basic, and C++ compilers apply the Sequential layout value to structures by default. For classes, you must apply the LayoutKind.Sequential value explicitly.
you're probably thinking about classes?
yeah, guess so. so this is not a thing. damn π
that said, i didnt even know you could apply layout to classes
considering it's called structlayout ^_^'
but seems like you can
Remarks
You can apply this attribute to classes or structures.
side note you should probably ask your question in burst forum not entities
much more likely to get a response from them
(that said they've been a bit less active recently though i think they were on holiday)
Yea, they were gone for about a month and some of the employees I was stalking checked in on with twitter had a bunch of images from their vacation. All europeans and their paid vacations. Tsh.
psh imagine not having paid vacations
i should take some, have like 3 months saved up =\
yeah, i realized when i hit submit :/ i always forget burst subforum is a thing π
we even get 2 additional payments in the summer and winter. so 14 times a year. but that's not everywhere, germans don't have it for example
I think they said something something ||KornFlaks|| something something
Basically: "2d is easy enough to make. So roll your own systems if you want 2D mechanics. We fired everyone working on 2D so good luck." That was on the post asking about a sprite renderer in hybrid at 1.0.
URL
that is a sad thread π¦
It really is. Really really is.
tldr: our priority partners do not care, only personal plebs use 2D /s
i personally have no stake in it. my observation is just, there are a LOT of unity 2d games
can we blame richitello?
A lot of shovelware sure. Not a lot of big budget money to unity licensed games
as much as i like dots i do think this is somewhat of a valid point
it's hard to advocate internally for 2D + dots specific stuff, because it's less common for 2D games to have as serious scaling/speed issues
as you say, there are a lot of unity 2d games therefore the engine is already quite capable of making them
and that's a weird take. i think someone down the line made the point that dots mainly speeds up simulation and not just rendering
you don't see many large scale blockbuster 3d games
sigh - that feeling when you are testing the build for company playtest and notice a bug that you introduced
already out or what? hotfix dat sheeet
Better than having someone else notice (god forbid the customer) and then all the fingers point to you.
i am writing a fix atm before anyone else wakes up
what a chad
well i am kind of responsible for this build so just my job
well, let's say i have worked with people who rather blame the alignment of the moon than fixing something asap
ok i have gone through every struct now. it's kind of embarrassing, i have made up like 0.5ms. down to 2.6ms now
someone wrote a tool in like 2018 early dots
to just check every struct in your project if it's optimal
now i hope i find some more. lol, easiest optimization i ever did
Regarding 2D, please by all means please provide that feedback on the DOTS Roadmap. https://unity.com/roadmap/unity-platform/dots
do you remember where to find that?
i've structured this pretty well. think i got every struct
from memory it has a bit of an issue with nested structs
i remember duplicating this a while ago and redoing it to try fix this
otherwise it has false positives
No one reads feedback from the general public / non-paying customers.
I like viewing whats on the roadmap with that thing but I really hate the idea of typing up some sort of request that will most likely just be quickly viewed and dismissed
Very optimistic. Thinking that your request will get viewed.
already helped me on some structs I missed π it has issues with enums that are assumed as byte but needs an int because of flags. still, very valuable tool
ah yeah that was another of the issues
besides writing a request for an entire product feature like animation feels dumb π
hello yes, I'd like to request ecs animation please because I dunno its like a pillar of modern game design these days
Ah, that's easy to solve. First become a paying customer
Everything counts in large amounts as Depeche Mode taught us
sometimes i'm just amazed what some devs are able to do. dreaming makes an animation package, this one guy writes some form of nanite in unity
oh yeah and the guy that made a visual editor for dreaming's animation package like a week later
that's also pretty sick
i would really like to use that animation package for my actual game but i'm also targeting mobile so, not an option with compute buffers as requirement π¦
I feel like I picked the wrong route with 2d + dots π€
Or be like me. Roll your own... everything.
Yea that's what I did lol
300 lines just to update AABBs
once 1.0 comes out I want to take a stab at writing an animation tree system for 2d
since I can roll onto 2022
yea lol
Thereβs a unite?
i think so?
Get ready for it β Unite is back and free for everyone. On November 1β2, join your fellow game developers and others from the Unity community for two full days of inspiration, learning, and connecting.
Wow, unity purged all references to hybrid components in 0.50. I just now am looking into it and it's mentioned twice in conversion and thats it.
They did want to delete it in 1.0 but it might the only way I can convert a tilemap.
Nevermind, it's dead in 0.50
any chance to simd this? ```[MethodImpl(MethodImplOptions.NoInlining)]
private void CalculateBuckets()
{
//Debug.Log($"CalculateBuckets with length {allocatedIndexLength} nextCap: {next->Capacity} bucketsCap: {buckets->Capacity}");
TValue* keyArrayPtr = (TValue*) (Values + keyOffset);
for (int i = 0; i < allocatedIndexLength; i++)
{
//var bucketIndex = GetKey(i).GetHashCode() & bucketCapacityMask;
var bucketIndex = UnsafeUtility.As<TValue, TKey>(ref keyArrayPtr[i]).GetHashCode() & bucketCapacityMask;
(*next)[i] = (*buckets)[bucketIndex];
(*buckets)[bucketIndex] = i;
}
}```
seems unlikely but i want to ask
not really because i+1 could use the same bucketindex as i
best you could probably do is simd the index into an intermediate array
yeah, hm, the allocation might not be worth it though. maybe i need to try the new update allocator. from what i read it's faster because it's buffered, is that right?
It's just a regular tempjob native array except it's "ref counted" kinda, just disposed at the end of the next frame
it doesn't actually dispose
there are 64 (or 32?) pools of memory
it tracks per frame memory requests and only releases memory if recent frames aren't using as much memory
i.e. if you request 2GB in a single frame it will release it shortly but if you reliably only request say 100mb/frame consistently it'll just re-use the same blocks every frame
/// <summary>
/// Rewind the allocator; invalidate all allocations made from it, and potentially also free memory blocks
/// it has allocated from the system.
/// </summary>
public void Rewind()
{
if (JobsUtility.IsExecutingJob)
throw new InvalidOperationException("You cannot Rewind a RewindableAllocator from a Job.");
m_handle.Rewind(); // bump the allocator handle version, invalidate all dependents
while (m_last > m_used) // *delete* all blocks we didn't even allocate from this time around.
m_block[m_last--].Dispose();
while (m_used > 0) // simply *rewind* all blocks we used in this update, to avoid allocating again, every update.
m_block[m_used--].Rewind();
m_block[0].Rewind();
}```
blocks not used this frame are disposed
blocks used this frame are just rewound for next frame
thanks! yeah i have to give this a try. maybe not for this but i think i have several other places
The absolute worst feeling is closing a subscene and getting an import error
basically gotta delete the subscene then attempt to recreate it all
what? no, just clear the entity cache
huh, thats what that button does
Thinking about that chunk of code for a bit, that doesnt really work well with fixed step systems. Since fixed step typically runs slower (50hz) than the framerate locked update (60hz or 144hz). So fixed step blocks are always disposed.
@safe lintel Seems like IJob scheduling can not be burst compiled.
Is there a way in query to exclude a type of dynamic buffer? Is it enough to just .WithNone<LinkedEntityGroup>()?
yeah
awesome
vertices.AddRange(((IntPtr*)curAtlas.vertices.GetUnsafePtr() + curOffset.verts.start * Float2Size),
curOffset.verts.count);
can anyone tip if my math is correct?
curAtlas.vertices is a large array
of float2
I have start index and count
of part of that array I need to copy
which is in curOffset
start and count respectively
Not (intPtr*), unless the vertex array is a set of int pointers.
I get pointer of it
You probably want (float2*)curAtlas.vertices.GetUnsafePtr().
IntPtr is the "safe" version for a random void*
yeah, but how am I supposed to add memory offset to it?
You can add to a pointer. Check C# docs
uuuuhm
You might want to directly apply the add range using an ResizeUninitialized() on the array then UnsafeUtility.MemCopy into it.
@rotund token sir, could you assist me a bit?
var vertices = new NativeList<float2>(Allocator.Temp);
var uvs = new NativeList<float2>(Allocator.Temp);
var triangles = new NativeList<ushort>(Allocator.Temp);
Here's what I have + meshData
Not sure how to correctly construct mesh out of that
meanwhile manual is doing some kind of weird stuff
// Tetrahedron vertices with positions and normals.
// 4 faces with 3 unique vertices in each -- the faces
// don't share the vertices since normals have to be
// different for each face.
data.SetVertexBufferParams(12,
new VertexAttributeDescriptor(VertexAttribute.Position),
new VertexAttributeDescriptor(VertexAttribute.Normal, stream: 1));
new VertexAttributeDescriptor(VertexAttribute.Position),
this defaults to float3 i think? going to have to give it a smaller size
VertexAttributeFormat.Float16
assume position even supports that
shoudln't it be float8?
but tbh, I do need float3
anyway
right now I have vertices, uvs, triangles
and array of offsets
which contains starts of arrays (index) and count of how much data belongs to them
each entity contains index of that array of offsets
meanwhile I also need to apply float4x4 matrix
to those values
and this is where I'm lost
ah, yes
Here's my ultra simple circle and box sprite renderer.
Takes in a float2x3 for object to world matrix and a float4 for color. The A in color determines whether it's a box or circle.
You can probably do more fancy things with the vertex but mine's just quad
If this is your first dive into a SRP, you chose a wild topic.
Im pretty sure they nuked that in 0.50
What's it called now?
But hybrid components is dead
ohhhhh
oh my god, maybe I can "convert" my tilemaprenderer
because I am not going to roll my own tilemap.
hrmmmm, i guess it's not as easy as just adding it as a componentobject to an entity
Damn, guess this just doesnt work. GetComponentObject returns null regardless of what I do.
it should be? or are you doing this during conversion
oh yeah
you can add it if you dont mind editing entities package
the check is done runtime system
oh boy, what did they lock out?
This is basic transform, the fundamental component that should be able to be added.
add it to?
add your Tilemap to the list
and it'll work like a hybrid component
that said, good chance this breaks in 1.0
oh, thats stupid
unity what the fuck is this
I'm gonna have to copy the entire package arn't I
i personally just use a class based IComponentData then have a system that handles this life cycle mangaement for me
due to concerns about 1.0 and this feature going
Can class based component data be baked on conversion?
Yea, im not gonna touch this for now. Tilemap conversion would be nice but not entirely necessary as I just need to pull collider vertex data from it
yeah
you need to assign it first
em.AddComponentObject(e, object);
it'll add any class
Adding MonoBehaviours does weird results though
normal unityengine objects are fine though
what would be the easiest way to disable and reenable entity in runtime? What i need is to disable mesh and collider if switch is pressed and then enable them when it is pressed again.
I'm doing it with triggers and when I used EntityManager.SetEnabled(), i'm having " Entities.ForEach Lambda expression makes a structural change.", when I add WIthStructuralChanges to ForEach, unity spams errors on swith because i have dynamic buffer (i'm using statefuls from the physics example)
add Disabled tag
if you want to disable rendering use
DisableRendering
to disable physics you need to remove component of simulation index
you can add the Disabled Tag to an entity yourself. if you do it with an EntityCommandBuffer you wont have structural changes in the lambda
Just read about that Disabled tag, trying it now
Disabled fully excludes entity from all systems
all queries*
unless specified otherwise
Can someone help me wrap my mind around the jobs system?
Basically I want to compress a bunch of data (without any heap allocations happening if possible). Would I need to create a new job for each integer/float that I want to compress and schedule them one after the other? Or how should this be structured? I already wrote all of the compression code and everything, I just have no clue how jobs is supposed to work, even after looking at examples.
it works with with command buffer, thanks. But now i have other problem, i have another trigger event connected to that trigger collider that kills the entity entering. Sometimes the switch triggers, sometimes not. I think it is due to kill happening first. I put [UpdateBefore(typeof(ThatKillSystem))] on the SwitchSystem, but it's still happening.
think of jobs as of black box
you give it input data
it does it's magic
you get back your output data
jobs (bursted and threaded ones) work only with unmanaged types
value types
for collections use Collections package
it'd be best if you initially kept your data unmanaged
so you won't need any GC during job init
how is that supposed to help xD
you write the jobs so how is it a blackbox.
it is a black box because they are burst compiled and contain some internal code
IJobParallelFor
you don't know how it's iterated internally
you only know what happens in Execute
that's why I think of it as black box with magic
kek
(allthough you do know if you look at sources)
xD
okay by that logic all of unity is a blackbox though. ^^
im not sure how to answer your question.
id say you wanna pass in an array of floats and compress all of them in a single job. jobs want to operate on batches of same data.
deleting entities inside the simulation group is a no go for me. i delay destroying them to a command buffer. you should plan out when and where stuff can be destroyed or moved in chunks (addcomponent/removecomp) and stick to those syncpoints. else you will quickly get into a dependency hell where everything needs to run in an exact order which is very hard to debug.
for example i do chunk move operations in BeginInitCommandBuffer and destroy commands are happening at EndInitCommandBuffer. this way i make sure all commands that need the entity to exist run first. that way i wont get errors telling me an entity is already destroyed when i want to remove a component from a destroyed entity.
Hi there! Guys Is there any asset or library to draw debug lines for dots? Built-in unity system is too slow
If you're willing to fork a tiny bit of cash check out aline on the asset store
It can draw from burst and is magnitudes faster
Otherwise it's not that hard to roll your own solution with basic functionality
Thanks!
Hello all, is this the channel where things about Burst should be asked?
yes
I am trying to upgrade Kinematic package to latest unity (2022) and I am having trouble with some of the burst compilation.
D:\Work\Inci_CharController\Packages\UnityKinematicaX\Runtime\Synthesizer\Synthesizer.Marker.cs(91,25): Burst error BC1063: Unsupported parameter `ref Unity.Kinematica.MotionSynthesizer` `synthesizer` in function `Unity.Kinematica.MotionSynthesizer.TraitExecuteFunc.Invoke(ref Unity.Kinematica.MotionSynthesizer.Any explicitThis, ref Unity.Kinematica.MotionSynthesizer synthesizer)`: Field `MotionSynthesizer.readDebugMemory.costRecords.m_DisposeSentinel` of type `Unity.Collections.LowLevel.Unsafe.DisposeSentinel` is not blittable. When compiling a method for use as a function pointer, only blittable types can be used in the method signature, including parameters and return type. To fix this issue, replace the non-blittable type with a blittable type. Blittable types include: void, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, UIntPtr, IntPtr, pointers, and blittable structs (i.e. structs containing only blittable types). Alternatively, use a pointer - `Unity.Kinematica.MotionSynthesizer*` - instead of ref - `ref Unity.Kinematica.MotionSynthesizer` - for this struct parameter.
"Unity.Collections.LowLevel.Unsafe.DisposeSentinel" is not blittable. is the problem. It is a class that comes from the new native collections.
As it is a class it is not blittable
The code is wrapped in ENABLE_UNITY_COLLECTIONS_CHECKS defines. Does anyone know where and how I can enable unity collections checks?
Actually the problem comes from NativeList which has DisposeSentinel inside.
Anyone got any idea why adding to an unsafe list (which is inside a NativeList)would not actually add to it?
i am adding and right after i am checking the length. length is always 0.
maybe because its a copy
I think I remember having to do something where you have to add to the list and then add the assign the whole thing back too
dataStructure.someNativeList[index].unsafeList.Add(element);
so this creates a new unsafelist which i need to assign back to someNativeList[index]?
I guess your already creating the new unsafelist inside the nativelist
it can get kind of confusing
thanks that pushed me on the right track. i need to first build the whole unsafelist and then assign it to the NativeList element.
yeah something like that
try to get the unsafelist by ref. this should work 100%. cant look up code right now. it's also very likely that the unsafelist in nativelist isn't actually a pointer. so you access it by value
internal UnsafeList<T>* m_ListData;``` ok it's a pointer. hm, not plausible to me right now what's going wrong. length is in unsafelist which should be incremented at the right memory space. the only thing that seems weird to me is that you access the unsafelist via . and not ->
what's your actual data layout? m_ListData is internal so you must have some other form which could explain the by value access again
Documentation is so bad sometimes
https://docs.unity3d.com/2023.1/Documentation/ScriptReference/Unity.Collections.LowLevel.Unsafe.UnsafeUtility.MemCpyStride.html
I am 100% sure this code sample is wrong.
The second destination should be source
Oof that does look wrong
hm, what's the actual optimization to doing it manually?
doesn't seem there's much to optimize
Manually?
just writing out the loop
I assume unity pads out the lesser sized component and then runs a single memcopy over the entire array.
whelp, can't see the actual assembly of it :/
Yea, it's an external call so who knows.
Angry Stallman noises
maybe it can be pulled from the symbolserver: http://symbolserver.unity3d.com/
You talking about memcpystride?
It's much faster the doing a loop
yeah
It's not as fast as memcpy but it's close
do you know if nativeslice is also faster than manual?
Not sure about that, probably depends what you're doing with it
It is handy though
Took me way too long to get my head around memcpystride
Always get it wrong
I was trying to include index into a component data array that was copied elsewhere and I thought about using it. Doesnt seem to hard to understand if my correction to the documentation is right.
it's not that hard to use, i just always mix up the variables
there are a lot of them to be sure
i optimized a key array away in a hashmap with a manual nativeslice. wasn't useful when the key is also in the data that is indexed.
Ya know, I'm thinking about replacing all my raw pointers from native arrays to spans.
Im wondering why unity hasnt done so already personally
that said, i'm not the biggest fan of memcpying existing data. it never worked out in my favor
isnt span just the fancy version of stackalloc?
so i played around a bit with the different forms of conversion. first of all, i have 2 conversion systems, one of them is just declaring refs with [UpdateInGroup(typeof(GameObjectDeclareReferencedObjectsGroup))]
the other class does the DstEntityManager stuff. Also, im using the inheritance method where you extend GameObjectConversionSystem instead of using IConvertGameObjectToEntity.. i suppose a custom system is best for assigning (authoring????) variables during conversion
Yea. It's a "safe" interface of stackalloc arrays. Like what native arrays are.
also, i would need to make a new system per gameobject?
hm, i've only tested stackalloc in combination of memcpying a foreign native array
The issue is of course the extra int designating length for spans.
If you use IConvertGameObjectToEntity, yes. If you use a GameObjectConversionSystem, no.
good!
Ive been reading through the physics source and they use stackalloc to create arrays inside job code instead of creating a native array
class BerryConversionSystem : GameObjectConversionSystem
{
protected override void OnUpdate()
{
Entities.ForEach((PrefabReference prefabReference) =>
{
//DeclareReferencedPrefab(prefabReference.PrefabGameObject);
Entity prefab = GetPrimaryEntity(prefabReference.PrefabGameObject);
Debug.Log(prefab);
//DstEntityManager.Instantiate(prefab);
DstEntityManager.AddComponentData(prefab, new Berry {
Id = 1
});
});
}
}
[UpdateInGroup(typeof(GameObjectDeclareReferencedObjectsGroup))]
class PrefabConverterDeclare : GameObjectConversionSystem
{
protected override void OnUpdate()
{
Entities.ForEach((PrefabReference prefabReference) =>
{
DeclareReferencedPrefab(prefabReference.PrefabGameObject);
});
}
}
it's a bit messy still
You dont need the PrefabConverterDeclare. Unity automatically declares reference prefabs for the target component.
Wait, the prefab game object
makes sense, it's very fast and local memory after all. with native array, i think, you don't know where it actually ends up
yea, that's how ya do it.
Yea, so much raw bleeding pointers everywhere though.
thanks for all your responses and help kornflaks (:
no it doesn't thats why you have the whole IDeclareReferencedPrefabs interface
i actually have no idea what you're trying to do with this conversion
u really helped
As in, it automatically DeclareReferencedPrefab(prefabReference). Not DeclareReferencedPrefab(prefabReference.PrefabGameObject); which is needed.
oh yep ok
Probably their first conversion. Get something converted successfully and then go from there.
i just try to create a berry entity with a Id field set to 1
i'd start with a IConvertGameObjectToEntity conversion first
are both not working?
i just thought custom conversion systems would be better if i wanted to assign variables during conversion, but perhaps both work
i have some pretty complex authoring setups and i never needed GameObjectConversionSystem
I use GOCS exclusively. I dont want to slap on a ICGOTE on every GO i'm converting. One GOCS is good for all the lights i'm rendering for example.
I cant wait for baker so we dont need to use all these acronyms
what's the difference, both work on 1 comp, right?
the power of a GameObjectConversionSystem is that you can run more complex queries and over multiple comps
yeah idrk how to make a GOCS for many components, haven't gotten to that part yet
right now it assumes a Berry
GOCS works on all components using an Entity.ForEach() while ICGOTE works on the GO that it's attached to.
i just filter with entities.foreach?
Just add more Entity.ForEach() for every component you're converting.
It's a different .ForEach than the one in SystemBase. It's the ancient lambda version
doesnt have filtering, cant do more than 1 component.
i worded that wrong, you are just using one light comp is what i mean
Yea. It also works on default components like transform which I run through a GOCS as well.
you can get the MB comps in a IConv too π
Yea, but then you have to link them in the inspector. Or use GetComponent<>() which might result in null errors.
these acronyms are getting out of hand
IJFEWI, IJPFD, NMHMP
ikr
thrown a requirecomp tag on it. that said, i've moved to completely seperate full authoring comps now. adding all these little comps was getting stupid
The tags are annoying. I might make a component with a flag enum to toggle on the flags added during conversion
2 tag comps, ewww π
I got an entire GO dedicated to system enable tags and singleton data
How do I accept DOTS as my personal lord an savior?
One: Forget how to code. Completely. Rip it all out by the roots.
Become one with nothing, got it.
Two: Code all 9 of these samples by hand: https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/ECSSamples/Assets/HelloCube
Play around with the result once you get each sample working. See what happens if you add another component, maybe keyboard inputs to control rotation speed, maybe an authoring component.
LetΒ΄s go
Three: Get an IDE that lets you "Go to declaration" of a method. DOTS is fully open source but with shit documentation. You'll need to read the actual source to figure out what's going on.
Reverse engineering is my first second and third name now.
Four: You know have accepted DOTS into your life. Go out and preach the glory that is ECS. Burn the OOS coders at the stake.
the actual code is pretty well documented (doubling your point)
The code has quite a bit of comments at the surface to mid level. Deep in it gets a little sparse but with the previous comments, it can be easily understood.
I think it's safe to say that, all of the things that make OOP and managed code so easy and quick to work with ( and are also their performance achillies heel ), must be thrown out and forgotten about
although, some stuff is in some ways quicker and easier in DoD/ECS which is nice in it's way
at work, we're at a point where dots holdouts are finally realizing how easy it is to add new content to an advanced project
compared to oop
"-uses ScheduleParallel to schedule the lambda to run on multiple worker threads..." Sure?
Yea, DOTS is a lot more modular.
Schedules an Execute() call for each thread, if possible. Try playing around with an IJob for an intro to job scheduling and burst
Roger that.
i guess technical debt is less of a problem with ECS arguably
Yea, since everything is flattened and independent of each other (largely), you can rip entire ECS sections out with little impact. Well, other than now that section is gone.
there's definitely costs associated with learning ECS and changing over though
The initial curve is hard yea. Cant really teach the 10yo kiddies how to think data oriented. If they only recently evolved object persistence.
and i'd say 100% it's easier to rapidly prototype in for example classic unity oop
i actually wonder about that
compared to doing like for like in DOTS
i have a theory if you never learned OOP you'd have a lot easier of a time
tough to tell, given it's the dominant model
Learning ECS/DOTS as a 22yo back then? Yea, easy. Now if I was learning it at 12? I could barely count my fingers... kinda. I think. Cant really remember what I was doing back then other than running around.
i can remember! i was making choose your own adventure games in vb6
You can show a kid that an apple has a property color of red. But can you really imprint upon them that while this apple has a color red, another apple has a color green and that both apples can be represented by a single entity indicating their unique identifier with a common component containing the property color.
(input-parameters) => expression It makes sense but how?
i think that definitely yeah without a problem, the only factor being if they're interested in learning that
That too. Kids are on natural crack most of the time.
also these days they're literally on the crack that is social media, which is really consuming a lot of their energy i feel
insta/tiktok/youtube/etc, it's almost like a drug addiction
God i am so glad to have been born before smartphones really infiltrated the classroom of grade school.
Didn't get my first phone to year 10. I was born right on the transition
it's definitely interesting that, there are two or three generations right now that were born around that time where, they sortof have one foot in the old world and one in the new
pretty significant in a lot of ways because the 'new' world is so insanely pervasive, and insidious in a lot of ways
I would have been a really early Facebook user but these days don't use anything (except if you count YouTube I guess)
They say parents killed Facebook, I agree
Bus maps these days are also pretty bad. If you use the official app or whatever they provide.
Google maps is a god send on that front
Does anyone just not use Google maps for this?
I do use the tram app just because it has real time tracking so I can see if it's late
And that data isn't in Google yet for us
Though buses recently were added
Only way I get anything done is to lock the phone for days.
I still have the ancient continental US atlas in the back seat of my car.
I hate tictok and short form video. Glad I never get distracted on those at least.
The only reason up upgraded from my s8 was because i ran out of battery trying to get home and it had my ticket on it
My S8's running strong. Probably another year or two before i upgrade. Dont use it much except for reading fanfiction...
haha s8 here too
I really don't use my phone except to chat in here on public transport
camera is pretty decent tbf
Which I'm doing atm
Battery life aint good anymore but I bought a 15 foot USB-C cable and it never leaves the charger.
definitely i'd say there's good and bad sides to the tech we now have, definitely a ton of benefits to it, and a lot of bad stuff also
We're all evil mobile developers feeding on addiction right
ill be honest, I loved my note2 & 5 but after switching to apple(because I constantly had issues where text messages only went through half the time to other iphones), the experience is way better
a lot of kids are way more tech savvy whether through progressing to modding games or even writing games, hacking, etc etc
Imagine having money to buy an Iphone.
mobile devs are literally the antichrist.
my monocle just popped out
mobile has been the pioneers for the worst gaming industry practices. Microtransactions, Macrotransactions, pay to wait, whale hunting, etc
also the whole upgrade phone addiction/cycle
I get upgrading a computer but damn, my little handsized metal brick cost nearly as much as my 17" development laptop.
I feel like that's wearing off a little?
There's been very little to be excited about in recent phone generations
New camera is about all that is advertised
The only thing interesting recently are the folds
I go 3 maybe 4 years before upgrading laptops because there has been noticable and significant advancements in computing power. Phones? Uhhh, more cameras.
Which I would actually consider getting if I could justify the price
Love they brought back flip phones
Cant bring a flip/fold into the shower. Instant no buy for me.
cries in eternal purgatory grad school
At least I'm funded with only undergrad loans. Poor souls are stuck here self funded.
Yeah not greatest idea
Oh we have government loans tied to price index
And undergrad is 50% covered
Oh yea, my loans are not linked to interest which is nice. Recent inflation has been steadily decreasing my loans without having to even pay it.
hah
i guess salary has to increase with inflation for that to work though right
so any word on entities 1.0 being still on track for release
0 info on my side but random guess is probably 3 or 4 months out. The Aspect API seems really raw.
I believe so, last I heard they were actually ahead of schedule
Like SystemAPI.Query<>()? Come on.
i'm guessing conversion workflow will take the biggest hit for people not using subscenes etc possibly.. i noticed it does say in the docs that for example GameObjectConversionUtility for converting on the fly will be dropped
Channel is surprisingly based in economics.
Netcode devs recently said this game been removed
But still under discussion
Completely not. Unity will never lower themselves and shorten their class names.
SystemCodeGenerationForEachJobApplicationProgrammingInterface.QueryEntitiesWithComponents<>()
i think possibly also IConvertGameObjectToEntity for mono's might be dropped, not sure though
conversion is still for me a bit messy and unsure
Everything merged under a single Baker. Does seem like it in the training. I see no examples using other conversion methods other than a single baker.
docs are a bit sparse on it also, the examples leave me thinking 'but what about this or that etc'
loading up samples and trawling through how they've did it is kinda painful also
Once you get it nailed down, it doesnt seem that difficult or confusing.
so yeah i think a single unified approach with maybe some alternatives for exceptions/caveats will be useful
yeah i think conversion system seems to be the best way forward
referenced prefabs is still a little bit of a grey area ( although i do understand and have a workflow for it )
and also for example conversion of stuff like joints and things that aren't created or initialized until later in the conversion pipeline
so potentially you might need different conversion systems running at different points in the pipeline to handle this stuff
Yea. I have no clue how to link together hybrid game objects properly. Tilemaps for example. Tried last night but then ran into the issue where I'll need to modify the entities package to allow for conversion of tilemap renderer and such. So I have a temporary solution of authoring the data I need at runtime OnCreate which is not ideal.
they've said they intend to lean towards supporting a hybrid workflow so i'm guessing there will be a few things that will basically just have to be hybrid, until they build in support for them
i kinda wish they'd said 'screw hybrid' and went/focused on full tilt dots tbh π
Converting everything done currently for GOs to DOTS will probably take years
Even more so than what it has taken so far to even make DOTS (development hell)
yeah i guess.. tbh i think they've done so well with entities/burst/etc, it almost feels like it would be harder and more messy to support a hybrid approach
but i guess in many cases it's easier to just, create a bridge for hybrid stuff, and that's that
Is there not always the option to migrate to Unreals ECS or what ever they call it?
Unreal's ECS is extremely barebones and new.
Despite everything, the years in development hell for unity DOTS have really solidified the ECS structure and style of the code.
kinda hilarious when you see like, the guy that created flecs for example, just doing it alone, in less time
you wonder what takes unity so long to do similar things
Too many cooks in the kitchen.
yeah
9 mothers cant produce a baby in 1 month. Just 9 babies. Is DOTS the equivalent of 9 babies? Maybe, there's definitely some loss in efficiency with the scale unity has been chucking at this project now.
What they've done with Burst and making C# code equivalent to C++ is extraordinary though.
stuff like jobs and burst, are a revelation in what they offer and can do for the platform, ecs also, but you do wonder, why take so long
Building from that foundation though is where Unity has definitely tripped and tumbled down the stairs a bit.
probably the requirement to integrate everything with the existing api's/enginecode, and also the UI has been a big part of that
UI hasnt been the bottleneck though. They had this interface solidified within weeks following 0.17 release if you read between the lines back before they went complete radio silence.
so i guess in a way bureaucracy just as a function of being a large organization has held it back
i wonder how many of the huge leaps have been rapid advances by a few talented individuals vs many drawn out periods of small incremental changes/updates by the wider organization
That's typically why research labs are structured very hierarchically. One or two lead researchers driving a group forward, determining what's the goals, what's the deliverables, what's the data required, and the lab scientist do the data gathering, the confirmation, a bit of the analysis.
Issue is with coding, it's very hands on. Lead researchers dont typically actually do the data gathering manually whereas coding, yea one brilliant coder with a vision can singlehandedly do the entire work.
one has only to look at the code of cinemachine. working with lots of people also means the code can be monolithic and full of weird decisions. then this whole thing about codegen, Entities.ForEach lambda, etc... it's a lot of overhead and pretty complicated to solve it all
Economics is a science, a soft science like sociology but science none the less. The term for this is diseconomies of scale if you want to sound like a prick.
And coding is as much a creative art than it is procedural science. You can have collaborative artwork but it together very rarely looks as good or superior to one great artist's work.
yeah interesting analogy, like a dozen painters working on a single work of art as opposed to a single artist
anybody know how many devs are actually assigned to any of the dots systems
talk was around 50 are in the dots team
And like artwork, 10 painters can whitewash a wall a lot faster than one but even DaVinci didnt finish the Last Supper.
i wonder if that includes like burst for example, which you could maybe say is mostly done except for incremental upgrades
does it include stuff like Animation
i guess everything under the namespaces
burst seems like a very small specialized team. I've only seen 3 unique unity employee names responding to questions and bugs on the forums relating purely to burst issues.
I can imagine there is a 5 to 1 ratio of social and less social people on that team. Surely a company as large as Unity Technologies can not have a 5 man tea, running this show? (!hend Selp ran out of Lager at 2 am! How can I now forget how to program?)
Ya know, I'm starting like like stackalloc. It allows for some really nice burst optimizations in loops:
Makes reading and understanding what's going on a lot harder though
Some day I will get the meaning of this.
Just vectorization and entire array actions
Stackalloc is great if you have small known or calculatable max values
You can speed it up a tiny bit more turning off its memclear on allocation as well
If you really want to optimise
You do have a limited stack size though
true, forgot about that. So it doesnt skip twice.
BinMinusOne is 7.
Yeah that's perfect here
I got plenty of space, stackalloc is only at uhhh, 40ish
I've just seen some people use it on like entity count or something silly
.seh_stackalloc 56
what? not even on the chunk entity count but whole query?
yeah passed in a query.ToEntiyArrayAsync thingy (wiht some data)
and were doing iterations of them
so if i have one scene with 1k subscenes is that gonna be a problem?
probably not?
Ya got me checking my code. Node count is possibly = num entities so i gotta add a conditional to go to heap if too big.
yeah ive seen this work before - it's a nice conditional optimization
Subscenes are just a conversion tool. It doesnt matter how many you have.
So will it make loading the scene take longer if there are a ton of subscenes than if everything was just in the scene im loading?
if you open every subscene at once its probably going to take a while
Ehhhh, sorta.
but subscenes are designed to handle large open worlds with a lot of them, and just streaming them in as needed
alright
Runtime loading depends on scene streaming loading speed. Aka reading from the scene byte compressed file.
thats what I am using them for
If you have a 1000 of identical scenes, the speed will be very quick as it just needs to load 1 scene and and then multiply that 1000 times.
If you have 1000 different scenes loading at once, that's gonna take a while.
it'll pop in one after another since scene loading is asynchronous. So the game will slowly pop in unless you write a loading scene that waits for all scenes to completely load in.
my plan is to split the world in 100x100 chunks each 100x100 area of the map will get its own subscene
each area of the map has unique vehilces and pedestrian models
if you're curious about real world situation
v-rising has 872 subscenes
that's how they split their world up
Wow, v rising is dots: https://blog.stunlock.com/v-rising-dev-update-4-v-rising-engine-and-cutting-edge-technology/
would I be better off just leaving the vehicles/peds in bundles or would each ped/vehiclce having its own subscene that I load when I need be a bad idea?
yes
first published dots game i've seen use subscenes
all the others were started before they were really a thing
Subscenes are the DOTS prefab. Each vehicle should be in it's own subscene. You can nest subscenes like nested prefabs.
if a vehicle is just 1 entity, ya dont need to make it a subscene. If it's multiple entities working together, one subscene should group them together and you add that as the vehicle.
I think with 1.0, subscene UI is getting a brush up. The UI preview presentation on youtube was really focused on subscenes and their interactions / conversions.
Right now it's a little uh barren. But it functions.
what approach do you guys have to enemy in range / detection.. can never decide whether do use a custom system that stores all current positions and loops over each doing a distance check, or just use large colliders with trigger events
Are there any other options for loading shit at runtime then? because right now it takes about 3 seconds to open a bundle load what I need from it and instantiate it. and I am trying to speed that up a bit
Ohhhh boy. Join me in handcrafting a BVH. Or just use Unity Physics and their superior implementation.
why not a spatial hash?
Loading of subscenes is not framerate bound. Try to do something while it's loading.
otherwise, pre-load it beforehand or get a SSD.
yeah i mean i'm thinking physics already has all of that optimized in broadphase right, just curious how others are doing it though
Reading through the physics system source, it's been purpose built for that. Their broadspace BVH construction is magic. Just turn off the kinematics if you dont want physics to be driving your movements.
I have an m2 the async calls are just really delayed. It doesn't stall my fps just takes ages for them to load. and there isn't really anything to wait on. If I decided to update the vehicle pool so new vehicles are added to it it just takes forever to do in the background.
unity's bvh is pretty re-usable as well
It's just 3D. And I dont want the extra memory of more useless floats.
spatial hash built around Rect works best for this imo
i was about to say my spatial hash is something like 4x faster for finding nearest neighbours for my orca system
sphere cast is fastest. triggers are really bad performance wise
but it's very specialized and can do a lot less than the bvh
but having a collection of nearest targets is very useful
i'm already driving the units via forces so i'm currently just adding an additional trigger collider and looking to capture it in my stateful event code, so yeah i'll probs do that
sphere cast wont be faster than non physic based solutions.
a lot of systems ends up using the same type of data
ah really
whether for targeting, local avoidance etc
tbh the stateful event system i've lifted from the physics samples is hella slow when there's a lot of collisions.. uses buffers on the entities etc
i didn't say it's the fastest. it's the fastest when using dots physics though
eh, you get the meaning. i did say that haha π
these trigger/collision events fire back single threaded
and you have to basically sort the data to do any parallel work on it
triggers are best left for rare events imo - entering specific areas etc
if you're querying every frame find something else
what then would you say is the optimal approach?
BVH is design for linear raycasts. It's what makes realtime raytraced lighting work (DXR etc). Other hierarchies work better for other situations.
If you need a raycast, and you need 4million of them per frame, BVH all the way.
are the entities you're querying for moving?
i have not found anything faster than a spatial hashmap for nearest neighbours - if you find something let me know
yeah
https://github.com/adam-arthur/spatial-hashmap here's one I googled up real quick.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I haven't tested this
i did actually write one for this for my previous dots project, but always looking for good recommendations
but this is how I do it
i like to use rect.overlaps
that way you dont have to add the whole cells collection when you query it
the problem i see in 3d space. nearest neighbour is only half of what you'd need. typically you also need a raycast.
i think yeah you could call spacial hash a broadphase and then you have a narrower list of entities to poll for raycast
i haven't figured out to make dots physics work selectively. all colliders are built
yea this is what i do for 2d
so you have the bvh and spatial hash to build. not really optimal
works fine for 3d for most cases too unless your game has a lot of vertical building going on or something
Collision flags?
i think Latios implements a way to query selectively, but i haven't actually tried latios just read the docs
this is how long it takes to build my spatial map every frame for 200,000 entities
a pillar is enough or some enemy inside a building
the single job is because i found batch adding to the hashmap to be significantly faster than doing it in parallel and only uses 1 thread
why you rebuilding it every frame?
i think the problem is, when you're polling collisions, you can't poll say the unit/ground pairs you have to poll all collisions
because things move every frame and it's faster than determining this and rebuilding parts
this is for my orca implementation (actor avoidance) so there are no static objects
can you implement some change filter?
You got your spatial hash posted anywhere curious how its designed. I just use a dictionary with cell as a key and a list of items as value and remove/readd the item when the item moves
awesome thanks
i havent looked at it in a year so there's a 50% chance i notice something straight away i want to improve π
private struct QuantizeJob : IJobFor
{
[ReadOnly]
public NativeArray<ORCAAgentState> Agents;
[WriteOnly]
public NativeArray<int> Keys;
[WriteOnly]
public NativeArray<int> Values;
public float QuantizeStep;
public int QuantizeWidth;
public int2 HalfSize;
public void Execute(int entityInQueryIndex)
{
this.Keys[entityInQueryIndex] = Hash(Quantized(this.Agents[entityInQueryIndex].Position, this.QuantizeStep, this.HalfSize), this.QuantizeWidth);
this.Values[entityInQueryIndex] = entityInQueryIndex;
}
}```
``` [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int2 Quantized(float3 position, float step, int2 halfSize)
{
return new int2(math.floor((position.xz + halfSize) / step));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int Hash(int2 quantized, int width)
{
return quantized.x + (quantized.y * width);
}```
that's the quantize job you can see in the above profile
the first bit determining their cells
the populate job just looks like this
private struct PopulateSpatialHashMap : IJob
{
[ReadOnly]
public NativeArray<int> Keys;
[ReadOnly]
public NativeArray<int> Values;
public NativeParallelMultiHashMap<int, int> SpatialHashMap;
public void Execute()
{
this.SpatialHashMap.ClearAndAddBatch(this.Keys, this.Values);
}
}```
just my batch add operation for a hashmap
o_O
I just started using dots like 3 days ago
oh fair enough!
yeah its /kind of/ a replacement for dictionary<T, List<TV>>
can you access its indexer?
you can get an iterator from a key
oh cool
guess most of the populate comes from the memcpy. maybe could be sped up with my ArrayHashMap π
How are you querying it?
yeah i probably could
i think there was a reason i didn't do that though
but i can't recall
should probably investigate it
well whenever i get around to actually integrating this system in my game
i'll revisit that
is it possible to create a subscene programmatically?
there's nothing special about a subscene
it's just a regular scene
and you can create a regular scene programmatically
just create regular scene and assign it to a gameobject with a subscene script
like loading or really creating the GOs in there? because I'd say subscenes are not really designed for that or more to the point, the workflow isn't.
i am super confused
got rid of the 2x array memcpy, the quantize job just direct write to the key/value buffers in the hashmap and then the populate job only does the bucket calculation
and it's slower?!
private struct PopulateSpatialHashMap : IJob
{
public NativeParallelMultiHashMap<int, int> SpatialHashMap;
public void Execute()
{
this.SpatialHashMap.RecalculateBuckets();
}
}```
consistent as well
takes nearly 30% longer
is a resize triggered?
just a recalc of the index can't take this long hm
stash my changes
0.58 π¬
[NoAlias] this NativeParallelMultiHashMap<TKey, TValue> hashMap)
where TKey : unmanaged, IEquatable<TKey>
where TValue : unmanaged
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndThrow(hashMap.m_Safety);
#endif
var length = hashMap.m_MultiHashMapData.m_Buffer->allocatedIndexLength;
var data = hashMap.GetUnsafeBucketData();
var buckets = (int*)data.buckets;
var nextPtrs = (int*)data.next;
var keys = (TKey*)data.keys;
for (var idx = 0; idx < length; idx++)
{
var bucket = keys[idx].GetHashCode() & data.bucketCapacityMask;
nextPtrs[idx] = buckets[bucket];
buckets[bucket] = idx;
}
}```
this is the after
this is the before```public static unsafe void ClearAndAddBatch<TKey, TValue>(
this NativeParallelMultiHashMap<TKey, TValue> hashMap,
NativeArray<TKey> keys,
NativeArray<TValue> values)
where TKey : unmanaged, IEquatable<TKey>
where TValue : unmanaged
{
CheckLengthsMatch(keys.Length, values.Length);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndThrow(hashMap.m_Safety);
#endif
hashMap.Clear();
if (hashMap.Capacity < keys.Length)
{
hashMap.Capacity = keys.Length;
}
var data = hashMap.GetUnsafeBucketData();
UnsafeUtility.MemCpy(data.keys, keys.GetUnsafeReadOnlyPtr(), keys.Length * UnsafeUtility.SizeOf<TKey>());
UnsafeUtility.MemCpy(data.values, values.GetUnsafeReadOnlyPtr(), values.Length * UnsafeUtility.SizeOf<TValue>());
var buckets = (int*)data.buckets;
var nextPtrs = (int*)data.next;
for (var idx = 0; idx < keys.Length; idx++)
{
var bucket = keys[idx].GetHashCode() & data.bucketCapacityMask;
nextPtrs[idx] = buckets[bucket];
buckets[bucket] = idx;
}
hashMap.m_MultiHashMapData.m_Buffer->allocatedIndexLength = keys.Length;
}```
literally removed the clear, capacity resize + 2x memcpy
and its twice as slow
popping changes let's try again
i think the issue is that the bucket/next array isnt set to -1
!!!
i was clearing it but
if (hashMap.Capacity < entityCount)
{
hashMap.Capacity = entityCount;
}
hashMap.SetLength(entityCount);```
i was doing it before the length set
All clearing does is set length to 0. You can skip the clear and directly set length.
that is not true on hash maps at all
{
UnsafeUtility.MemSet(data->buckets, 0xff, (data->bucketCapacityMask + 1) * 4);
UnsafeUtility.MemSet(data->next, 0xff, (data->keyCapacity) * 4);
for (int tls = 0; tls < JobsUtility.MaxJobThreadCount; ++tls)
{
data->firstFreeTLS[tls * UnsafeParallelHashMapData.IntsPerCacheLine] = -1;
}
data->allocatedIndexLength = 0;
}```
it memsets the bucket/next arrays to -1
Ah, hrm. Guess it's not a list then.
yep, i'm using next->Resize(length, NativeArrayOptions.UninitializedMemory); buckets->Resize(bucketLength, NativeArrayOptions.UninitializedMemory); UnsafeUtility.MemSet(next->Ptr, 0xFF, length * 4); // sets everything to max, Unity uses the same method in their NativeHashMap clear UnsafeUtility.MemSet(buckets->Ptr, 0xFF, bucketLength * 4); to clear to -1
noice π
yes
Is there like a way you can do this in unity ecs?
var w = new World();
w.Systems.Add(new SomeSystem()):
w.Systems.Update();
Yes, but it's pretty painful.
really lame
how do you control execution order?
I saw attributes
but
that looks painful as well.
I mean:
That works. But doesnt sort.
Execution is just add to a system group then maybe update before or after another system
Yes that looks painful xd
Create groups.
Use [UpdateInGroup] in systems.
Use [UpdateBefore] and [UpdateAfter] on groups, and systems within groups
Thats really the only way?
no
whats the other way?
If you really really want, you tick your own groups and systems
any docs on this?
lemme check
Does this effect oninit and ondestroy order too btw?
Yes
My self imposed time limit on checking has expired. Not sure π
it comes down to calling 'update' on a system, although I can't remember how you disable auto updating
you can [DisableAutoCreation] but I'm not sure if that's really what you want
I mean that will work tbh
then can I just new System(); and system.OnUpdate wherever I want?
System needs to be created through the World property or else the properties like EntityManager will not work properly. But yes.
awesome thanks
groups and before/after cover pretty much the most use cases for ordering. does that not work for you?
I can see cases where manual update would be nice. Like update once for monobehavior events if singletons are not possible.
kind of hacky, requirecomponentforupdate but not have that comp around
I need someone to verify this logic. I cant think it through:
Idx is originally 1, 2, 3... At the end, I want the value at Idx to match the resulting location of where the corresponding AABB and cents end up.
does the tuple not require a temp variable?
Nope. This is C# swap.
huh pretty handy
what is the halfSize and width values being set from?
Just settings
Is there a good example somewhere of using the DOTs physics for colision detection?
I have been trying to find this all over and all I can find is raycasting stuff
oh and upto date
cause all the stuff I find is out of date
wait so we just call hey has this thing collided all the time? that seems inefficient...
The entire physics collision world gets regenerated / recreated every single tick. It's stateless.
Due to being stateless, what you have is "has it collided this frame". Nothing about last frame or any histories.
oh so we are not running a new calculation we are just checking the current state?
Yep.
I feel like I am missing something here I don't see where this code belongs it just says to make a method public unsafe Entity SphereCast(float3 RayFrom, float3 RayTo, float radius) but not what class that is in or what system it needs to extend or how it gets called or anything
It's probably buried somewhere in there. I'm not familiar with actually using the physics package personally.
seems unrealistic. 1.7ms job for 250k entities
this on the other hand. pretty much nothing
What does it take to move an entity from one scene to another during runtime?
These are float3s right? Distancesq is just dot itself. Really fast.
Yea, those percentages are clearly wrong.
There are no such thing as "scenes" in runtime. The hierarchy you see in the inspector is just visual.
Yeah I'm aware. I strictly want to do this specifically for the hierarchy π
Only one way, during conversion. Use AddAdditionalEntity() in your GameObjectConversionSystem.
Otherwise, not during runtime. I asked the DOTS folks about that on the forums and they said Soon^tm.
Ooof, there's that word again..."Soon"
it's not entirely true, all entities in a subscene share the same shared component
and can be closed together
you can add entities into this group by simply giving them the same component
however it's not persistent, once you 'close' the subscene during runtime the entity will just be destroyed
reopening the subscene will not recreate this entity
(and when i say open/close i mean during runtime via code, not via hierarchy)
I think I'm gonna try that, I don't need them to persist between play modes.
but it can be useful for tying effects and other things to these entities that will cleanup at same time
it wont persist within the same play session
if you close the subscene
Oh!
it just does destroy(allfromscene) including things you've added to it
I think that's okay too in my situation. But thanks for the fine print.
Huh, that is a neat trick.
but it will just read back off disk when loading
Thanks man
yeah, sucks that profiling burst is so inaccurate for some reason π©
The guy who made the quote on the product page is one of the devs, I dont think lead, of Burst so there has to be a way to get accurate data
these components
cant remember
if you have something in the subscene referencing a prefab
that prefab will also automatically be added to subscene and instantiating off it will be into the subscene at runtime
nice
sorry i had to leave yesterday.
{
public Entity headTile;
public NativeList<KernelSlot> kernelSlots;
}
public struct KernelSlot
{
public UnsafeList<Entity> tiles;
}```
thats the layout
this is essentially how it didnt work:
var tilesKeyArray = slotTilesHashMap.GetKeyArray(Allocator.Temp);
var kernelSlotTiles = new UnsafeList<Entity>(100,Allocator.Temp);
intersectedCollapseKernel.kernelSlots.Add(new KernelSlot
{
tiles = kernelSlotTiles
});
kernelSlotTiles.Add(tilesKeyArray[0]);
Debug.Log(intersectedCollapseKernel.kernelSlots[0].tiles.Length);```
that debug would always print 0
now my easy fix was to first fill the kernelSlotTiles and then add that to the kernelSlots afterwards. but i sure like to learn how id make that work. how would i access with -> ? never used it to access before.
Hrm. Not good showing for only 10,000 entities.
hehehe down to 0.28mt + 0.28st for 200k
feel like unity's would be faster than that?
Why map population is single core?
Because I programmed this by hand it's singlethreaded for now.
I mean tertles too
Adding to a hash map is faster in singlethreaded with a bunch of memcpys
Unity physics cause sync point as far as I remember
So maybe you should use this
Somehow
How would sync points help?
You can calculate map capacity beforehand
Hrm, assuming the parallelism is linear, division by 10 threads probably means 0.5ms for 10k. Which is pretty awful.
Increase it and then fill it threaded
because in a single thread can now do it in <0.3ms and in multithread it takes 2.5ms per thread trying to add 1 element at a time
i have a lot of extensions for native hashmap to do batch operations
So I better always use single thread for it?
Hmm
Can you show batched add range?
I could use this one
^
I wonder, would it be faster if during that quantized portion, you instead atomic add to a NA<int> containing counters for each grid square. Next a small singlethreaded jobs that calculate the offset for each grid. Then a third multithreaded write to another NA<Entity> now that you have the offset for the grid and the index of that entity.
Huh
Maybe I can speed up target finding by a margin with that
But I assume
I should always use single thread for filling map, right?
profile it, sometimes it faster, sometimes it's slower
it's just a simple method change so just profile it.
It's not
Or do both and profile the changes
Makes me refactor method
Which is a bit more complex than simply changing schedule method
if you want to see difference from when i made it parallel to single thread batch operation
(and today i double the speed of the single thread operation)
the gotcha is this is only safe on a hashmap if it's empty
and if you're using non-multi version it won't check for duplicates
There are no duplicates in my case
(it doesn't check for duplicates in multi either but the container allows it)
yeah that's fine that's the one i linked
Ah
I simply need to fill entities based on sharecomp separation
Where they all share same id
So that should be easy to batch
Hmm
is there a way to have singleton blob?
I assume I could use World extension for that...
but would love some less managed option
apart from being immutable, what advantages do you have using a singleton blob over a singleton entity?
I decided to use combination of both
blob for value
entity for tag whether it's active or not
I use blob because having I need a way to access data from anywhere
and since it's never removed
or moved
I can use singleton approach
it's kind of a variable like Time
im having a hard time finding an up to date solution for this
how do you add a component to an entity in a job you run with entities.foreach().scheduleparallel
commandbuffer
In the sample posted here
https://docs.unity3d.com/Packages/com.unity.entities@0.51/manual/entity_command_buffer.html
does this.Dependency.Complete(); have to be called
or can i just comment that out and it would still work?
no
it's an example how it works
all you need to do is create ECB
and then addjob handler to producer
in ECB system
a bit below an actual example
of how it should look like
So you have to write your own ecb system?
ok cool thank you
Can you create the command buffer in system init and use it later or does it have to be recreated each frame?
every frame
ecb has no get component is that just safe to use then?
GetComponent is codegen in foreach loop
it implements ComponentDataFromEntity for you
Is there no way to run this as a job?
EntityCommandBufferSystem sys =
World.GetExistingSystem<BeginSimulationEntityCommandBufferSystem>();
// Create a command buffer that will be played back
// and disposed by MyECBSystem.
EntityCommandBuffer ecb = sys.CreateCommandBuffer();
var pos = new float2(cam.position.x, cam.position.z);
var sceneSystem = World.GetOrCreateSystem<SceneSystem>();
Entities.WithAll<WorldChunkComponent>().ForEach((Entity e, ref WorldChunkComponent chunk) =>
{
if (math.distance(pos, chunk.position) <= 400)
{
sceneSystem.LoadSceneAsync(chunk.hash);
ecb.AddComponent<RelevantComponent>(e);
}
else
{
if(HasComponent<RelevantComponent>(e) == true)
{
sceneSystem.UnloadScene(chunk.hash);
ecb.RemoveComponent<RelevantComponent>(e);
}
}
}).ScheduleParallel();
Passing sceneSystem is causing an exception since im passing a non value type
well, there is
but I have a feeling
that this job is run on simple entity
or not?
oh wait, is that dynamic culling system?
anyways
you can load scenes
by creating entities
Loads the map in and out of memory with subscenes
Can you elaborate a little more on that?
take a look at what LoadSceneAsync does
pretty sure it creates scene entity
void LoadEntitySceneAsync(Entity sceneEntity, LoadParameters parameters)
{
var requestSceneLoaded = CreateRequestSceneLoaded(parameters);
EntityManager.AddComponentData(sceneEntity, requestSceneLoaded);
if (parameters.AutoLoad && EntityManager.HasComponent<ResolvedSectionEntity>(sceneEntity))
{
foreach (var s in EntityManager.GetBuffer<ResolvedSectionEntity>(sceneEntity))
EntityManager.AddComponentData(s.SectionEntity, requestSceneLoaded);
}
}
yep
its nested in there pretty deep
but its in there
I wont be able to do that in a job anywyas will I?
Entity CreateSceneEntity(Hash128 sceneGUID, LoadParameters parameters = default)
{
var requestSceneLoaded = CreateRequestSceneLoaded(parameters);
var sceneEntity = EntityManager.CreateEntity();
EntityManager.AddComponentData(sceneEntity, new SceneReference {SceneGUID = sceneGUID});
EntityManager.AddComponentData(sceneEntity, requestSceneLoaded);
return sceneEntity;
}
loading subscene is literally just creating entity
that triggers SceneSystem update
which will load it
this is creating scene entity from scratch
but you should instead first check whether scene entity is created already
basically
you can resolve it all during your world chunk creation
That is done in the editor