#archived-dots
1 messages ยท Page 150 of 1
positions of items in the world for example.
Items are not entites?
they are, but when I close and save the game, how would I place them in the spot where they were positioned otherwise?
Ah you save the items with the chunk?
I'm thinking about doing that, I am not certain what is the best approach right now, but I need to have items that stay when I close the application for example.
The world I can just generate with the same seed
Why not a SharedComponent for all items that are part of the same chunk?
How would that work?
You add a shared component to the cube entity and just set that value the same across the chunk?
You would just add the same WorldChunk SharedComponent to all items in the same WorldChunk.
Sorry my daughter woke up so I need to go.
That at least would be my solution. :)
I'll look into to it.
One thing I'm curious about though is what exactly defines as "the same" shared component.
Just the same values of all the entities inside the shared component?
yep, that was correct...So my shared component literally only should have the value of the chunk in it to stay the same ^^;
maybe biome type would also be applicable.
So there is no way to write generic systems right ?
The issue with a generic system would be that Unity wouldn't know what system to spawn. If you just want reuse of code, Making a a generic system (or generic helpers) and making concrete implementations of that should work under what I know of the DOTS system
//define
public class SomeGenericSystem<T> : Systembase where T is SomeRequirement {
//generic implementation
}
//Make specific versions that Unity can actually spawn
public class NonGenericSystem : SomeGenericSystem<SomeType> {
//Only type-specific code and overrides
}
Again, haven't tested, but I think it might work
In a DOTS managed game, I guess I would store saved data and such the normal way? Like placed items in the world and so on.
Save the data? You'd serialize it as usual, yeah, and AFAIK there is a helper to serialize an entire DOTS World
ooooh, what, I can just serialize the entire world?
I probably have to rethink how I unload chunks in that case and not destroy entities....I imagine that if I were to destroy entitites when unloading a chunk of land, the world would not remember to spawn them in again on the same position unless I have a collection of these items where they should be placed in the world...
You can have the chunk data loaded to memory while not simulating it, but more likely you just save on unload
I was so sad that the subscenes don't work fully in script, so I can create them on the fly, that would be super nice to use for terrain chunk loading ^^;
instead I might have to use a distance from the character to decide if I should unload or load a chunk.
But did you say you could just unload entities too? So they are around but they kinda stay hidden?
regarding voxelchunks:
assume we have a component holding float values for a fixed size subspace of the game world, so basically a flattened array holding some value for a bunch of 3d coordinates.
now we run marching cubes to draw the mesh, where it goes over that component data and assumes that every coordinate is inside the geometry, if its value is greater then some value and vice versa.
once the mesh is generated, how would one update he mesh, incase a player digs into it?
ofc i can adjust the values of the component accordingly, but there is no (and should not?) reference between the component data and the actual mesh... woul di redraw the whole voxelchunk ehenever its changed? or do i partially stitch the mesh together by deleting vertices at some position and caclualting the new surface only where its needed?
alos i cannot get the right coordinate of a vertex anyhow, as a vertex may be between two coordiantes when i lineary interpolate it based on the values for those coordiantes
redraw the mesh on demand, yeah. You should optimize the size to be fast enough to remake mesh while not being so small you need a crapton of them (assuming a crapton of them is slower)
I wouldn't throw the chunk away...since you might be standing on it.
You can just change the translation of said entity changed
its not an entity, the chunk iteslef i sone big entity wiht many vertices inseide
oooh
When you build the mesh that's the way you wanna do it
ok thanks
I was referring to making the mesh for an entire chunk VS making mesh for each block
But also, yeah, the simplest way is to handle terrain changes have some flag on a chunk whether it needs re-building. As a bonus, the same system can probably spawn generate the mesh around the player to begin with
How would I go about checking if there are any entities above my current entity btw?
Each entity has a position placed in a component, so normally I would just check a dictionary if there is a key vector3 there, but how would I go about checking these values in DOTS and can I limit it to ones which has the same shared component values?
Like, making an entity query of the ones with the shared component that has "worldchunkvalue == 1" or something
So to be clear, you want to check if there's a block above another block?
yep!
Grass?
Because that's one reason why you'd want entities be entire chunks rather than individual blocks
Because then you, in the generate mesh(and find texture (UV coords)) method, have a flattened array of all blocks in chunk, and probably an easy (cheap) way to get neighbouring chunk if needed
Do I consider adding a component to an entity as a structural change?
ergo, I would need to ecb it?
no wait... I think I answered my own question nvm
I use ecb to add components at least.
Yes, adding and remove componets is structural change
Maybe I should create an entity with a hashmap of chunk index and a list of positions where I have placed cubes...
Maybe there is a better way to store that hashmap...
You might wanna consider properly chunking your blocks (so entity per chunk, as opposed to per entity)
With fewer entities to content with, it should be easier to handle issues such as that
So instead I would have an Entity with a list of vertices basically
Which list type would be used in an entity, is it the nativehashmaps/nativearrays?
Probably DynamicBuffer<T>
Hello, I'm trying to understand DOD/DOP, so Question: would this example below be Data Oriented Design/Programming?
PlayerPositions{
public Vector3[] playerPosition;
}```
where playerPosition[0] would be the position of the first player and playerPosition[1] would the next player's position?
instead of
```cs
PlayerPosition{
public Vector3 position;
}```
and generating instances of playerPosition and then doing your function with it.
Pretty much
would it be detrimental if I have PlayerPositions in a sort of a Tree/Node inheritance structure and then reference that node containing PlayerPositions? am I breaking out of the design?
"and then reference that node"
๐ค this concept is really being difficult for me to fully wrap my head around.
if you want to know how to code in DOD/DOP way.
the best I can point you to is this video.
https://www.youtube.com/watch?v=ZHqFrNyLlpA
In this demo we start to do some 'object-system-ish' stuff, but with a data-oriented mindset. The goal is: how do we recreate some of the high-level expressiveness you get in a language like C++, but in a way that helps make your program fast?
jsut avoid referencing things and work with value based things isntead
I've checked some videos already but most use complex web frameworks to demonstrate it and it was hard following everything but this one seems to be C#...no It's C++
let me check
btw, that's in C++.
not to worry though, if you listen and see his code and also what he's outputting with it, you'll understand how to prolly code in DOD
you can't entirely avoid referencing though, that's where I'm not sure of when to do it and when not to.
EnittyQuery is what u use for "referencing"
Although I don't understand why you want to make your own ECS-like system. when unity already has one for you that gives you high level expression already.
Maybe for learning purposes?
its less referencing and more searching for your entites
yea I'm trying to understanding it all, aye learning purposes.
@gusty comet then I recommend watching the video I linked. J. Blow explains it very well.
Thanks! will do.
I'm really trying to make a system for not coding at all sort of like visual programming but with granular components to make the functions that I need for the data I wish to transform and as my current layout stands I've designed it all thus far in OOD and have all my Data in a Dictionary Tree structure for clarity and maybe scalability? and I'm currently thinking from knowing little from the resources I previously checked to do something like attaching playerpositions to a node instead of playerposition but this all will still revolve around using references but I guess I need to ditch classes entirely now
still haven't watched the video... I'm getting to it...afk
@cursive cosmos For a blockchunk you'd probably want a flattened NativeArray<BlockInfo> (simplest form: ID of block type). This could be placed on entities representing chunks.
You will need some communication between chunks (check if blocks neighboring etc), which could be done by having another entity(singleton!) with a NativeHashmap<ChunkPos, Entity>.
Whenever you're doing an operation requiring neighbouring chunk info, you'd, you'd grab the neighbouring chunks in the main-thread OnUpdate and send that to the relevant job(s).
You want your chunks to be as big as possible while not taking too long to generate - I'd set this using a const value, and that means the hashmap shouldn't need too many chunks, and thus be quite fast to access.
One thing to note with this is that you want two "circles" of chunks - an inner circle of loaded and built chunks, and an outer ring which is semi-loaded; the block info is in memory, but no mesh is built so it's purely in case the inner circle needs neighboring block info.
The design here is a bit complicated, so ask me if it's unclear what I mean or you want to know the "why"
@tawdry tree can I ask you to take a look at my spawn system? I wanna know your opinion it.
Sure? Just DM me if you want, or take it here if you think that fits better
alright lemme put it all in one hastebin
how come IJobForEachWithEntity was made obsolete?
Probably because it is more code (boilerplate) than what replaces it (primarily Entities.ForEach in a SystemBase system).
ah gotcha
okay here it is. @tawdry tree
https://hastebin.com/eweruhidab.cs
context: I'm currently making a bullet hell game.
And I wanna know if my implementation of spawning bullets is okay.
and also how can I expand on this bullet spawn system for more bullet patterns?
right now I only have the bullets going at random direction.
@deft stump
-Aside: C# convention says CapitalPascalCase for object fields, such as the value(Value) fields of ICDs
1 - Having BulletSpawnSystem create entities before simulation means you (to the player) effectively spawn bullets one frame into simulation. Is this intentional?
2a - StopSpawningData stopSpawn seems a bit odd to me, waht's the purpose of this? When is it set?
2b - If you want to keep using stopSpawn, invert the if-condition to reduce nesting (if(stopSpawn.value) return;)
3 - To expand the bullet-spawn system, grab the player(s) position and velocity. Then you could fire towards the player, in front, behind, etc.
4 - If the bullet always has certain components and data, consider making one or more archetypes. This would be done in OnCreate(), and reduces the amount of "stuff" in the OnUpdate() Entities.ForEach. It should have a neutral or possibly even positive performance impact.
If you're using Visual Studio, there should be conventions for naming built-in. Otherwise you can just add that. Oh, and to improve chances of following the convention, crank it up from suggestion to warning or even error
C# convention says CapitalPascalCase for object fields, such as the value(Value) fields of ICDs
Yeah I should try to follow conventions XD. Really in VS already? I'll look it up.
effectively spawn bullets one frame into simulation
what I was going for is... spawn the bullet before the BulletMovementSystem does stuff.
StopSpawningData stopSpawn seems a bit odd to me, waht's the purpose of this? When is it set?
I want to have some sort of ROF and not spawn bullets every frame.
To expand the bullet-spawn system, grab the player(s) position and velocity. Then you could fire towards the player, in front, behind, etc.
I was thinking of adding a SharedCompononentData with an enum in it. But I dunno hahahahhahaha. then have several systems go through it. Like let's say a set of bullets are homing type. and another set maybe do a flower pattern.
If the bullet always has certain components and data, consider making one or more archetypes. This would be done in OnCreate(), and reduces the amount of "stuff" in the OnUpdate() Entities.ForEach.
So create an EntityArchetype in OnCreate and in OnUpdate() edit the values it up as I need to?
Regarding #1, I would make the bullet spawn at the end of simulation, and the bullet would then be simulated from the next frame. Reduces synchronization, too.
For #4 yes, create the archetype in OnCreate, and spawn it in OnUpdate, and once you have done that, set any specific values as normal. The archetype is static once created,
#3 - having an enum of spawn pattern sense, but if youwant bullets to stay in pattern while moving you might need more than just spawning them right.
Also, do you just randomly spawn bullets, or are they fired by enemies?
}
protected override void OnUpdate()
{
blank line between members
//A system
add space between // and comment. Should be indented the same level as the block they're related to. prefer to use a /// summary for public facing member descriptions.
//<--------SYSTEMS-------->
avoid ascii art, and avoid obvious comments, if you need to group stuff consider refactoring or use a #region
@mint iron um it's just for hastebin purposes.
Also, do you just randomly spawn bullets, or are they fired by enemies?
they're fired by enemies.
but the pattern right now is that all the bullets are fired in random directions.
#2 Regarding firerate, I think it makes more sense to save the last time it fired and ROF and comparing that with current time. Unless you want asystem devoted to checking that and setting the stopSpawn value...
Straight towards player makes more sense for bullet direction, doesn't it? Just grab player pos before the foreach, and you can use it in the Entities.ForEach
I think it makes more sense to save the last time it fired and ROF and comparing that with current time. Unless you want asystem devoted to checking that and setting the stopSpawn value...
I honestly dont want to have another system checking it. It feels so wasteful to check something every frame
Well, how does the stopSpawn value change, then?
Ultimately, if you want to fire at specific points, you need to check somewhere whether it should fire or not.
That's why I think it makes more sense to have LastFired and ROF values, and checking them in that system(BulletSpawnSystem). Which, by the way, already checks "stopspawn" every frame anyway...
Straight towards player makes more sense for bullet direction, doesn't it? Just grab player pos before the foreach, and you can use it in the Entities.ForEach
yeah. but what if I want 4 columns of sine-wave like bullet pattern. It doesn't have to be homing. It can just go straight.
do I have to make a system for that? if so, do I use SCD's with enums in it and have the system setfilter the scd? or do I do tags?
That's why I think it makes more sense to have LastFired and ROF values, and checking them in that system(BulletSpawnSystem)
this is actually want I wanted to do before I wrote that SpawnTimeGapSystem that only checks if it's time to spawn stuff or not.
is the only way to convert to entity "on demand" to put a "Convert to Entity" mono on the GO when we want to, os there a wa to tell the ConvertToEntity component to wait for a call from another component ?
torsina, could you explain why you would want to do that?
@deft stump Yeah, you'd need a separate system for special motion patterns. I assume you have a MoveForwardSystem to make the bullets move? Similarly, you could have a MoveSineSystem. Or MoveInFormation or whatever. The latter you might want for enemies too, come to think of it.
@tawdry tree thanks hodhandr! I was dreading the special motion patterns for... 6 hours! XD
Does anyone have a sample for World Serialization?
I'm using SerializeUtility.SerializeWorld but im unsure what to do with referenceObjects, i need to serialize those as well?
referenceObjects is a Array of unity Objects, things like Mesh and Material, I'm guessing I should be saving some sort of lookup link for them?
Hmm I'm wondering how I can temporarily disable collisions (but not PhysicsVelocity) for a few entities, or how I can make it that they can't collide with a particular entity.
I've looked into CollisionFilters, they do what I need them to do but PhysicsCollider has a BlobAsset reference, so I think that's the same collider for all entities; however, I need all projectiles spawned by one entity to safely leave its colliders.
...Spawn the projectile outside the bounds of the collider, by some combination of shrinking the collider and moving the projectile spawn point away?
Theoretically possible, yes.
I have a lot of guns on a lot of ships though.
Their pivot and relative origin is very close to the mesh, and the projectiles are rod-shaped.
I could spawn them a little outside but that's more config data. (well dynamically managing collision filters is also a bit of work but I got the system set up - I just can't actually set the filter on the colliders because I can't seem to find the component)
@warm panther Awesome, Ive done the same thing. How I solved it is i didnt have colliders on bullets, instead i would RayCast per bullet (not every frame)
then when i had the raycast result i could compare the entity, each bullet kept a reference to the owner ship
so it became a simple != owner
yes I'm tracking the owner too
I could work with triggers...
I wonder if I move the projectiles out a bit along the firing axis, whether that suffices. There's still the issue with the shield bubble they spawn inside, but I could indeed make that a trigger I THINK (current collider based method works really well for precise impacts)
My plan was:
Each ship gets a negative collision id, that becomes the groupIndex for its colliders and the colliders of the bullets.
I'll have a lot of ships, but it's unlikely 2 billion IDs ever run out, and I could also pool these if need be.
I looked at those group ids, I didnt think it could be used like that
If they're positive and equal, always collide.
If they're negative and equal, never collide.
Otherwise, use the bitmasks
// Return true if the given pair of filters want to collide with each other.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCollisionEnabled(CollisionFilter filterA, CollisionFilter filterB)
{
if (filterA.GroupIndex > 0 && filterA.GroupIndex == filterB.GroupIndex)
{
return true;
}
if (filterA.GroupIndex < 0 && filterA.GroupIndex == filterB.GroupIndex)
{
return false;
}
return
(filterA.BelongsTo & filterB.CollidesWith) != 0 &&
(filterB.BelongsTo & filterA.CollidesWith) != 0;
}
use a custom collector
I'd rather like to use this a little differently actually (modify it so it can deal with multiple physics worlds folded into one until unity cleans up their physics stuff)
use a custom collector
@safe lintel huh?
if you want to ignore self hits ie projectile raycasting?
I'm not raycasting, the projectiles are physical objects
meaning they will generate collision events
and get deflected unless I somehow disable collision (or ensure they can't spawn inside or clip the hull on their way out, which has a lot of corner cases)
and for missiles, that spawn inside a tube and then go out, there's no way around that.
personally i would use collidercasting (and a custom collector) for this over having an actual collider for collision events, and afaik trigger and collision events for now arent multithreaded
I have an impossible problem today! Literally!
the colliders are pretty chonky of the things I'm firing
So the collidercast would happen every frame for each collider?
Based on the predicted distance traveled, or looking backwards?
What's the tag to post code here again?
private void OrientCamera()
{
Entities
.ForEach((Entity entity) =>
{
}).ScheduleParallel();
}```
That does nothing and is never called anywhere. If I delete it, the behavior of my game changes.
Code bracket:
```cs[linebreak
(code)
```
Is there a temp file somewhere I need to delete or something? Code that does nothing and is never run should have no effect.
Not only does the behavior of my game change, but it does something it isn't programmed anywhere to do. It rotates thousands of entities without being asked to.
Is that code exact or paraphrased?
Does anything call it
Also, have you checked the entity debugger to see what systems are running and and without the code?
The entities are quads built procedurally to be flat and facing so that their up vector is the positive y direction. With that deleted, they're rotated 45 degrees about x, but show no rotation. It's like the whole world rotates briefly.
Nothing calls it.
Only the systems that should be running, are.
What if you change the signature to have some component or combination of components that doesn't exist?
No change there when I delete that code.
What if you comment out the entity query but not the method?
If I add something that should give me a compilation error, it does. If I change the query, same effects.
As soon as I comment the query, the quads rotate.
Bug in the scheduler?
So if you make a query with a completely new component that is never added to anything and change the entity foreach to (in allNewComp)={}, does anything change?
One moment
You could also try to make a minimal repro project, and if that reproduces it's obviously a bug to be reported.
If I take out the Entity or put in an unused component, then the rotation happens
Do you have the project as a Git repo, local or otherwise? Because if so you could clone it to another directory and see if it also does the thing there. If it does not, you could delete all the unity-generated files (remember to close unity and IDE first) in the original project
I gotta go now, but I hope you find a solution ๐
@warm panther I do it every frame for my bullets based on their velocity, and looking forwards. its raycasts but it should be pretty much the same thing for collider casts. i replied to someone else on using custom collectors for the purposes of ignoring self collisions https://forum.unity.com/threads/physicscollider-value-value-castray.905759/
@tawdry tree Noticed the meshes can only hold a certain amount of vertices, meaning that if I make a big world, I will have to start looking at stacking chunks when spawning in a mesh for each chunk^^;
Thanks a lot for that @safe lintel
@cursive cosmos Mesh has indexFormat now, so you can have up to 4 bullion vertices
https://docs.unity3d.com/ScriptReference/Mesh-indexFormat.html
How come my mesh just stops if I go too big then...I'm not even talking a lot, I'm making like 3 sides of 100x100x100 cubes
@ocean tundra Do I need to add some settings to my mesh or something?
I just added vertices, triangles and UV's
try setting that index format
Like so?
I'll try running it in a bit, doing a bit of an overhaul, so can't test it yet.
yea
Can dots interact with non-dots things?
@abstract flume Yup, but you lose out on some of the performace/threading gains
But it's still multithreaded?
no
That's all i care about
only the DOTS bit will be
So then i need to use JobSystem?
anywhere you interact with old Components or Monobehaviours you lose threading
no stay with SystemBase for it all
I need parallelization
how many old Components/Monobehaviours do you have?
Most things will use old components and monobehaviours
i would recommend writing the compex parallelization code as pure ECS and then pass whatever data you need down into old gamobjects
that way you gain the performance and parallelization for your demanading maths/logic/simulation stuff
prob meant using job system which is different from JobSystem
Only resource intensive things like casting spells will use ecs because i don't have anywhere near enough experience with ecs to use it for everything
I meant Jobs
Would Jobs let me use multithreading with monobehaviours?
honestly that sounds more complicated then just using ECS and mixing with old gameobjects
yes. but you still need to pass in managed stuff into the jobs code as a local variable.
Jobs will give you multithreading, but what will you even be threading?
you cant instantiate in jobs
i dont think you can even access transforms
Then that wouldn't work
to get jobs working you need to get your data into a NativeCollection, all as structs
work on it
then you get a native collection out of stucts that you need to map back to things
thats basicly what ECS does
i think there is a jobs compatible physx API now days, and a nav mesh one too
Im currently using recursive coroutines for my Spell System, but i noticed that things have a small but noticable delay even without adding any delay
i think changing to using jobs is def a lot less complex than changing to ecs
but you need to do it only for code that is your bottleneck
and there's very few cases where jobs are the first solution to that bottleneck
@abstract flume what part is the delay tho? if your instantiating things then maybe you just need pooling instead, or break things up over a few frames
Yea what @hollow sorrel said, jobs isnt the first solution to performance issues
Anything, instead of doing any actual spell things, im currently just drawing a debug line from the player position to the spell target position
delay sounds like a coroutine problem tho, unless you mean the entire frame is freezing
No, just a slight fraction of a second delay without using any delay in my spell
@abstract flume def profile it, if your not instantiating things what are you doing thats slow?
The only thing being done except for recursion in for loops and switch statements is Debug.DrawLine
how many of those? debug stuff can be a bit slow
Once per execution of the coroutine
It takes a fraction of a second per line, i can see the lines appearing after eachother
btw @ocean tundra for some reason 32 bit doesn't work, no errors, but it doesn't render the mesh
@abstract flume but the game dosnt freeze??
@cursive cosmos What??? that sucks i was planning on using that for my terrain meshs
maybe a limitation in hybrid renderer?
@abstract flume ok good so if no freeze then its your code and not a performance issue
coroutines are broken up over frames
Yes, if i remove the yield return then it all gets drawn at the same time
yup thats how co routines work
Anyone know what might cause this?
I do instantiate the object at 0.0 which is by the point it just dissapears from my sight in the scene. Is this just some scene standard?
@abstract flume Yield return XXXXX will stop executing and continue next frame or next XXXX you returned
Ah
@cursive cosmos Check your components on them, looks like one of the Bounds (worldRendeerBounds???) is missing or still default
I cant remember the exact name of it sorry
I do have it on, and it is still set to default, what should it be at?
Well it's just a mild annoyance (and the person in my team responsible for server hosting asked me to make things multicore), I'll see what i can do
@cursive cosmos umm i think the world bounds??? im not too sure sorry
@abstract flume Coroutines are not threads
@cursive cosmos Ive seen it set to mesh.bounds somewhere
worldrenderbounds should be world pos/rot * mesh renderbounds
Yes, that's why i asked about if ecs or jobs can interact with normal MonoBehaviours, because I often use scripts from asset store or similar as Black Boxes, and I want to avoid making everything with ECS
normally it gets autocomputed from renderbounds and ltw but dunno if you're using default systems
@abstract flume Core unity is very unfriendly to threading, Theres lots you can do, but you cant really touch anything inside UnityEngine (which is sooooo much). DOTS is AMAZING for threading but you need to use Entities and Systems to access it easily
Are fps player controllers possible with ECS?
Yea theres a whole MP fps sample somewhere by Unity
Ok
If i manage to make everything in ECS, then that would make my server host very happy
yup ๐
its even better then that, for your server mode you could completly strip 3d models, textures, sounds
i even tick my server slower then 60 fps, currently at 20 fps to save performance
Yes, I haven't looked into server code and netcode at all yet, everything is still in early stages, nothing works fully and probably very little is actually compatible with other things currently
yea i dont like the new netcode at all ๐
if you want MP tho you have to do it early
Only networking I've done is with Mirror
it should be one of the first features working
renderbounds only has a "Value" what am I supposed to do with that information x)
This is my first 3d game so i have no idea what I'm doing
And i made my last 2d game in Unity 5.4
@cursive cosmos Add RenderBounds and set bounds by mesh.bounds.ToAABB()
found that googling
think of it as like drawing a box around your mesh and it'll only be drawn while the box is inside camera view
YAY
I don't know what it does, but it works!
@cursive cosmos basicly unity wont render entities that you cant see
this keeps them rendered until you actively remove them yourself?
and your bounds were in the wrong place so it would be culling them even tho you should be able to see it
i think they will still be culled, but it should match your camera now so will look fine
Shweeet, finally can start to render buttloads of chunks, and try to get that 32 bit to work...
please let me know if you get that to work, might save me some time when i start creating my meshs
Are there any good tutorials on ECS?
I got one that is plenty good, just a sec.
This is a sample project to compare a simple task in "Classic" Unity versus Unity DOTS/ECS:
https://github.com/UnityGameAcademy/DOTSCompare
Several thousand cubes push forward until wrap around the screen. Use the dropdown to change the GameManager's Mode from "Classic" to "...
Thanks
@safe lintel Hey so I finally got to my world serialization, and tried Odin serializer, No luck serializing the referenceObjects yet
@abstract flume It's really good. The Game Academy also has a playlist where they go through a game with you using DOTS/ECS and not just the concept of it.
yeah i am hoping unity does the hard work for me in this case, otherwise i will have to pester eizenhorn for more details on his experiences ๐
i found a post from him in the fourms, saying that he removes those shared components and replaces with a ID pre saving, then reverses that going the other way
@safe lintel https://forum.unity.com/threads/serializeutility-deserializeworld-throws-no-objecttable-was-provided.907208/
I'm planning to integrate with unitys Addressables for dealing with my referenceObjects
i saw that, but what im unclear is on if the unique id is automatically created somehow or if its done manually in some way.
i would guess manual
if you hook it up via addressables, do you kinda have to reconstruct all of your prefabs?
๐
the thought of manually listing out every asset just makes me cringe
You can mark materials and meshs as addressable
the key issue ive run into is taking a unity Object and getting its Address
Like why cant i go Addresssables.GetAddressFor(OBJECT)!!!
but i have a solution
in editor i take the Object.name and its HashCode (havnt tested this completly yet, hoping hash code stays the same in editor and build) and then map those to a Address
as every unity Object has a Name, which apears to be its filename
and those reference objects are all Unity.Objects and have that name field set
hmm interesting
so i have a map scriptable object that contains all those name/hashcode to address
i havnt completed all this yet ๐
i ran into the getting address for existing object issue last night
and this is what ive dreamed up
its not perfect, as im planning to proc gen my terrians so i imagine ill still have to custom serialize those
also if theres changes to a matieral this system wont link back to the original which im unsure is a good thing or not
i might not be thinking clearly but just thinking about it all makes me think i need to construct the prefabs if i create addresses for all my assets and kinda frankenstein it all together when loading, which kinda rules out wysiwyg unityeditor approach to creating prefabs and stuff? i dunno its late and this is a problem that i shouldve investigated at the start of my project ๐ฑ
so basicly im trying NOT to reload the whole prefab
as ECS world will contain all the entities and prefabs and things, it only really needs is the Meshs and Materials
you could have something like, each prefab has a guid address component , you copy the whole world to a saving world and remove all linked components (or just child) and strip off things like rendermesh
then on loading you loop over every entity that has that guid address, load and convert the prefab and reattach/link children
but that sounds way more error prone then figuring out how to get a unique id/address for a Unity.Object at Runtime
ill be working on this tonight so if i get it working ill PM you, will be happy to share this code too
cool, my brain is totally worn out tonight
anyone know a good way to .Complete() a World? maybe iterate all systems and .Complete() their Dependency but doesn't sound like a good idea
basically a callback for knowing when all jobs scheduled from the World have been completed
@hollow sorrel Entity manager has a complete all jobs
or you could force a sync point somehow
ooo
thanks! that'll prob do it
also i thought sync points complete every job currently in progress, but then continue with the rest of scheduled ones after the sync point?
if that's not the case, wouldn't the sync point at the end of the default world try to complete all jobs
not sure
yea your probably right
yea i think complete all jobs after world.update
as all the jobs should be scheduled by then
and jobs cant schedule other jobs
why do you need to complete a world?
messing with seperate sim/render worlds, dunno if i'm gonna have them run synchronously like that in the end but wanna test if it works
yea having them run completely seperate is prob best, at worst they'll be 1 frame out of sync but who cares
so mine is made to be out of sync
sim world is always at least 1 tick ahead of the client
so ive made mine for networking, so inputs get captured on the client world, and sent into a message queue
but my input isnt raw inputs
my game is a RTS so it all commands
eg move unit 1 to x y
complicatedly ๐
yea all over the network
i dont do any predict/rollback yet
not sure if i will at all
my issue with input is the sim updates at a fixed rate right
but unity updates its input once per Update() basically, so if i do input in the simulation world there's a chance the player's input falls in between updates and doesn't get processed
was thinking maybe seperate input world but goddamn that seems more hassle than worth with how barebones serialization is right now
how do you deal with that?
all custom
using Ceras serializer
Universal binary serializer for a wide variety of scenarios https://discord.gg/FGaCX4c - rikimaru0345/Ceras
super nice
but it depends on code gen which was a pain to get working
oo ya i've looked at that before
but for local worlds im planning on skipping that bit
what about inputs tho, do you use a seperate input world?
btw interesting to see someone use ceras, never seen a project that actually uses it yet
ah
not sure ill keep it
one day i want to use UnityTransport which kinda has its own serializer
but ive looked at moving to use it and it looks scary as
so will wait
i've used MessagePack in the past which is nice but i'm not sure if it lets you deserialize without knowing type beforehand
but yea for ecs i've only been looking at SerializeUtility, the use case there seems to be to copy/move the shit you want to serialize to a seperate world, then serialize that world
can you give me some pointers on how you started to serialize yours with ceras?
like do you just loop every entity?
Technical deeptime into the unique networking architecture of Planetary Annihilation.
i implemented that
so server world has a bunch of things i want to sync like position
i have a system with a change filter on it
when it changes i take the value and current time and write into a dynamic buffer of a different entity
i have another system that tracks those, loops over the buffer and sends what needs to be sent to each client
its still pretty early days but works really well, im not sending much info around, and ive just worked on projectiles which are very cool as i predict the path and can send start+end when shooting the arrow
- have tons of optimizations planned
ooo that sounds pretty cool, lots of optimization there with just start+end of curves
yup
let's say you want to serialize a new property like position2 for lack of originality, does that mean you have to add it seperately to your serializesystem and then deserializesystem?
or do you do something fancy for that
kinda fancy
i have code gen in place now
so i make the IComponentData
then select that for code gen
ooo
then on the entity i want to sync it for, i add it and a Record_Position2 component
and on the recordStore entity i add its dynamic buffers, ServerKeyFrame_Position2
on the client entity i also need to add dynamic buffer ClientKeyFrame_Position2
and a playback_Position2
yup ๐
was painfull the first couple of times
the worst part is setting up my entitys/prefabs
but im reworking that now
as i need to take the prefab and then add a bunch of stuff depening on if its client or server
and one day want to strip off stuff too, like meshs
nothing really
i just want to use Jobs everywhere
to do that i need Unity.Transport
as my networking layer is currently ENet
and dosnt work with Jobs
ah
damn i'm not looking forward to implementing serialization
thought it was gonna be easier hah
its not too bad
just the default code gen was annoying as
ended up just using the exe version
and calling that from unity
do that and save yourself the pain
thanks for the advice
happy to help
i wish there was a simple way to mark components for serialization and just loop through world and only serialize those
and then patch them back when deserializing without messing with the other components
altho i guess that's where the codegen comes in
i have to go do stuff, if you have any more questions PM me
and there kinda is
but its more for whole world saving
Is it normal that Converted entities from a SubScene do NOT have the LinkedEntityGroup component? It for sure seems to get added when instantiating from prefabs at runtime ๐ค
Turns out it is: https://gametorrahod.com/game-object-conversion-and-subscene/
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) {
conversionSystem.DeclareLinkedEntityGroup(this.gameObject);
}
5argon is a frickin champ, he's solved like half my problems. Right up there with @storm ravine ๐ช
Half the credit goes to WAYN_Group in the forums: https://forum.unity.com/threads/dots-skill-system-repo-available.894007/#post-5884673
It's for a revamped/flexible skill system that both of had worked on and will end up replacing the "fixed" attack system in my game ๐
His repo is here. Definitely worth a look if you're building some sort of skill/ability system: https://github.com/WAYNGROUP/MGM-Skill
Oooo interesting
I ran into limitations with my own system and figured it's worth to make a more generic rewrite that allows for creativity/easy of creation for new abilities: https://youtu.be/upDWz-AFOys
Next up is getting up to par with the old system, projectiles and particle system "effects", then new stuff like AoE and healing spells which would have required significant extra work before ๐
So pumped ๐
How to batch remove tags?
Many options. One of them: entityManager.RemoveComponent<Foo>(entityQuery);
ok, just pass in an entityquery of stuff with component?
entityManager.RemoveComponent<Foo>(entityQueryOfEverythingToHaveFooComponentRemoved);
yup
Ymmv. There might be more efficient ways though. Afaik this will create a sync point on the main thread, because entityManager is main thread only.
Is anyone able to build using IL2CPP + Unity (it just crashes for me the moment I launch the game).... I tried with a new project with just the default unity sample project and adding the entities package (Same result in 2019.3.2, 2019.3.15).... it only worked on 2020.1
hrmmm
I dont understand
how do I add an archetype with ecb?
I see a CreateEntity() function... it's return type is an entity. And it's just creating an entity not spawning the entity prefab that i have

yup
kinda sounds weird tho, i never did any archetype stuff, it seems redunant for me, but ECB is for making structral changes, and creating an archetype isnt a structral change
what is your use case ?
I'm making a bullet hell game.
So I'm using a system+ecb(let's called it spawnsystem) to spawn a bulletprefab.
I plan to extend the spawnsystem to add some components so that other systems can manipulate the bullets in special motions.
it feels like... using ecb is so freakin slow..
no matter what i do with system.. I feel like I'm being bottlenecked.
to the docs! search for a better alternative!
For systems that need to operate over monobehaviours does anyone know if there are different performance characteristics for using class bob : IComponentData { public Component Value;} vs e.g. entityManager.AddComponentObject(entity, component)?
@deft stump did you see the Instantiate method instead of create?
@mint iron in ecb?
yeah
entityManager.Instantiate(prefab, nativearray<entity>) is crazy fast - might not even need ecb?
the overloads for that is Instantiate(int jobIndex, Entity e);
that's the only overload offered in ecb
I have to manually 1 by 1 add components to the instantiated entity
pretty sure you can get the index it wants; but if you use a non-concurrent version it should let you without it
@deft stump you sure you need to add components 1 by 1 per entity? Rather than to the first entity and then instantiate that? Also fwiw entityManager has a .AddComponents method I think.
How to combine meshes in ECS?
there's also ecb.CreateEntity(archetype) overload
@mint iron I actually dunno how to use that XD.
i'm guessing it creates a new entity?
but I'm cloning from a prefab entity sooo... might not be good from what I'm doing
@deft stump you sure you need to add components 1 by 1 per entity? Rather than to the first entity and then instantiate that? Also fwiw entityManager has a .AddComponents method I think.
@amber flicker well I adjusted the system. all it does is set new values to the components and not add components (I figured it'd be faster).
yea setting new values is massively faster than adding components with values
I actually dunno how to use that
https://github.com/jeffvella/UnityEcsEvents.Example/blob/11e0a09f8592dc3b947686f7ab7af2b739d153f6/EventsExample/Assets/Game.Scripts/Systems/SpawnPlayerSystem.cs#L57
as you're not changing the structure and forcing a sync point each time
but isn't using an ecb already forcing a sync point?
yeah but every time you add a component it does that in isolation, its not smart enough to know its got another 5 adds to go, and so it makes a compeltely new archetype every time
it waits for all jobs to finish in whatever commandbuffer you set it to. and under the hood it probably does entitymanager stuff
eah but every time you add a component it does that in isolation, its not smart enough to know its got another 5 adds to go, and so it makes a compeltely new archetype every time
true.
5argon is a frickin champ, he's solved like half my problems. Right up there with @storm ravine ๐ช
@spark glade Yep Sirawat cool guy, we chat with him from time to time in slack (he also in Unity slack), he one of them who was at the beginning (a bit later than me but not so far) and yeah he has good explanation for many DOTS basic (in meaning - root) things
how can i access on a job to a component that has a dynamicarray<float3>
i mean
i have a elementbuffer that contains a dynamicbuffer<float3>
similar to a list of list
but i want to fill it on a job
and i cannot create a dynamicbuffer on it so
i dont know how to proced cause i cannot use a nativearray on a component
@storm ravine i know i always ask to u , could u help me one more time pliss ๐
Iโm driving now, canโt write much, but simplest solution (if you really want array on component) store entity in that component which has another buffer for representing array. Or use unsafe containers or write your own
thanks man ๐
is there any difference between having 2x foreach in one system, and having 2x systems with one foreach?
if i meet u once, i will pay u some beer @storm ravine
is there any difference between having 2x foreach in one system, and having 2x systems with one foreach?
@dry dune Do u mean about complexity or something ?
performance
i dont know much about this so before saying idiot things i think i will better shut my mouth
i was going to say that it depends the calls u made or something but i dont really know
sorry ๐ฆ
take a look at hybrid render but i dont know
I doubt terrain is supported by either hybrid renderer or dots physics directly
as for anims, there's DOTS Animation package but it's super experimental
On that thread, Joachim wrote this on last October: We are working on a dedicated dots terrain engine that will fill the hole.
wonder if that's still a thing
well, DOTS isn't "ready" anyway
you need to have a will to experiment with most of these things if you jump in today
Anyone know if there is a problem with hybrid renderer and 32 bit Mesh.indexFormat?
Tried using it and my mesh just vanished when using entities.
that frankly doesn't surprise me at at all ๐
I wonder if it's by design or if they simply forgot to test it
I've filed some bug in past for SRP batcher that broke with 32bit indices
apparently it's not a thing they test actively (or at least didn't back then)
Anyone know if there is a problem with hybrid renderer and 32 bit Mesh.indexFormat?
@cursive cosmos If you on built in render pipeline - all works fine (we're using 32bit mesh version)
built in render pipeline, would have to read up on that. Would be able to create some silly cool worlds if I did use it.
Have I understood it right that when working in a job, I should only use immutable classes as help to calculate things?
yo. so not using concurrent gives me a performance boost of...
wait for it...
20fps!
and pairing it with run gives me another 20fps!
lol

I'd be a little cautious what conclusions you draw from that but if you were trying to e.g. scheduleparallel a lot of ecb add components that could make some sense.
I keep finding myself trying to come up with neat and/or reusable ways to run some ForEach against either the same or some other entityquery (using a bunch of different data from the second entiyquery's hits components).
Currently thinking and reading about possible AI implementations and thought I'd just do something simple and dumb for starters. I've searched in this chat history as well as of course on google, watched talks, read forum posts, blogs... it seems there's very very little practical info about implementing AI in dots though ๐ฆ
currently I have the dumbest of all solutions that I would like to extend a little - my enemies chase the player if they're within x dist(sq) of the player
Just my opinion but beyond something like a* I think doing fast DOD AI will generally be quite bespoke to the game/task - not sure how much you could generalise. That said I did read a post that you may find interesting if you haven't read it.. will try and find.
but before I go making the equivalent of an if/else I figured I'd read up and think more about how to structure this so I can extend it and/or modify to drop in better solutions down the line
if it's the PxDev one I have ๐
I think there are two I'm thinking of as interesting - I can't remember one of them but the other is this: https://forum.unity.com/threads/dots-skill-system-repo-available.894007/ - it's tangential to 'how to do AI in DOTS' but worth a read imo if you haven't already
Cheers, will take a look
np - I also know I'm not being directly that helpful here - I haven't tackled something like this - perhaps someone here believes there are some good general ideas that apply and could be conveyed
interesting responses from Joachim on future enabling/disabling of components
yes - looking forward to those
not sure what you're looking for the AI to do; eizenhorn has certainly a lot of experience in his current project with villagers accomplishing various assigned tasks.
the core mechanic of my game is basically agar.io - I have a bunch of spheres. bigger spheres can eat smaller spheres. All spheres can pick up particles - generally these make the spheres bigger (but not always). Spheres can emit particles, and freeze opponents if they hit (but the opponent then also gets the particle that hit them so they may grow as a result).
I don't want to go down the full ML agent "beat my game" AI approach, I'm happy with fairly dumb spheres, but because I haven't fully decided on the final implementation and would really like to have something modular so I can test out different things, that makes it more tricky to get started in the first place!
For example, in this clip, the orange enemy is pure dumb - it doesn't yet know about shooting the player, it chases the player but doesn't take a detour to pick up the blue particle. Also, if it was not in range of the player, it won't currently go off picking up particles or actively searching for the player
how can a query become a nativearray of component but this component is a buffer ?
getbufferfromentity maybe ?
an approach of calculating a weight for the possible options I've found to be a good way to handle combat choices in the past where there are many factors to consider.
For example in a targetting system lets say you have 20 targets to consider and each of them have their own attributes/movements/intentions. You go through them one by one and add/multiply amounts to their weight based on conditions. At the end of that step you have a sorted list, and can take the one with the highest weight and perform the response to that target (which might be to attack, or run, or evade, or pickup a health globe nearby etc). Range tends to be a large factor with exponential weighting contribution the closer you get - so if you're standing really close to a pickup, it would be picked up before attacking someone far away.
yeah, from what I've been reading about utility AI it makes a lot of sense, though I think my conceptual issue starts before that point, like how to structure the modular code within an ECS project to actual do the sensing, storing of sensed data, processing of considerations etc
Then you have other more traditional behavior tree style loops that take control before and after where appropriate, so for example, you can't pickup something until you're standing on top of it, you can't melee attack someone until you move in range. Can you use a vault ability instead of walking when its off cooldown, etc all those things would take priority in the behavior tree sense where eneded.
at the minute I've built in pickups as an automatic thing (which I will keep rather than a pickup action, you simply have to collide with it to pick up). However, things like deciding to initialize/charge/execute a jump or emission (shot) would be something potentially to add down the line
not sure where to store it honestly or how this fits into ECS im talking from a different project i did the past but i had organized lists of actions, which contain a list of conditions, all or any of which need to be met and/or could be setup to modify a weight. that way you can add extra conditions and actions outside of the system that processes them.
The potential to have a cleverer AI is of course that it would give me a much wider scope for tuning difficulty, which would be lovely
totally, you could build in things like delays where it waits a while sometimes and is slower to make decisions
I read somewhere about someone storing their list of actions in Dynamic buffers - I think it was when searching through this discord channel actually
allways remember its not wrong to just dont use the ECS/DOTS for some stuff
if you have stuff that is fairly naturally OOP, like AI behavior tree, then just slap a normal C# class
although then I have to learn how to make it talk to the entities too ๐
while I'm here...
for iterating each enemy over all enemies (plus player plus pickups), I find I do this in a couple of places eg with collision checking. Would it make sense to have a single system that generates NativeCollections of the various components, so I don't have to go through each entityquery in different systems each frame for this stuff? seems to go a bit against the principles
it wont
in fact its a good idea
the unity ecs has huge overhead on "random" access
so if you have a pass that copies data into basic arrays (that can be indexed cheaply), then you can do it nicely
of course it depends... as usual
but if each enemy iteraetes other enemies, thats a N^2 problem, so doing the caching is likely to be worth it
Cheers @vagrant surge
i do something similar-ish on my boid experiments
the main problem is finding close boids, and look at their location
so what i do is that i build an accel structure, AND store that location within it
this way when im looking at neighbour locations
i only look at locations, i dont go through the ECS
I could add that in actually... good call - I already have a very simple grid acceleration structure that I use for the raymarching
someone explain to me the pros and cons in using ExclusiveEntityTransaction?
Asynchronous entities creation\destruction\setting values\adding values inside job. Entities streaming (for subscenes) works on EET.
so, when I add ENABLE_HYBRID_RENDERER_V2 to the scripting define symbols, I get a warning that the hybrid renderer only works with hdrp or urp versions 9 and up, but the package manager's most up-to-date version of urp is 8.1... where do i get version 9? I'm using 2020.1 beta 11
so, when I add ENABLE_HYBRID_RENDERER_V2 to the scripting define symbols, I get a warning that the hybrid renderer only works with hdrp or urp versions 9 and up, but the package manager's most up-to-date version of urp is 8.1... where do i get version 9? I'm using 2020.1 beta 11
@left oak enable preview packages.
ok, thanks! I already had a bunch of preview packages
but I guess that option gets reset time-to-time?
Project Settings -> Package Manager
It can reset once when they moved checkbox from Package Manager window
Preview packages which are already in the project - will be shown, not matter enabled or disabled that checkbox, but these which not in the project will appear only when checkbox enabled
Guys, does it make sense to combine meshes in ECS
What Minecraft would look like in ECS
new burst package ๐
Joker, what do you mean by combining meshes?
i bet it will be "updated dependencies" ๐
If you're referring to voxel-based terrain (like in Minecraft) you'd probably want to combine all blocks in a chunk into one mesh (along with hiding any block-side that is obscured by other blocks)
If we were to make minecraft in a regular unit, we would make a chunk in which a lot of blocks, these blocks are collected in one mesh so that there would be more performance. As a result, the chunk itself is drawn immediately and not each block individually.
sry cuz i use google translate ๐
yes i mean that @tawdry tree said
new Visual Studio Editor package.. crosses fingers
is that worth to use it ? for some reason whenever i created a new script from Unity and change to VS it always asks me to releoad, was kinda annoying so i deleted it, now it works fine
### Fixed
- Burst compilation is no longer cancelled when exiting play mode.
- Filter symbol warnings to prevent them reaching logs.
- Fixed handling of conversion from signed integer to pointer which caused issues as discovered by Zuntatos on the forums.
- Fix an issue where a function/job could run without being initialized.
- Fixed a bug with constant expressions that could cause a compile-time hang.
### Added
### Removed
### Changed
- To avoid users falling into the consistent trap of having `Safety Checks` set to `Off`, any reload of the Editor will issue a warning telling the user that `Safety Checks` have been reset to `On`.
- The command line option --burst-disable-compilation is now disabling entirely Burst, including the AppDomain.```
@opaque ledge honestly not sure - I think it's supposed to make working with VS smoother but recently it's not exactly been smooth for me.
i mean, everything works fine for me so i dont know why i need that package
Hopefully somebody actually knows. My guess is your solution isn't being regenerated when you e.g. add a file - with a new file do you get intellisense support without restarting VS?
# Code Editor Package for Visual Studio
## [2.0.2] - 2020-05-27
Added support for solution folders.
Only bind the messenger when the VS editor is selected.
Warn when unable to create the messenger.
Fixed an initialization issue triggering legacy code generation.
Allow package source in assembly to be generated when referenced from asmref.
## [2.0.1] - 2020-03-19
When Visual Studio installation is compatible with C# 8.0, setup the language version to not prompt the user with unsupported constructs. (So far Unity only supports C# 7.3).
Use Unity's TypeCache to improve project generation speed.
Properly check for a managed assembly before displaying a warning regarding legacy PDB usage.
Add support for selective project generation (embedded, local, registry, git, builtin, player).
(2020.2 supports c# 8 now btw)
Wait, so... 2020 + updated code editor package supports C# 8 syntactic sugar?
Or is it just the package for the sugar, and 2020.2 for proper support of new language features
Either way, gimme dat sugar
from 2020.2 alpha release notes (https://unity3d.com/alpha/2020.2a):
* Scripting: Compile scripts with C# 8.```
now we just wait for .NetCore support
that being said... https://forum.unity.com/threads/how-to-enable-c-8.900182/
what c# 8 has it exactly to make you so excited ? i thought the only big thing was that null thingie
Syntactic sugar
which is ?
Honestly I don't know how much of it is C# 8 vs 7.x, but being forced to work on a project in a professional capacity without being able to use modern syntactic sugar hurts my sense of aesthetics. And also made for a couple not-so-fun bugs to track down.
mfragger, there's no reason for them to do .Net core support - .NET standard (very recent) or skip straight to .NET 5
In case you didn't know, Core is being renamed .NET 5 in the next version (this september), and Framework is pretty much discontinued (though will have support s per the rules they've set for themselves
Curly:
In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.
(from Wikipedia)
https://forum.unity.com/threads/unite-now-q-a-stacking-up-the-new-functionality-in-dots-physics.907820/
about this... it does suck that they dont tell in advance who will reply to the Q&A
Heck, most of newer ECS can be seen as syntactic sugar for the previous, much more verbose, versions
yeah i know that, but what syntatic sugar you are so interested ?
like, switch statements ?
I mean, my questions would totally depend on people doing the thing
i will just look at the patch notes i guess ๐
if it's some Unity evangelist, I may just as well not ask anything
The one I've used the most is switch expressions, often together with enums.
Though C# nullables is great in a webapp/backend setting, for forcing the team to maker safer code
(granted, that's not syntactic sugar)
Oh yeah, and using declarations, because that removes one line of boilerplate which is a likely cause of bugs
it doesnt really help on DOTS tho right ?
And now I've listed like half the C# 8 features...
default interface seems also pretty good
Probably gonna end up using switch expressions with enum extension methods where applicable, but gamedev doesn't have quite the same needs and wants as backend programming
Still, that means I won't code and suddenly get taken out of flow trying to figure out what I'm doing wrong only to find out the project doesn't support my sugar...
Can't decide if I'm not used to or simply don't like this ๐
public static string RockPaperScissors(string first, string second) => (first, second) switch{};
Oooh, switch expressions can be great. I possibly overuse them slightly, but if you have an enum and you switch statement constist of something like these, then it drastically shortens your code
//A:
case SomeEnum.Option:
return someVal;
//etc.
//B:
case SomeEnum.Option:
someVal = someNewVal;
break;
You can also use when statements, but at that point one should consider full switch blocks. Right tool for the right job, and all that.
My biggest gripe is that each case needs its own statement, so you can't dump cases together with one result.
Obviously enums & switch are awesome and I can see the power of when and such.. but combined with tuples and a sort of implicit equals comparison of strings in the example I was referencing... kinda cool but also I'd probably always prefer to do it differently.
## [Platforms 0.5.0] - 2020-06-08
### Changed
- Tiny build specific classes moved from `Unity.Platforms` to `Unity.Build.DotsRuntime`.```
```md
## [Platforms.Windows 0.5.0] - 2020-06-08
### Changed
- `Unity.Platforms.Windows` assembly renamed to `Unity.Build.Windows.DotsRuntime`.
- `Unity.Platforms.Windows.Build` assembly renamed to `Unity.Build.Windows.Classic`.
Syntactic sugar should make code more readable, even to people who aren't super familiar with them. (I assume at least passing familiarity with the existence of the sugar, though)
I feel like that's a good guideline to keep in mind.
Yea agree - that's why I feel undecided about the rps example
@tawdry tree you can let switches fall through in c#, when theay ahve an empty body
Regular switches, yes, but not with switch expressions.
Childbuffer on the parent @halcyon plume canโt see what the parent entity has as far as components
@safe lintel It turns out no difference how deep it is inside? Does it all children and children of children, etc. become direct heirs of the main object?
What is blob asset store?
Have you tried looking that up, for example in the manual?
Generally a good first step.
https://docs.unity3d.com/Packages/com.unity.entities@0.11/api/Unity.Entities.BlobAssetStore.html
It used in conversion from prefab to entity
And when i use convertGameObjectHierarhy in entities created one example of prefab. Why?
when I convert a prefab I get an instance of an entity that doesnโt show up anywhere except in EntityDebuger
It seems strange to me that when we convert, we immediately create an object
And who, as it were, made chunks for minecraft in ECS? Do you need to optimize the blocks somehow?
When you convert a prefab, it makes an entity with the Prefab IComponentData. This marks it as a prefab, and makes it not ssimulated or rendered. That's how prefab entities work in DOTS.
Combine blocks into a chunk, and remove all faces (sides) of the blocks that cannot be seen (so you only show the outer "shell" of the blocks, if they are next to each other)
That's hopefully all the basic optimization you'll need. You can consider other things later, if you want/need to optimize your game.
I understood about prefabs. many thanks. But I did not understand about optimization. What would a chunk component look like? block?
Minecraft has one chunk as 16x16x16 blocks
I understand that it is necessary to combine the meshes and not show the internal ones.
1616256)
Data-wise, you would most likely have an entity, with a flattened NativeArray of the ids of blocks to say which blocks are in the chunk. Then some system would read those, and generate one mesh for the entire chunk
16-16-256
Oh, you're right, MC chunks go the entire world height. Must've been another place that split chunks vertically too
that is, will there be an entity with a Chank component inside which will have a NativeArray <Entities>?
public struct ChankComponent :IComponentData{
NativeArray<Entity> blocks;
}
I would advise against having block enties
//Note that this is class, because NativeArray is managed
public class ChunkBlocks : IComponentData {
public NativeArray<int> Blocks; //Flattened array of block IDs
}
public struct ChunkInfo : IComponentData {
//Does mesh require rebuild, ie. has the blocks changed
public bool RequiresMeshRebuild;
//Position of the chunk, in chunk coordinates.
//The one in the center of the world would be [0,0,0], with neighbors [1,0,0], [0,1,0], etc
public int3 ChunkPos;
}
You can with class ICDs
ah didn't see the class part
We had a discussion on what and why previously, also regarding procgen terrain
But the short version is that you should use struct in most cases
So i need to use monobeh?
can you give me the tl;dr of the benefit of using class+nativearray instead of struct+dynamicbuffer
Joker, no. Class ICDs are still within DOTS
And i can use Entities.forEach?
AFAIK you cannot grab the nativearray inside the ForEach in that case.
But changes to the world would be relatively rare (a couple chunks per second with several actors changing the terrain), so you can just grab them main thread, hand them to a job that generates mesh data, then use that data to set the RenderMesh (which also has a special case so you cannot fully make one in a entities.ForeEch or job)
You could use dynamicbuffer, but you have a known, constant array size, and as mentioned changes are fairly rare, so the constant size of the NativeArray is more "correct" compared to dynamicbuffer, with little drawback.
In the end, if you're not comfortable using class ICD and NativeArray, just go for DynamicBuffer if you can get that to work ๐
If you do not change in runtime array (data immutable) - Blob assets best
If you know array max capacity - Dynamic buffer with InternalBufferCapacity attribute best
Else Dynamic buffer with InternalBufferCapacity(0) using
@safe lintel Hey so you have Direct messages off or something ๐ But good news!!
I was able to link the referenceObjects back to their address and then load them again when loading the world
If I have a struct/method that is able to calculate the distance on a bezier curve does anyone have any idea how I might use that to move something at a constant speed along the spline?
hello has anyone tried porting the dots sample to urp?
because i did try and this happens
@ocean tundra sorry i mightve, went a bit crazy a while ago turning off everything to stop all the annoying discord beeps and boops
The mute feature is the best.
People who use "@ here" in public channels should be keelhauled.
@hidden holly urp isnt really well supported atm, it kinda works by accident in hybridv1, and in v2 only a directional light works.
Where is it not well supported?
what do you mean
how hybrid affects the render pipeline?
I can have hybrid disabled if I want how different is urp from hdrp apart from the deffered renderer?
indirect light & lightmapping are questionmarks, the docs page for the hybrid renderer should have detailed specifics on this
Okay, I'll check that out
Constantly need to remind myself that when I'm testing stuff in unity without DOTS I can't use the same standard I use in DOTS...Just tried to spawn a new galaxy without it and my computer is crying.
the answer is DOTS for EVERYTHING!!!
Yeah, but I'm merely testing out voxel spawning so I got more control of the terrain and voxels by creating my own mesh on the fly for each chunk instead of building it with blocks, and it requires some testing since I've never worked with vertices and meshes manually before ^^;
@cursive cosmos https://github.com/Syomus/ProceduralToolkit
So doing some quick testing in unity to understand what I'm doing, then sending it to dots.
check that out, if your building meshs from scratch theres some types that may help
MeshDraft i think
I have made an entire library from scratch actually. So no need anymore ^^;
I like the control I get from building it myself
trying not to these days, otherwise i spend forever playing with the tech/library bits
I do find it very trixy that triangles have a side you have to view it from, kinda weird but it explains all the odd graphical bugs when you look inside a character
But now is the time to transfer this shit into DOTS, gonna be fun.
Need to make like...everything static on some way or another
Want to be able to use it all in jobs if I can.
I like jobs.
jobs are good
Right, I knew I had a problem, all the chunks are using the same xyz inside of the classes, so technically, the same perl comes out xD
iz bad
seems easy fix, pass in a chunk xyz?
yep, just pass in an offset basically
but this texture sure is horrible, better change it away from unlit
http://prntscr.com/sw7xia
looks good
Okay, posting here since general code is no help,
Where would I add an offset to these noise methods so I can spawn the chunks with connecting noise?
I'm very shit at math.
public static double NoiseGenerator2D(float2 pos, float offset)
{
return math.mad(noise.cnoise(pos / scale), 0.5, 0.5)
* frequency;
}
public static double NoiseGenerator3D(float3 pos, float offset)
{
return math.mad((noise.cnoise(pos / scale) * 2 - 1), 0.5, 0.5)
* frequency;
}
I'm guessing I have to send the chunk position*chunkWidth in here as an offset, but have no clue where to place it x)
Yea you need chuck size, but it could be a const
and probably add it to pos
pos = pos + (chunckpos * chunk size)
I tried that, but weird things happen ^^; can show you
also show the code you had
So the scale and frequency are static values which should not matter since they only represent the waves shape, but crazy stuff happens when I add it to the 2D array, just a sec
that was changing the 2d noise by adding:
var NoiseVal2D = NoiseHelper.NoiseGenerator2D(new float2(x, z) * (SharedWorldData.ChunkWidth.Data * pos2D));
So basically I am sending in the chunks position in the world, calculated with a simple float value first is 0,0 and counting up by 1 for each x/z
chunk pos for the first is 0,0, the second one spawned will be 0,1
or pos2d?
yeah, pos2D is the chunk world position
and x z is the block pos?
yep
ok cool
inside the chunk
so it should be blockpos + (width * chunck pos)
so that first * should be +
i think
oooh, testing
๐
same with 3D perlin for offset?
yea think so
2d perlin for heights in this kinda map is both the width coordinates, right?
sorry no clue?
hm...I think I need to add this like after the noise has calculated
before the MAD
I get basically the same result right now but just different pattern...wait a minute
nope, setting the world chunk position right whenever I create a new chunk
so adding instead of * didnt work?
well, that's when I got that odd pattern, maybe my other scales and such became off when using it.
a different pattern?
yeah, the image of a flatter terrain I posted earlier
nah, + works okay for one chunk, but it's still the problem with every chunk having the same perlin
so you have this:
(SharedWorldData.ChunkWidth.Data * pos2D)); ^^^
that was the one causing this:
http://prntscr.com/sw968r
oh, oups, no nvm, that was times
๐
it's still the same patterns :p
still got borders
ChunkWidth.Data and pos2D correct?
if they were 0 it would explain that
I'll debug it just to be sure, but I send them in with a for loop, so it shouldn't be any issues.
famous last words
you could replace SharedWorldData.ChunkWidth.Data with a number eg 32 (whatever the size of your chunks are)
so im unsure how the new maths deals with float * float3
so
try this:
var NoiseVal2D = NoiseHelper.NoiseGenerator2D(new float2(x, z) +
(new float2(SharedWorldData.ChunkWidth.Data,SharedWorldData.ChunkWidth.Data) * new float2(pos2D.x,pos2D.z)));
i think the mix of float, float2 and float3 might be confusing it
chunk width is even an int, might be why
yeah, I'm unsure, gonna slam my head through the code some more
did that not work?
nope
what did it do visually?
the world one?
Is there a way I can access a native collection that belongs to System A in a job scheduled in System B?
@viral niche make it public in systemA
and in onupdate of system B get it and store in a local variable, then just use it in the Job.With.. or Entities.Foreach
its a good idea to mark it read only in systemB if it is readonly ๐
use Job.WithReadOnly or Entities.WithReadOnly
and then finally you might need to mark system A as a dependancy
Dependency = JobHandle.Combine(systemB.Dependancy, Dependency)
with a [UpdateAfter.... too
๐
Ah ok, that makes a lot of sense. For some reason the first thing I thought to try was using a reference to the system in the job which obviously didn't work. Thank you!
also like old gameobjects dont do World.GetExistingSystem in onupdate
cache it in OnCreate
in classic unity, i can GetComponent<Interface>().InterfaceFuction(), how do I do that in ecs?
preferable with jobs
Interfaces are reference type, you cant do any interface stuff in a bursted job, or in job in general
how about on mainthread?
is there a way to filter a query on parallel ? maybe giving the query as parameter on schedule ?
i mean i have a query and i have to filter on parallel with a certain sharedcomponent
you can try GetComponentObject<IYourInterface> i am not sure if it will work tho, ofc in order for this to work you have to add a monobehaviour to your entity
i am not sure what do you mean by filter a query, you can do ScheduleParallel() to schedule your job in parallel
you can try GetComponentObject<IYourInterface> i am not sure if it will work tho, ofc in order for this to work you have to add a monobehaviour to your entity
ok will try
thanks๐ฌ
i am not sure what do you mean by filter a query, you can do ScheduleParallel() to schedule your job in parallel
@opaque ledge I have a query that i want to filter with a lot of different sharedComponents , and i want to know if i can filter it on parallel but i dont want to have race conditions cause i want to reset filter each time , this is only one filter apply
probably the best way it is going to be duplicate the query on each iteration and filter the duplicate one
i dont know ๐ฆ
Ecs is made by gods to gods and i am a simple mortal xd
well i didnt do any advanced stuff with filtering, but you could have multiple jobs that has each different filter run in parallel
something like
var job1 = Entites.ForEach().Schedule(Dependency);
var job2 = Entites.ForEach().Schedule(Dependency);
Dependency = JobHandle.CombineDependency(job1, job2);
so that way you wont encounter race condition, Unity will handle it for you
but obviously if each job has the same 'ref' struct then they wont run in parallel
my problem is more about this
struct FaceVertexJob : IJobParallelFor
{
//EntityQuery query;
NativeArray<int> gameobject_id;
public void Execute(int index)
{
query.ResetFilter();
query.AddSharedComponentFilter<BelongGameObjectID>(new BelongGameObjectID { instanceID = gameobject_id[index] });
}
}
i want the filter the query on parallel but without applying the two or more filter on same time
so i think i have to duplicate the query on each iteration
i dont know i am a real noob
i really apreciate your help @opaque ledge
all people here is amazing and breathtaking
Well, you cant use referenced stuff in Jobs, so having EntityQuery in a job wont work
if this is something you only run once, you could think about making it run on main thread
i just realize that the man who sold the world is a nirvana song so i am happy now
I will try other stuffs, thanks man for all your help ๐
okey i just read david bowie made it , interesting
could i have a lock inside entities.foreach ?
When I try to spawn an NPC in play mode, I get the following exception :
InvalidOperationException: The previously scheduled job MyTriggerSystem:TriggerEventsJob reads from the NativeArray TriggerEventsJob.EventReader.m_Bodies. You must call JobHandle.Complete() on the job MyTriggerSystem:TriggerEventsJob, before you can deallocate the NativeArray safely.
Looking at the full stacktrace the exception seems to come from CollisionWorld trying to update the number of bodies it manage, but I'm not sure how I'm supposed to prevent that. Is there a specific moment in Dots where you are allowed to safely spawn new Entities or something ?
Are you using the trigger system as an input dependency?
The issue here is that you don't wait for the job to finish before doing your own job, and that's as simple to fix as to simply use the other system as a dependency.
(Sorry, Discord bugged at bit). I don't think I do ? I just copied someone else's code from the forum and it worked fine until I tried spawning stuff :
{
TriggerEventsJob EventJob = new TriggerEventsJob
{
/*
GetComponentDataFromEntity stuff goes here
*/
};
return EventJob.Schedule(this.StepPhysicsWorld.Simulation, ref this.BuildPhysicsWorld.PhysicsWorld, JobHandle);
}```And I'm using [UpdateBefore(typeof(StepPhysicsWorld))], in case it matter.
how could i make something like this in ECS? the component for spells has a NativeArray<int> next
public IEnumerator Execute(Spell currentSpell, float3 pos)
{
switch (currentSpell)
{
case LoopStartSpell loopStartSpell:
for (var i = 0; i < loopStartSpell.repeats; i++)
{
yield return StartCoroutine(HandleSequencing(currentSpell.sequence,
pos,
float3 => pos = float3));
foreach (var spell1 in loopStartSpell.loop)
yield return StartCoroutine(Execute(spell1, pos));
yield return StartCoroutine(HandleSequencing(loopStartSpell.endSequence,
pos,
float3 => pos = float3));
}
break;
// other stuff
}
foreach (var spell1 in currentSpell.next)
yield return StartCoroutine(Execute(spell1, pos));
}
how can i make recursive things like this in ECS in general?
First, of, think of the data (it's the Data Oriented Tech Stack after all).
Remember that data and logic is separate.
As for how to do that specific thing in ECS, I don't understand what that code does on its own.
it's not important what it does specifically, just the recursion
Why do you need recursion? Are you sure you need it?
And could you use "just code" for the recursive bits, or do they interact with data somehow?
the data just stores the spell
If you want to convert that to DOTS, a good first step is probably to jobify it. Some searching should give you some good resources for that, but in short try to make heavy work into jobs that have clearly defined inputs, and can only output via the DOTS data containers.
From what i can see, whatever you are doing there is something you want to avoid with DOTS, though
i need recursion because in my game spells are made with a node based editor, and have the structure of a tree, which is stepped through by that function to cast a spell
the data itself is stored flattened, each part stores the indexes of the next part
and spells can have delays
So you have a tree-structure, which is best interpreted with recursion, that's fine. Could you feasibly do that recursion and output a non-recursive instruction on how to do whatever must be done?
If you want to make this DOD (bare in mind, not everything has to be), you need to clearly separate out the temporal aspect imo. That's what makes it more painful. As for the recursive part, you'd probably want to create an array of operations or similar.
So "flatten" the recursive into something non-recursive, but explained better
yes, but it needs to be multi-threaded
since youre yielding it will start next sequence next frame so all you'd need is a system for each phase of the spell (sequence, loop, execute, end)
if you didnt intend to yield and if it should be able to schedule a spell, finish, schedule next spell and finish that all in same frame i suppose it gets more tricky
yes, and i want to run things multithreaded as much as possible for my server hosts sake
But yes, this seems like a problem of having a structure and plan which is deeply OOP; you will likely need rather big changes to make it work in DOTS, at least to make it good DOTS code.
yielding is inteded because of delays, so in HandleSequencing it does yield return new WaitForSeconds() if required
dont need recursion then, just treat them as seperate phases
From what you've explained I don't understand your game systems very well, but it sounds like you could possibly use entities for each part of the spell that does something, and have them refer to each other when one leads to another.
For example: node1-has delay component, which says game time to activate. When that is hit, a system checks the other components and triggers effects and/or other nodes.
That would mean a lot of structural changes though, and I'm not sure how such a system would work. (system in the non-ECS meaning
The delay is remarkably easy if you do it that way, as you just need some component which says" activate after this point in time"
yes, the entities for each spell part is what ive had in mind, but i don't know how to trigger the next parts to run
having some in as systemBase where is yield and stuff could work perhaps in DOTS perspective
So - to do this task in a DOD way I believe is simply more verbose. If it's important that it is efficient I would recommend checking this thread out as it's all about this kind of task: https://forum.unity.com/threads/dots-skill-system-repo-available.894007/
yeah that is good repo for when spells are like skills right
thanks
A spell entity could be, for example
-SpellBaseInfo (has delay, if any, other basic info?)
-SpellExplosionStats
-SpellTriggerOtherSpell
You might have systems like
-SpellExplosionSystem - Looks for SpellBaseInfo, SpellExplosionStats, and uses a static helper ShouldSpellActivate(SpellbaseInfo) to see if it should do the explosion thing
-SpellTriggerOtherSpellSystem - Similar, but for triggering other spells
-SpellCleanupSystem - removes spells that have been activated at the end of the frame (or beginning of next?)
Just throwing initial ideas out there. But yeah, look up the skill system. Given how often it's linked, it should be pretty good ๐
On a completely different note, does anyone know:
- How to get the average rotation from a set of
RotationICDs (so quaternions) - How to do a "clamped rotation" with an start rotation, target rotation, and maximum rotation in angles?
Hi all, how u do cascade deleting entities that must be deleted in the same frame? When i saying cascade i mean when one entity depends on another and must be destroyed synchronously. Do DOTS have built in solutions?
except of adding additional component "Destroyed" to run destroying handle systems. i want avoid archetype changes as much as possible
LinkedEntityGroup - instantiate\destory entites as solid group.
you mean save and load ?
kind of, have a bunch of chunks of terrain that needs to dissapear when out of range and so on
oh, you can put "Disabled" component to your entities that is out of range
oh, there's been a new netcode release (0.2): https://docs.unity3d.com/Packages/com.unity.netcode@0.2/changelog/CHANGELOG.html
I mean... is there someone with such crazy levels of insanity that are playing around with dotsnet?
I bet there's already a team out there making a commercial multiplayer game. using dotsnet 0.2
๐
Can I create a project with Unity tiny "normally" now? I've tried starting a Unity Tiny example project but the camera doesn't render (if I open the subscene manually it works, but it doesn't work if it is an entity), and I don't even know how to export to html5..
If there is no simple way to create a project without starting from an example, what are the "essential" files in the example? Which files should I keep and which ones can I delete?
Hey All, anyone done anything with EntityRemapInfo, how am i meant to get the Source Entity from that?
I'm moving entities between worlds and want to bring its name along with it, just in editor
got it
you cant go from remap array back to source
instead get a list of source entitys and map to target
Hey, are we prevented from using a regular List in a shared component?
I can't find anyone else mentioning this, but no matter how I construct the list, or where, neither AddSharedComponentData nor SetSharedComponentData have any effect. Lists remain null.
And I can't see why, considering that we can't work with shared components in threads anyway.
someone in forums had a problem with dictionary as well, maybe someone wrote a solution there
I also had issues with lists
but mine were around builds
i had a shared componet, which had a object and that had a list
build would die and it was due to the list
was super annoying as it worked in editor
In editor, it won't let me instantiate ANYTHING in a shared component containing a list
No matter where I do it, no matter how, everything remains null
have you tried using a managed class component instead of shared component?
share your shared component?
and standard question, Entities version and Unity version?
I just tried that. Same effect
What happens is the system starts trying to compare equality before it's allocated
And it's happening behind the scenes where I have no control over it
Even if everything is allocated when the prefab this is on gets converted
you need to override equals and get hash code
Error messages are worse than useless
I did that
So it says the "other" in the Equals() method is an invalid reference]
Because it tries to do a comparison between two of these, for the first one that exists
Yep
It gets weirder
Suppose I move an AddSharedComponentData() to the exact. same. system. where the prefab has its mesh built -- something proven to work
The method call to AddSharedComponentData() is ignored completely
๐
protected override void OnUpdate()
{
Entities
.WithAll<Progenitor, Quad>()
.WithEntityQueryOptions(EntityQueryOptions.IncludePrefab)
.ForEach((Entity progenitor) =>
{
DefaultQuad(EntityManager, progenitor);
EntityManager.AddSharedComponentData
(
progenitor,
new Progenitor()
{
callers = new List<Entity>(),
names = new List<string>(),
cloneComponents = new List<System.Type>(),
batches = new List<int>(),
progenitorName = "QuadFather"
}
);
EntityManager.AddComponent<DisableRendering>(progenitor);
}).WithStructuralChanges().WithoutBurst().Run();
World.DefaultGameObjectInjectionWorld.GetExistingSystem<SimulationSystemGroup>().RemoveSystemFromUpdateList(this);
}```
The shared component with Progenitor(). Completely ignored. But everything with the mesh is perfect, and it ends up using the exact. same. method.
๐
.WithAll<Progenitor, Quad>()
that code will only run on entities that already have Progenitor
Whoops. I'm tired from trying to make this work elsewhere
in which case you should use set** instead of add
Right.
Why wouldn't it allocate these at all in the following though?
using Unity.Entities;
using System.Collections.Generic;
[RequiresEntityConversion]
public class QuadPrefabAuthoring : MonoBehaviour, IConvertGameObjectToEntity
{
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
Quad quadSprite = new Quad() { reversed = false };
Rotate rotate = new Rotate() { change = false };
Translate translate = new Translate() { change = false };
dstManager.AddComponent<Prefab>(entity);
dstManager.AddComponent<Quad>(entity);
dstManager.AddComponent<Rotate>(entity);
dstManager.AddComponent<Translate>(entity);
dstManager.AddComponent<CloneInfo>(entity);
dstManager.AddSharedComponentData
(
entity,
new Progenitor()
{
callers = new List<Entity>(),
names = new List<string>(),
cloneComponents = new List<System.Type>(),
batches = new List<int>(),
progenitorName = "QuadFather"
}
);
dstManager.AddComponentData<Quad>(entity, quadSprite);
dstManager.AddComponentData<Rotate>(entity, rotate);
dstManager.AddComponentData<Translate>(entity, translate);
dstManager.SetName(entity, "QuadFather");
}
}```
That's where it should really be done
so
Progenitor gets added, but all of its members remain null
Yep
Well, it gets instantiated once the lists in the shared component have content
That instantiation is what this is controlling
That's what is shared.
All the instantiation code works if I move everything in Progenitor into the system that does the spawning, and leave Progenitor as a tag.
But I want to be able to spawn more than one kind of thing, without recreating this for each. Easiest way is to attach that data to spawnable prefabs
I am, but it uses the data in Progenitor to control how many are instantiated and what tags are added to them
Or so I'd like it to anyway
ok so you have some of those prefabs
you instante those
and they spawn other thinsg?
Only one prefab for each kind of geometry
They're instantiated from the prefab, and then another system sets them up in the world
share you Progenitor component
That way, my instantiations are all done in one system
1 sec
using System.Collections.Generic;
using Unity.Entities;
using Unity.Mathematics;
public struct Progenitor : ISharedComponentData, System.IEquatable<Progenitor>
{
public Entity entity;
// The entity placing the order is cached and then tagged with Signal when the order is complete
public List<Entity> callers;
// A unique debugging name to be assigned to clones
public List<string> names;
// A component (not shared component) to be added to the clones
public List<System.Type> cloneComponents;
// The number of clones to instantiate per order
public List<int> batches;
public string progenitorName;
public bool Equals(Progenitor other)
{
return other.GetHashCode(this) == GetHashCode(this);
}
private double GetHashCode(Progenitor progenitor)
{
return entity.GetHashCode();
}
public override int GetHashCode()
{
return unchecked((int)math.floor(GetHashCode(this)));
}
}```
those equals and hashcode methods look weird to me
do you use rider? if so delete them and let them be autogenerated
I use VS for now
Once I make money with this, I can justify getting Rider
For now I just dump all my time off work into it to get there
here
{
return entity.Equals(other.entity) && Equals(callers, other.callers) && Equals(names, other.names) &&
Equals(cloneComponents, other.cloneComponents) && Equals(batches, other.batches) &&
progenitorName == other.progenitorName;
}
public override bool Equals(object obj)
{
return obj is Progenitor other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = entity.GetHashCode();
hashCode = (hashCode * 397) ^ (callers != null ? callers.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (names != null ? names.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (cloneComponents != null ? cloneComponents.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (batches != null ? batches.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (progenitorName != null ? progenitorName.GetHashCode() : 0);
return hashCode;
}
}
rider is AMAZING ๐ highly recommend you get when you can
And that explains why the other shared component didn't have the same problem
was your equals/hashcodes wernt 100% correct, so when you added a new shared component Entities was like... that matches this component, use that instead
so when you made new Progenitor entities would map them all back to the same one
which was maybe a null one, or empty
Here's the line it was failing on (1 sec)
queue.callers.Add(trigger.caller);```
The very first time one of those lists was used.
Somewhere between converting the prefab and accessing that component, behind the scenes it threw away the component
That's before any instantiations and on the first attempt to change data in Progenitor
๐
happy that solved it
now go dig up some $$$ and buy rider ๐
it gets cheaper every year too, best way to do a subscription
Next chance I get, I'll do that. You just demonstrated its value for sure
the circuitsystem duplicates once a frame
using UnityEngine;
using Unity.Jobs;
public class CircuitCalculation : SystemBase
{
private EntityQuery query;
protected override void OnUpdate()
{
EntityManager entityManager = World.EntityManager;
int querySum = 1;
while (querySum != 0)
{
var cBSystem = World.GetOrCreateSystem<EntityCommandBufferSystem>();
var concurrent = cBSystem.CreateCommandBuffer().ToConcurrent();
var _state = GetComponentDataFromEntity<CircuitComponent>(false);
JobHandle jobHandle = Entities.
WithNone<CircuitCompletedTag>().
ForEach((Entity entity, int entityInQueryIndex, ref CircuitComponent circuit, ref DynamicBuffer<CircuitInput> connections) =>
{
var _check = GetComponentDataFromEntity<CircuitCompletedTag>(true);
bool allDependencyDone;```
allDependencyDone = true;
for (int i = 0; i < connections.Length; i++)
{
var connection = connections[i];
if (!_check.Exists(connection.entity))
{
allDependencyDone = false;
break;
}
}
if (allDependencyDone)
{
concurrent.AddComponent(entityInQueryIndex, entity, new CircuitCompletedTag());
}
}).
ScheduleParallel(Dependency);
jobHandle.Complete();
cBSystem.Update();
EntityQueryDesc desc = new EntityQueryDesc { All = new ComponentType[] { typeof(CircuitComponent), typeof(CircuitInput) }, None = new ComponentType[] { typeof(CircuitCompletedTag) } };
query = GetEntityQuery(desc);
querySum = query.CalculateEntityCount();
Debug.Log(querySum);
}
query = GetEntityQuery(ComponentType.ReadOnly<CircuitCompletedTag>());
entityManager.RemoveComponent(query, ComponentType.ReadOnly<CircuitCompletedTag>());
}
}
what could i be doing wrong?
Systems are unique on a per-world basis, so they don't duplicate. But your entities are. I don't see entities being destroyed here, and I don't see them being made. But it appears that you're making new entities when you could change the component data for entities that already exist.
quote line pls?
No line; it's inferred. Entities are being created somewhere, and were they being destroyed at the same or greater rate, then their total number would not increase.
ok
what are the most likely culprit?
is updating cBSystem going to restart the entire script
ok i narrowed down the problem to this code EntityQuery circuitQuery = GetEntityQuery(desc); circuitQuerySum = circuitQuery.CalculateEntityCount();
but i still dont understand why
if i comment out circuitQuerySum = circuitQuery.CalculateEntityCount(); the problem still persist
so the problem is EntityQuery circuitQuery = GetEntityQuery(desc);
