#archived-dots
1 messages Β· Page 217 of 1
what do you mean
converting entity to transform ?
or youre copying doubles from
entity
and setting them in MB transform?
that would still result in floating point precision error i think?
I mean more like the latter yeah. You work with position as doubles, but instead of being global world coords, they are position in your current grid cell. Your client view (Unity scene) matches the grid, thus MB transform is relative to the origin of the scene
Hi, I am very new to DOTS so this may seems really easy π
I have a struct called PushboxData which is a Data Component.
How could I find every pushboxdata from every entities containing one ?
I tried to use GetEntityQuery(typeof(PushboxData)).ToComponentDataArray<PushboxData>()
But PushBoxData need to be a class, but its a struct
Entities
.WithAll<PushboxData>()
.ForEach(() =>
{
// your logic here
}
Good starting point, but that's used to iterate through every PushboxData and execute logic on them. I want to read them
Well I can show you my code
Entities
.WithAll<PushboxData>()
.ForEach((ref PushboxData data) =>
{
// manipulate data here
}
You won't be able to WithAll and use the lambda param at the same time
{
foreach (PushboxData other in otherPusboxes)
{
// Do something
}
}
).Run();```
where otherPushboxes (in the foreach) is actually every PushboxData
You should read this page and the sub-pages too https://docs.unity3d.com/Packages/com.unity.entities@0.17/manual/ecs_creating_systems.html
are you sure? I have classes that work that way
CodeMonkey has a really good DOTS series on youtube, if you're getting started.
Maybe something like that could work ?
Entities.ForEach((PushboxData pushbox) =>
{
pushboxes.Add(pushbox);
}).Run();```
it should work, but im pretty sure theres a direct API call to get all components of type.. can't recall the exact function right now tho
Yeah that what I am looking for
I found GetEntityQuery(typeof(PushboxData)).ToComponentDataArray<PushboxData>()
But has I said, T from ToComponentDataArray need to be a class
Class? It should be a struct extending IComponentData. Class implies managed component data and that should not work with managed data.
Why does it need to be a class?
What is the fastest way to overwrite the entirety of a DynamicBuffer's contents? I'm loading some patches of terrain from a map and creating or replacing existing procgen terrain patches with them:
{
DynamicBuffer<HeightDataBufferElement> buffer = GetOrCreateTerrainPatchBuffer(terrainPatch.Position); //already crazyfast
//todo: unsafe memcpy? buffer magic? this is my 5 second implementation that is tragically slow :D
var r = buffer.Reinterpret<float>().AsNativeArray();
for (int x = 0; x < kvp.Value.Length; x++)
{
r[x] = loadedTerrain.HeightData[x];
}
}```
what is loadedTerrain?
or rather
what is HeightData
Just a data structure returned from the map loader - contains the coordinates of the patch and the height data. HeightData is currently a NativeArray<float>, but I can shove the loaded floats into whatever structure is most efficient π
if you can get them both as slices
not sure if it's any faster..
Β―_(γ)_/Β―
Ooh, I missed those - thanks, I'll try them out! π
No dice, seeing about the same performance on all of them - ~11ms per patch copied. Most maps are broken up into > 1000 patches. π
Only 1024 elements per patch, though, so it's not an outrageous amount of data I'm asking it to copy - but unfortunately there's no obvious way to streamline it further, as the terrain has to be broken up into many separate patches of this size for efficiency in the rest of the game (grid registration, pathfinding, etc etc)
I'm sure there's a bit of unsafe pointer copy magic I've forgotten about that will solve this, but I'm ashamed to admit that it's been far too many years since regularly working with good old fashioned C++ manual memory wizardry
Disregard that, my bottleneck was indeed GetOrCreateTerrainPatchBuffer, caused by some leftover debug code I was Totally Sure Was Turned Offβ’οΈ. I thought to measure just the copy operation. 3ms total for all >1k patches. Hahaha. π
Problem solved, thanks @solid rock π
Nice!
What is NativeSlice for?
Sometimes you want to work with just a part of nativearray, nativeslice is a convenient tool to do this type of thing, it is just a window to another arrayπ€
You need to pass an allocator type as a parameter to the ToComponentData function. It will work then. The error message is confusing.
I found an other way
Don't remember it but I loop through every entities and get their data using a var with myVar[entities]
how would you guys do this sort of thing?
https://i.imgur.com/GPq8fYw.png
right now all of these planet entities (central and surrounding ones) are using same mesh and material so its just 1 chunk i guess
but it doesnt look good at all, its too obvious that its all the same mesh
so the other choice is to give different mesh and mat to each entity but then it will be like 15 chunks
(and i have lot of objects like above in my game so that could result in hundreds of chunks or thousands)
@gusty comet It's probably not too bad to have different chunks. Let's say you have 1000 of these each with a different mesh, that's only 16 MB, as each chunk is 16KB. That's not too much tbh
oh ok
I'm trying to change the material of an entity using the new Entity Component System
In the entity debugger it looks like it is working and changing the materials, but it does not update in the game view
They are all blue/yellow, but in the entity debugger, some of them are linked to a red/black material
Why does this happen?
maybe instead of changing material you can change just colour?
@small cloak What version of Entities and Hybrid Renderer are you on?
It looks like you're using some old API with the ComponentSystem, instead of the newer SystemBase
Also, if the only thing you're changing is the color, consider using a materialoverride instead, it's more efficient
I have a question related to material override, why colours differs when i use it?
I read a few posts online saying it's less efficient, I want to spawn a lot of objects (100,000-250,000), and I only need 4 colors
you can link your component to variable in shader
Okay, but why it does not change the colors in the game view?
@small cloak Then you should definitely use SystemBase instead of ComponentSystem
But why in the entity debugger the materials are different but not in the game view
Why it doesn't change color, I'm not sure tbh
I have this problem with material override in URP, left is regular material, right is material override
@warped trail Are they both converted?
yes
You also have to make sure your color space is correct
I think linear is the only supported one
Or gamma
Either one π
It's linear
Try using MaterialOverrides instead and see if it works
@bright sentinel is there some property to make hybrid renderer use linear color space?
Instead of setting the material in the ForEach, I used entityManager.SetSharedComponentData on the entity
Why?
What's the difference?
entitymanager's methods and componentsystem's foreach are main-thread only
No those are just in the project settings I think, maybe HDRP/URP settings
with systembase and materialoverride you will use multithreaded foreach
@bright sentinel then color space is not the culprit for sureπ
just default urp template project and the only difference between those entities is that one has URPMaterialPropertyColor and other doesn't
this feature works, it easy to use, but i can't understand why colors are not sameπ
I changed it to SystemBased
And this error appeared
Does this mean I cannot use RenderMesh with the burst compiler?
@small cloak RenderMesh is a managed class, so no you cannot
ComponentSystem isn't using burst in the first place
@small cloak You might want to look at the documentation to learn how to use SystemBase
There are only some small changes
So I can't change the color of a mesh using multiple threads?
Well if you use MaterialOverrides like I told you to you can π
How can I do that?
Hah you beat me to it
and don't forget to enable hybrid renderer V2
You have to use the build configurations to build
Can't build through normal builds
I'm getting a bunch of Burst compile errors the first time I run my game - they disappear the second time I run it. They appear to be due to reading static fields from within a Job. Suggestions on how to make them static and readonly to satisfy the Burst compiler while maintaining convenience and readability? They're constants for a fixed point math library:
const long ONE = 1L << FRACTIONAL_PLACES;
public static fp one => new fp(ONE);```
You can try doing a static readonly field
'Constants' like this won't compile with the readonly tag, though, since it uses the initializer - even though it's just setting a long. One of those syntatical edge case gotchas since it's obvious that it's effectively readonly in practice, but not to the compiler. π public static readonly fp one => new fp(ONE);
Hmm is there a reason you need to return versus just assigning one the fp struct?
public static readonly fp one = new fp(ONE);
One way I can think of is to treat the property as a function signature instead π€
public static fp one() => new fp(ONE);
has anyone done a lot of work with understanding the way
Unity.Physics has been updated to work with fixed timestep?
I want to find a write up on the basic strategy they used to make things like gravity, which presumably would previously have just added to velocity each frame, work with a fixed timestep with catchup
same for joints
I'm not sure as I haven't dug into it, but I'd assume they're just running off of a fixed time step
Like not changing functionality, just making sure physics are updated every X seconds
Where X could be like 0.02 seconds or something
Just like PhysX works
huh. yeah maybe im overcomplicating this in my head. I'm trying to work out how things work if you have multiple simulation steps per display step. but if you just do everything in the simulation step, I guess it all just stays consistent
oh yeah I was way overcomplicating it.
Yeah it uses the fixed time step now @tight blade
yeah lol, my situation is actually way less complicated. I dont even use a time delta for what I'm doing, its all on a per frame basis. Similar to gravity. Like when doing gravity, you don't do velocity.y += -9.8 * time.deltaTime, you just do velocity.y += -9.8
I just got myself all confused
There's an exception that whenever it occurs the next time I press Play, all the scripts in the scene will lose their references. ```Unexpected exception Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'Assets, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x00105] in <28cdca1704d2491781795499c297b78b>:0
at Burst.Compiler.IL.AssemblyLoader.Resolve (Mono.Cecil.AssemblyNameReference name) [0x0007c] in <3e87bd30b339441eaceba44e8d9c979f>:0
at Burst.Compiler.IL.AssemblyLoader.Resolve (Burst.Compiler.IL.Helpers.SimpleTypeReferenceString simpleTypeReferenceString) [0x00015] in <3e87bd30b339441eaceba44e8d9c979f>:0
at Burst.Compiler.IL.AssemblyLoader.Resolve (Burst.Compiler.IL.Helpers.SimpleTypeReferenceString simpleTypeReferenceString) [0x00120] in <3e87bd30b339441eaceba44e8d9c979f>:0
at Burst.Compiler.IL.AssemblyLoader.Resolve (Burst.Compiler.IL.Helpers.MethodReferenceString methodReferenceString) [0x0000e] in <3e87bd30b339441eaceba44e8d9c979f>:0
at Burst.Compiler.IL.Jit.JitCompilerService+CompilerThreadContext.Compile (Burst.Compiler.IL.Jit.JitCompilerService+CompileJob job) [0x0031a] in <3e87bd30b339441eaceba44e8d9c979f>:0
It's caused by this While compiling job: Unity.Jobs.IJobExtensions+JobStruct`1[[ItemOwnershipMessageSystem+<>c__DisplayClass_OnUpdate_LambdaJob1, Assets, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(ItemOwnershipMessageSystem+<>c__DisplayClass_OnUpdate_LambdaJob1&, Assets, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at <empty>:line 0
One of these for every job in my codebase
hmm package doc format rework? https://docs.unity3d.com/Packages/com.unity.tiny@0.13/rt/tiny_runtime/classes/_runtimefull_.ut.core2d.transformobjecttoworld.html tried to use /rt/ on the entities docs but didnt work
Currently I am studying Unity ECS
and I have a curiosity that..
'Is it possible to regulate every game logic to 60fps or 30fps but rendering unlimited fps?'
including animation and other things
@opal lynx Yea theres a few ways
You can use the built in Fixed update group for your logic and do some manual code in Update Group to interpolate
Another way is to use 2 custom worlds, One for the logic (simulation) and the other for rendering
thats what I'm doing
Thanks a lot!!
And.. can you tell me a little more in specific, please?
I dont know too much about the first
but the built in Physics system does it
you should be able to find the code for that somewhere
how did you learn the second one way?
π i just did it
theres not like theres tutorials for 90% of DOTS
ill be releasing it one day, its the backbone of my netcode
actually unitys Netcode must do similar too
okay I'll figure it out
I appreciate for you, again
How you connect entities between world?
@frosty siren So i do this in 2 ways
When the player is a 'host' (running the server and is a client) I sync my network messages using ECBs from the other world
I have systems with [DisableAutoCreation] that i manually create and link to the target worlds
(but im looking to build a better subworld/linked world system soon)
All my synced entitys also have a ID, I'm still working on the exact data layout of this and its sizes (currently its just a Int) so thats what i use to 'match' entities in different worlds
Finally i use Unity.Transport and its low level stuff to sync between completely separate client/server
Does id shared?
kinda
Im using subscenes and have a ID creation/assignment as part of a conversion system
still needs work as its not unique if you load many subscenes at once
but otherwise works great
and if you create something (you can only create in server world) it will be given a new ID and the create event will be synced
oh and everything you want to create must have my custom authoring component, which will assign the ID during conversion OR when creating (eg if your instantiating a prefab) by triggering some systems
If player isn't a host (only client) does it have simulation world? Or your sim world is a server logic but itself?
If that happens consistently, make sure you report a bug about it, because that shouldn't happen!
Guys, if i want to construct entity prefab from scratch is it enough to add Prefab component to whole hierarchy?
Should work. If it should have sub objects you will also need a linked entity group so you can instantiate it all at once
lol what
System.IndexOutOfRangeException: Index {0} is out of range in DynamicBuffer of '{1}' Length.
when burst compilation is off this error looks this
IndexOutOfRangeException: Index 75 is out of range in DynamicBuffer of '0' Length.
looks like burst can't string.Format right
I've just enabled HybridRendererV2, downloaded URP and it shows me warnings and errors
I'm creating the entities
And then updating info about them in a loop
It worked before I enabled HybridV2 and installed URP
Now it does not even spawn the sprites
the hybrid docs has info on the api you should use to initialize your rendermesh entities
hey guys, remind me the name of the component that disables rendering of an entity? do I add it or remove it?
how can i use the cinemachineCollider script with an ECS wall?
i dont want to duplicate the wall
from first glance, the "easiest" way imo would be to duplicate the CinemachineCollider script and modify it to use ecs physics @undone delta
@crude sierra add DisableRendering to disable any entity from being rendered
im not that advanced in ecs
yeah, for some reason that didn't work.. ended up removing the RenderMesh component altogether
whats the difference between .schedule and .run?
run is immediate on the mainthread, schedule is a single thread, and scheduleparallel is multithread
ok
Where?
I could not find it
@small cloak
It's been ~1 year since I've checked in on this
but has anyone here experimented with DOTS animation?
I just want to sample an animation and get bone positions at a given frame
i think its the animatedlocaltoroot/world buffer? cant remember exactly, had some tests with rigidbodies going but then shelved them and am waiting for the next release before I start testing again
Time to wait yet another year before anything actually moves
Is there a way to convert game objects into entities in code? I have this monobehavior script called "Arrow" that I'm essentially trying to integrate into a System (ECS). I know how to do it in the editor. Simply have the Arrow impelement IConvertGameObjectToEntity and then drag the ConvertToEntity script onto the entity with the prior Arrow script. Not sure how to do that programmatically though. I.e. A player shoots an arrow and that arrow is spawned as a monobehavior object but then is converted.
Maybe I'll have to rewrite the Arrow class as a component.
Theres a conversion class you can call to convert a given game object
its not really recommended tho
and to actually gain any DOTS performance you still need to rewrite to a IComponet+system
I get it, I'm just falling back to old SWE techniques like "Write wrappers around library code and write your new code in the standard you demand."
also you will generate a ton of garbage by doing it that way, spawing a GO and then converting it is not quick
thats why they want you using subscenes so they can pay that performance cost in editor
Yeah how about I just rewrite the Arrow as some kind of Component and just write the relevant systems that aren't provided in Unity.
or you convert it once at game start and use it as a prefab
Oh that's a thing I saw just now.
yea π
Reusing a prefab so it's instantiated.
the prefab thing is probably a better way
as even if you can create the whole entity via code, to add mesh/materials to it you will have to fall back to the main thread
but if its a prefab entity you can just instanite it
What exactly does prefabbing do in Unity? In other engines, a prefab or instanced entity is usually only in reference to the mesh. It's like a graphics thing.
All the other data associated with it obviously can't be instanced.
the only difference between a prefab entity and a normal entity is the Prefab tag component
any entity with it will be ignored by systems (including renderering)
and when you create it the prefab tag is removed
so you can build the entity up however you like (i recommend sub scenes) attach your components, set meshs/materials/sounds then add the prefab tag and your good to go
I've seen subscenes as well. I still don't understand the poitn of the subscenes.
At least in context of ECS.
basicly its just prepackaged data
so subscenes get converted in editor/build, then saved in a VERY quick format for ECS to load later
Ah, so less delay between the transition of game object to ECS?
Lots of interesting "tricks" to get ECS to play nice with the existing ecosystem.
yea no delay really
Every time I come back to Unity, the ECS approach changes (for the better)
its really great for seperating data from entities
or adding it
eg in my netcode i need to give anything im syncing over the network a unique ID + a 'shadow' entity
Isn't an entity just a opaque ID?
so i can create that shadow entity in the subscene, during conversion. and link them to each other and setup a ton of components depending on whats being synced
yea kinda
One of my early prototypes used entity id/version as its network id
but its almost always more data then actually needed
i could probably get away with 16 bits, maybe 24
maybe even make network ID size dynamic
Man dealing with anything dynamic with the burst compiler is super annoying.
But it's appropriate because the engine needs to know the memory layout to do anything efficiently.
Lots of goodies gets thrown out of the door with Burst. Can't use LINQ for example.
i dont really miss linq with DOTS
I wouldn't miss it either if I could write F# but that's bound to lead to nowhere in Unity.
yea cant see f# happening any time soon
GameObject arrow = Instantiate( arrowPrefab, arrowNockTransform.position, arrowNockTransform.rotation ) as GameObject;
It's already a prefab lol!
no thats a gameobject prefab
look at the ECS samples repo
pretty sure theres a spawner one that shows this in ECS form
Know of a good keyword I can git grep on?
they still called it Instantiate
Oh is the cast what makes it different in my example then?
You say either or, you can replace converttoentity operations directly to subscenes? Sounds like something I really need to read up more.
I was imaginging subscenes as like a primitive namespace.
Ah yes my ignorance, I now see: https://unitycodemonkey.com/video.php?v=91kJtsDLTyE#:~:text=Subscenes use Unity DOTS %2F ECS,you can edit as usual.
I guess you were talking about this https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/ECSSamples/Assets/StressTests/HybridComponent/SpawnerSystem_HybridComponent.cs
Yup, that's why I don't even use the samples these days.
but the core bit is still the same
Or I always ref with the actual documentation and forums to see if it's what I should be doing.
or I bug people like you.
π
How would I narrow this down?
A Hybrid Renderer V2 batch is using a pass from the shader "HDRP/Lit", which is not SRP batcher compatible. Only SRP batcher compatible passes are supported with the Hybrid Renderer.
It gives no further information π¦
i dont think there is a way currently. was wondering if theres a way to just log the shaders name in that error code but then i more or less stopped using shader graph so never got around to checking
Ah lovely, when I try to add a hybrid component I get random NREs.
it's really annoying as f***. it was all working fine until today and I can't figure out what changed
SRP Batcher check is fairly simple to see. Just check your shader inspector when you click on it. https://cdn.discordapp.com/attachments/497874081329184799/830576296349270116/unknown.png
If there's something wrong with it, it'll say so: https://cdn.discordapp.com/attachments/497874081329184799/830576441011601458/unknown.png
I believe for something like material property being declared outside CBuffer, all you need to do is just relocate the declaration (within the shader pass and not the properties list) into the #define cbuffer section or something like that.
I personally dont use Hybrid Renderer (I stand by my opinion that it was a mistake and the reason why all this entities drama is going on, it's the only reason why we're stuck on 2020 LTS) so I dont know the specifics of making it SRP Batch compatible but it's something along those lines. Fairly simple.
The three shader graphs I have all say Disable batching; no
hmm
also SRP Batcher: compatible
id just go through, override every property and make it hybrid per instance
deleting library fixed it
ah cool
So many crashes, isn't LTS meant to be decently stable lol
Wow this new build config thing
kinda nice
how many of the build components actually work?
and also anyone know how to run it via command line/script?
and of course the build dosnt work
Anyone seen this?
(0,0): error Mono.Cecil.ResolutionException: Failed to resolve UnityEngine.RuntimeInitializeLoadType
My build config
If i use static function inside bursted job then will function be bursted or i should add [BurstCompiled] for it?
Looks like they didnt bother to update the stress tests, though the examples themselves are kept up-to-date. Start with the HelloCube samples, all of the folders circled on the screenshot cover many workflows for converting GO to entities, and they have a readme explaining what/how they do it. Digging through all of them is worth it. I find it's the most reliable up-to-date resource for syntax, alongside the official manual
I only tried a few basic ones. Last time I checked LiveLink it kinda worked but seemed capricious. I still need to play with the headless build for servers.
aaaand nothing much otherwise :p
looks like a standard unity build error
not dots related π€
What does the headless build do? Can't we just run the final exe with -headless or something?
Hmm weird if it's just normal unity
which versions of com.unity.platforms and .platforms.windows ?
Umm latest
maybe it does just that xD
I'm away from pc right now
did you click apply after adding that classic build override ? looks like it's not greyed out
Yup
That's probably from me changing the names
Maybe I'll try a normal build and see if it throws the same build error
Are there any additional components we need to install?
I'll probably review those too
maybe log file will be more verbose
Be it packages or overrides I think you have enough
I was thinking like editor components
@karmic basin thanks, I'll try more tomorrow and hopefully have good news
im having a weird issue with DOTS physics
so im applying a linear impulse to my player to make it move
but when you move the player goes in a weird back and forth way
there is no gameplay impact
but it looks funky
(gif is still uploading)
var dt = Time.DeltaTime;
Entities.ForEach((ref PhysicsVelocity velocity, ref Rotation rot, in MoveDirection moveDir, in PhysicsMass mass) =>
{
// get the direction from the component, and times it by the speed and make it framerate independent
var dir = moveDir.Direction * dt * moveDir.Speed;
velocity.ApplyLinearImpulse(mass, dir);
// look in direction
var lookRot = quaternion.LookRotation(dir, Vector3.up);
// if it isn't moving it changes it to NaNF for some reason
if (float.IsNaN(lookRot.value.w)) return;
// transition to new rotation
rot.Value = Quaternion.Slerp(rot.Value, lookRot, dt);
}).Schedule();
generic movement system
this is the player movement system
also the camera is following a mirrored version of the player but that doesnt matter as it happens even if i dont do that
(also using URP if that matters)
still uploading...
ok im just gonna rerecord this
you can see the glitch pretty easilt
@undone delta seems like your physics is running at fixed rate and camera is updating every frame (which is good)
to fix the stuttering you can use interpolation
which is built in to newest unity.physics version, but i'm not sure how you enable it, is there a setting on the authoring gameobject?
or maybe it's a separate authoring component, not sure
Talking about that one ? PhysicsGraphicalSmoothing
thanks
this should be the only line right?
there's a ApplySmoothing prop to set between 0 and 1
And in the character controller they used it with PhysicsGraphicalInterpolationBuffer, which stores prev/current positions IIRC
But maybe Scor was talking about GraphicalβSmoothingβUtility.Interpolate https://docs.unity3d.com/Packages/com.unity.physics@0.6/api/Unity.Physics.GraphicsIntegration.GraphicalSmoothingUtility.html#Unity_Physics_GraphicsIntegration_GraphicalSmoothingUtility_InterpolateUsingVelocity_Unity_Mathematics_RigidTransform__Unity_Physics_PhysicsVelocity__Unity_Physics_PhysicsVelocity__Unity_Physics_PhysicsMass__System_Single_System_Single_
All of these are worth a look to study I guess https://docs.unity3d.com/Packages/com.unity.physics@0.6/api/Unity.Physics.GraphicsIntegration.html
try to add the interpolationbuffer too, maybe it needs it ? I didn't study teh character controller, it's messy :p
Use SetComponentData to add and set at once, not sure it will like to add twice the same component
(To answer to myself, using Add another time is okay)
AddComponentData<T>(Entity, T)
Adds a component to an entity and set the value of that component. Returns true if the component was added, false if the entity already had the component. (The component's data is set either way.)
@undone delta How are you moving your camera?
i think the way you are copying position from entity to gameobject that camera followsπ€
That is correct
My dad is using my PCs monitor so I can't share any code rn and on mobile
Yeah it's hacky but it works well
is there a more performant shader than Unlit I can get somewhere?
(a general one, if I can't write my own shader)
The next step down from Unlit is no shader at all. Unlit is the most basic shader there is.
Well, dont use the default unlit which has a lot of "features". Writing your own unlit shader is as simple as making an empty shader moving it onto a material.
gotcha, thanks
back on pc after forever
wait i did not know this existed lemme see if it works
nope didnt
Is it intentional that systems without any Entities.ForEach, but with EntityQuery are not automatically updated?
it didnt
Systems should automatically update regardless of the existance of EntityQuery or not so long as you do not tag the system as [DisableAutoCreation].
Shouldn't [DisableAutoCreation], you know, only disable their automatic creation?
Yes. That means it will not be automatically included in the update loop. Otherwise, all SystemBase classes or ISystemBase structs OnUpdate will be called automatically.
Well, assuming you're using the default world. Beyond that like NetCode, uh. No clue. I'm still trying to figure that out myself.
I have other systems tagged with [DisableAutoCreation] which contain Entities.ForEach, these are listed as containing queries and being updated
What? That should not be possible. Did you add those systems manually?
Yes, they are being added manually
They are also being updated, which is why I am confused
Oh then yes. DisableAutoCreation does not prevent updating. Use Enabled = false inside the OnUpdate method to stop auto-updates.
But I don't want to prevent updating :)
Basically, here is what is happening:
The system is tagged with [DisableAutoCreation], and contains no Entities.ForEach. It does contain an EntityManager.CreateEntityQuery.
It appears in the list of systems, but says it contains no queries, and is not finding entities (even though a matching entity exists).
If I replace EntityManager.CreateEntityQuery with SystemBase.GetEntityQuery(), the system stop appearing in the list of systems altogether. I can see OnCreate using logging, but not OnDestroy, so I have no idea what is going on.
Hrm, I'll try doing some of my own tests. So what is preventing you from removing the tag?
It has to do with a networking library I use. Basically the system gets auto-created by the networking library once the server / client has started / connected.
Oh, networking. Nevermind then. I have no clue.
(The issue shouldn't have anything to do with networking though)
Make sure the world in which the CreateEntityQuery contains the entity you are trying to look for and not the Default or another world.
EntityQueries cant cross world boundaries.
Heh
Ah, it even shows the targeted chunk if I use [AlwaysUpdate] to stop it from being autodeleted.
So everything works as expected and I am just careless 
Interestingly, it works whether or not I use EntityManager.CreateEntityQuery or SystemBase.GetEntityQuery, but only the latter shows the targeted chunk in the system view
Not sure what the actual difference is, but I think SystemBase.GetEntityQuery should be preferred
Maybe this? Systems cache any queries that your implementation creates and return the cached instance rather than creating a new one when possible.
Huh, I was looking for that implementation. Yea, the entity debugger and the system manager hooks onto SystemBase and everything happening in it. Not EntityManager. Use the GetEntityQuery found inside the SystemBase implementation and not EntityManager's version.
Yeah it makes sense. I usually cache queries in OnCreate anyways but I guess it's not really needed
iirc GetEntityQuery didn't exist in earlier versions
Same here. I guess I can just clear a bunch of OnCreate functions.
\o/
Does Job.WithCode().WithoutBurst().Run() do anything? Since it would only run some code immediately and without burst...
Yes.. it would run code in a very very convoluted way
Having issues with float3, do I need the new? float3 tempForce = new float3 (0f, 0f, 0f);
Inside C#? Definitely. Float3 is just a struct. Inside a shader you dont need to because that's a completely different language.
@jaunty herald There is a minor advantage to using Run..
Calling Run() completes the system Dependency JobHandle before running, blocking the main thread, if necessary, while it waits for those jobs to finish.
it handles the Dependency for you
Or you can just use Dependency.Complete() before running anything on the main thread.
But without entities.foreach Dependancy wouldnt be setup right
I guess it would complete everything then
If you're doing it manually with structs (like a true Scotsman programmer), the SystemBase Dependency wouldn't do anything. So yes, Dependency.Complete() will do nothing without Entities.ForEach
Basically, you just need to set the eventual jobHandler's dependency to Dependency or just merge the dependencies. I dont remember the exact syntax off the top of my head.
On a different topic, if I remember correctly Allocator.Temp does not need to be disposed. However, is it recommended to do so?
I remember reading somewhere that Temp does a caching mechanic with NativeContainers to speed up creation.
but I dont recall if that is enabled if you manually call dispose or not
Ah, right. Here we go: https://www.jacksondunstan.com/articles/5406
JacksonDunstan.com covers game programming
Temp is just really fast until a special temp allocated memory of 16kb is used up. Then it's just TempJob.
So yea, dispose as soon as possible to reduce temp cache usage.
I really wish he continued on DOTS stuff. I mean sure, C++ for C# developers is incredibly useful but I wont be coding with Unreal any day soon.
This is a bit outdated. Today, disposing a temp allocator is just a no-op
I remember I saw a Unity employee say that on the forums
No op?
Oh, hrm
So either way it doesn't hurt to do it, but it's not required either
Yea. Every time there's a leak I just control-f all allocations. Having the disposal even if it doesnt do anything keeps me happy at least.
π
I really feel like I'm abusing C# when I overload identical generic methods with optional parameters. The difference between them all is the generic type extending different interfaces.
The compiler works, but i'm pretty sure the original C# programmers did not intend for it to work that way.
@robust scaffold Who cares. If it works - it works π
i wonder how can i further
optimize my game
i am kinda fixated on it
to the point where i do not care if i waste lot of time on recreating already created thing if its going to be a bit faster
also i have this weird theory that you should always use ScheduleParallel because this way youre using all threads, so even if Schedule was faster for some reason (and it probably shouldnt), you should still go for scheduleparallel because then main thread is doing less work = more space for monobehaviour/single threaded code
can be wrong though
@gusty comet no because scheduling has overhead, moreso for scheduleparallel
you might save a bit of main thread time but if the cost is 10x more total thread time then it's not really worth
so you do .Run?
depends on the case
if it's a small job with little/no dependencies then .Run is faster
what about setting movement and rotation for 500 entities (that may have children)
sure that would prob be .schedule, not sure if it's worth going parallel tho
should profile and see
like if one thread using .schedule can do it in 0.1ms, or with parallel it takes 0.05ms but is x8 threads all taking 0.05ms, then your total time is 0.4ms instead of 0.1ms
isnt parralel == in same time ?
no due to overhead
doesn't mean never use it, just gotta profile and see if it makes sense in your case
i would have to spam way more entities to see any noticeable difference in fps
between schedule and scheduleparralel
don't need to rely on fps, profiling window is your biggest friend
set it to timeline mode and you can see how much time every job worker thread is using
@hollow sorrel is spot on. Some additional factors to consider:
- Cost of ScheduleParallel() goes up with the number of cores - a cpu with more cores can become slower overall
- Schedule runs off main thread but on a single thread. This is often a reasonable compromise - it doesn't block the main thread but also doesn't have the scaling problem of above
- The main problem with Run is creating a sync point. With this stuff, generally you want to avoid sync points where possible
- Currently dependencies between jobs can take much longer than the work the jobs do themselves. Thus it makes a huge difference if you're trying to optimise for 100 entities or 1mil entities.
- In order to think about 'best performance' you not only have to constantly profile but you absolutely can't look at one system in isolation. On the scale of a full game, schedule can be better for this reason.
just to add, .Run doesn't create a sync point in the sense that unity docs call sync points (completing all current jobs)
it does call .Complete on all current jobs that use the same components, so preferably you wanna use it if no dependencies/no other jobs relying on those components
It's as you said and right now, overhead for acquiring data is so slow that Run is in most cases, depending on entity count, faster than Schedule. Scheduling has quite the cost and if your code isn't heavy in computation or entity amount, the actual code will be only a fraction of overall cost.
if the code isnt heavy in computation then how many entities do you need to make ScheduleParallel worth it
it depends(tm) but in my experience, certainly >1000 entities. That said, IJEB improved this situation a bit.
Anybody can explain the second parameter of IJobEntityBatch? It says batchesPerChunk but I don't know what it actually means. 1 means the whole chunk. So what does 2 mean? Does it mean that there would be 2 batches per chunk and they could run in separate threads?
what is IJEB even doing?
Correct - the idea is that for small sized entities you could have thousands of entities in a single chunk. IJobChunk could only process that on a single thread but IJEB could divide that up to multiple.
I see.
What I would have wanted is number of entities. Say I want separate batches for every 2 entities because computation of each could be long. By using batchesPerChunk, it's hard to gauge what number is optimal.
Yea I think it's designed for the more common use-case. In that case there are lots of approaches you can take but they all depend on what your data & transformations actually are.
IJobChunk is still multithreaded just along chunk boundaries. One chunk per thread. IJobEntityBatch can further break down each chunk into multiple threads so its recommended. Problem is, only IJobChunk works with ISystemBase.
Isn't that pretty much exactly what I said? π - but yup, gotta stick with IJCs for the ISBs for now, that's true.
Ah, yea. My excuse for terrible reading comprehension is that I typed that the minute I woke up.
Np βοΈ
i think about adding mechas to the game as a way to escape floating point precision issues
up to 5000meters normal monobehaviour/dots world
but after that you have to wear mecha suit or you die
and mecha suit would be moved purely by dots with doubles
of course that would involve recoding combat, camera, etc
but i guess its integrable way to make gameplay in big worlds possible (even without starting the game in this manner)
I like it. That is a good solution and sounds like super fun gameplay - but note that you're not gaining much in the sense of solving the fundamental requirement of needing to rebase the world's coordinates at arbitrary points. Once you implement this functionality, you can do so whenever needed, not necessarily only at specific points like transitioning in/out of a mech. π
Camera is a good example of that, and likely what you'll run into the most trouble with in order to get smooth transitions between coordinate shifts / coordinate worlds
well you dont need to do this from day one
so thats definitely a plus
i still dont know how to achieve this with dots, i know theres dots physics system with doubles
perhaps could add that to game so it can do the work for you
Depends on the scale involved - doubles weren't large enough for me, so I went with camera-origin rebasing from day one. But if you're sure that it won't limit you later on, I would probably just stick with doubles everywhere from the start for both performance and simplicity, as you won't even need to rebase coordinates of game objects
The old advice of designing everything on paper first is annoyingly true, especially when it comes to difficult architecture decisions like this - measure twice, cut once and all that π
oh i do multiplayer, floating origin wont work
yeah except my game is a mix of monos and dots - as far as i know you cant really use doubles for position with monobehaviours?
thats why i probably cant start with only doubles from day one
Why not? You'd need to handle the conversion of each player's coordinates when interacting with their objects, but there's nothing stopping the design from working π
Not with the built-in Transform system AFAIK, you'll have to roll your own - but that will always be true of pretty much everything once you start going down this wonderful rabbit hole
that alone is a nuissance and then you can only have local origin shifting (differently for each player) but on server the origin cannot move
so you will experience malfunctioning floats on server at least
underlying transform representation: doubles
rendering & physics: doubles->floats with origin shifting.. no?
It doesn't have to - the server should have perfect knowledge of every client's origins, and can maintain coordinate spaces for each of them
That's another good way of handling it, yeah π
Like I said, it's one of those problems where it really helps to plan everything out from the start to make sure the flow of coordinate systems and conversions between them makes sense at every level
DOTS is alive: https://forum.unity.com/threads/dots-editor-0-12-0-preview-release-the-new-way-to-inspect-entities.1045306/#post-7094827
At least the employee is talking about 0.20 release. They might just be skipping 0.18 and 0.19. Or those will be locked to LTS and 0.20 is the reconnection with the Beta/Alpha tech stream.
SUPER happy about this: Multiple Inspectors We now support inspecting Entities in multiple inspector windows. Bringing the option to lock and inspect multiple Entities for debugging just like with GameObjects.
so where's enable disable?
dont think there was any doubt about dots being alive
This gives me hope there might be an update sometime in my lifetime rather than the next.
the time between updates is getting frustratingly long
lol uDamian is giving us more info right now than that dramatic compatibility post
@frosty siren I really appreciate when the devs just post stuff like that, makes it so much easier to understand current development issues. dont understand why we cant have more of that
- Entities Structural Changes - see what happened each frame, like entities created, components added/removed, etc.
- Entities Memory Profiler - see current state of your ECS memory, grouped by Archetypes```
these are major profiling improvements π₯³
@safe lintel hope uDamian have told it to us in a "legal" way and will not suffer. Because all this silent with DOTS are a bit creepy π€
where is this uDamian information you guys speak of?
ty
I swear, I read somewhere that there is best practice related to when to use GetEnumerator for Native Containers but I have no clue where.
It was something along the lines of Use GetEnumerator at the creation of the native container and not at job struct settings.
But I cant find it anymore
Suggestions for the cleanest way of waiting on an EntityCommandBuffer to playback before continuing scheduling job?
I have a scheduling system that creates an Entity for each long-running task, and tags it with the specific work that needs to be done. All of these items of work depend upon the results of the prior one being completed. E.g:
struct ExpensiveParallelTaskTwo : IComponentData {}
...
Entity workOrder = EntityManager.CreateEntity();
EntityManager.AddComponent<ExpensiveParallelTaskOne>();
EntityManager.AddComponent<ExpensiveParallelTaskTwo>();
...
Entities.ForEach((in ExpensiveParallelTaskOne foo) =>
{
//do work, write some output to an EntityCommandBuffer
ecb.RemoveComponent<ExpensiveParallelTaskOne>(); //and ensure that the job is cleared; syntax omitted for brevity
}.ScheduleParallel();
...
Entities.WithNone<ExpensiveParallelTaskOne>.ForEach((in ExpensiveParallelTaskTwo bar) =>
{
//we know that the first task is complete, but how do we make sure that the commandbuffer has been run too?
}.ScheduleParallel();```
The ideal solution is to not use ECBs or any structural changes at all. Do you have to use something that creates or destroys entities?
Yup, this is for generating and processing chunks of terrain data in fairly complex chains. Mix of procgen + handcrafted chunks and other special sauce that requires multiple passes in order to function.
For example, one task has to write out global flags out to a NativeMultiHashMap, which another task will read from and use to guide its processing
Hrm, what Im trying to say is that do you need the ExpensiveParallelTask tags? You can instead force a dependency between the two tasks to force the first pass to complete before the second.
Just make an empty tag and include it in the delegate variable list as "in" with both ForEach functions.
It wont do anything other than fill a space in the variable list but it will create a dependency chain between the two ForEach lambdas. The first will have to complete before the second.
Hmm, I'm not sure I understand - isn't that what I'm already doing by filtering with the existing empty tags? Further, I'm already enforcing order via tagging the Systems that each of those lambdas are running in, e.g.
public class ExpensiveParallelTaskTwoSystem : SystemBase
...```
Actually, it should do that automatically. If you need multiple passes, that implies that the next pass will require information from the first. That dependency is already handled.
Everything should work properly out of the box. No need for tags or ECBs. Just make sure the actual systems are in order with UpdateBefore and UpdateAfter like that.
Yup, I just had that epiphany as well - I think the bug is elsewhere in my implementation, as removing the tags in the ECB, at the final step of its command chain too, would implicitly assure that the ECB has been run before the next job that relies upon its output.
Thank you for being my rubber duck haha π
Is there a way to create temporary NativeCollections inside the Execute method of a job?
Or do I need to assign everything before scheduling?
Use Allocator.Temp
So you can do
void Execute()
{
var list = new NativeList<int>(n, Allocator.Temp);
}
I then get this: InvalidOperationException: The UNKNOWN_OBJECT_TYPE VoronoiMerger.regionEnterPoints has not been assigned or constructed. All containers must be valid when scheduling a job.
Or am I not allowed to have them as a field in the job? They are marked private. Do they need to be completely local to the execute method?
Dont have them as private fields, temp containers are generally treated as local containers
It's a miracle. The build of my project worked first try. Literal magic.
And never mind.
I apparently can not use blob assets obtained from a singleton in a ForEach lambda. Fuck. Time to write out the struct version.
Well, at that point, I have no excuse not to use ISystemBase.
what do you mean ? You can access a ICD that contains a blobassetreference, from a lambda right ?
Yes, if it's stored as a component on the entity. However, that's a int sized component I particularly need across 5000+ entities so I instead store the reference on a singleton that also manages its disposal in a special system.
So when I try to pass in the reference to the Lambda after obtaining the singleton's data, C# itself complains. Well, off to writing my own manual IJobChunks. Fun.
It's not too hard, just an incredible amount of boilerplate.
Wait, fuck. No. Even this doesnt work. Why unity.
Wait, am I stupid?
I am. I didn't read the error message. I need to pass around the reference, not the blob array itself.
I have main Grid Entity which has thousands of child. So if i want to destroy Grid entity i have two ways :
- get DynamicBuffer<Child> and destroy all children
- Before create Child adding it to linked group to parent and no need to care about children later
which way is better?
@slim nebula LinkedEntityGroup it is like logic relationship and DynamicBuffer<Child> it transform relationship. Destroy Parent with only Child buffer without LinekdEntityGroup destroy Only parent, children will survive and will have null in their parent component
Yeah the relationships create/destroy are pretty annoying
i guess the decision would come down to if you need your childs to be components or if bufferdata is okay.
buffer data would be faster, but you lose the ability to do component only things
Hi. is it possible to have different scenes, each one with their own systems? (maybe that's called multiple worlds?)
Yes you can disable auto discovery/update of your systems and add them to a different World
do subscenes share systems?
Subscenes are not relevant for systems. If anything, Unity conversion will put them on your default World. But you can convert yourself and add to whichever World. But I don't really know your use case so i hope I'm not off topic
Sorry should be read: will put gameobjects in the subscenes as entities * in your default World
Thanks for clarification @karmic basin.
Youtubing' about ECS, seems Megacity demos use subscenes with low/hight quality versions to improve performance, not loading neither rendering the whole city.
As i'm doing something similar in scale, i was wondering if that's a correct approach.
However, there's a little difference that bugs me out: subscenes seems to be for "rendering" objects, but I'm concerned about "loading" objects from code(using a system)
what i really need is to split my world into several smaller worlds, each one loading their part only when needed...but instead of gameobjects, like subscenes, a huge bunch of entities created by code
Do any of you have any link/ref/doc...to better help me understand how worlds can be loaded/unloaded and so?
Is there continuous collision detection in havoc physics like there is in monobrhavior
@night venture I dont think you need multiple Worlds (entity ones) or systems then. Split your game World (gameplay area) into subscenes like Megacity yeah. But again I',m not sure I understand well sorry :p
You would need another Entity WOrld if you wanted to apply different systems to each entity group (think physics vs rendering world, or server vs client world)
If you want the same systems to apply to everything, but just splitted in multiple groups, use subscenes
damn that's not a clearer explanation π
Should I dispose Unsafe* members in component when I destroy entity?
generally yes, if you allocate it
so it looks like it's better not to use it in components
not disagreeing with this but physics colliders are unsafe arent they? and they dont appear to have any special cleanup associated with them(like system state components to dispose of them), although I havent really delved into looking for this in the physics code
yeah i always wondered how the physics system does that π€
Another question.
How is NativeStream supposed to work? Are there any simple examples?
[Test]
public void StreamTest()
{
using var stream = new NativeStream(1, Allocator.Temp);
var writer = stream.AsWriter();
// Getting System.ArgumentException :
// NativeStream.Writer must be passed by ref once it is in use
writer.Write(42);
Assert.AreEqual(1, stream);
var reader = stream.AsReader();
Assert.AreEqual(42, reader.Read<int>());
}
Alright. The correct usage in this single thread case would be:
using var stream = new NativeStream(1, Allocator.Temp);
var writer = stream.AsWriter();
writer.BeginForEachIndex(0);
writer.Write(42);
writer.EndForEachIndex();
Assert.AreEqual(1, stream.Count());
var reader = stream.AsReader();
reader.BeginForEachIndex(0);
Assert.AreEqual(42, reader.Read<int>());
reader.EndForEachIndex();
You need to specify "thread index" every time
Day 45ish, still trying to get a standalone to work since I have a finished DOTS/ECS game, but it will only run in the editor. Can someone please help? https://hatebin.com/wbigwfiidj
For one, make sure GameBoardModel.playerEntity and GameBoardModel.entityManager exist and not null. That's 3 variables you must check for null, GameBoardModel object, playerEntity property, and entityManager property. If any three are null, it'll throw that error.
Use the debugging mechanism in your IDE to check during runtime.
i'm having trouble with understanding how systems work - I run some parallel code on my OnStartRunning method and it works fine, however, if I copy paste that code into a public void method and run it from another system, it stops working with some errors regarding Call Complete() before ...
this is what i'm trying to run
m_ecb = World.GetOrCreateSystem<EntityCommandBufferSystem>();
var ecb = m_ecb.CreateCommandBuffer().AsParallelWriter();
Dependency = Entities
.WithBurst()
.WithAll<AttackerComponent>()
.ForEach((int entityInQueryIndex, Entity e) =>
{
ecb.SetComponent(entityInQueryIndex, e, new Translation
{
Value = new float3(450, 0, 450)
});
}).ScheduleParallel(Dependency);
m_ecb.AddJobHandleForProducer(Dependency);
First, you dont need the .WithBurst(), Dependency = and .ScheduleParallel(Dependency). They are all done automatically.
ah okay, was just following some examples from the unity ECS sample project
.SetComponent requires that the component already exist on the entity. Make sure the Entity has a Translation component.
Oh, yea, they do a lot of boilerplate so you understand but those are not needed.
Is that the entire code?
the entitties have translations when I call this yes
nvalidOperationException: The previously scheduled job EnemyPatternSystem:SpawnInPattern_LambdaJob0 reads from the Unity.Entities.EntityTypeHandle SpawnInPattern_LambdaJob0.safety. You must call JobHandle.Complete() on the job EnemyPatternSystem:SpawnInPattern_LambdaJob0, before you can deallocate the Unity.Entities.EntityTypeHandle safely.
Call complete error typically only happens if you have multiple jobs (Entity.ForEach() and Jobs.WithCode()) one after another.
For one, make sure GameBoardModel.playerEntity and GameBoardModel.entityManager exist and not null. I already did
There is literally no difference between standalone and editor that I can see in debug statements.
https://hatebin.com/phpchbshdy Gives the same output on both
Alright, you're deleting an entity somewhere. Where is the code for the EnemyPatternSystem?
that's the one, the code block is all that system does.
KornFlaks, like I said, I already made sure all of those exist and are not null. The values are the same in standalone and editor.
inside a function called SpawnInPattern
This is all terribly frustrating, I have a very large and super ambitious game ready to be published, but I can't compile a standalone.
A game I spent about 3500 hours on...
500 of it being DOTS/ECS
Is that function the only thing being called? Because the error message is for code after that job is created / run. What's the rest of the code>
It crashes there
Because the next Debug.Error log never gets called
https://hatebin.com/wbigwfiidj is literally the last line executed before the crash
I wonder if it has to do with weird package incompatibilities
since I added packages manually and such
Upgraded/downgraded etc etc
https://hatebin.com/kwiandoibq
litteraly the entire system is that code block
Is your code on github? If you spent thousands of hours making this, then there are probably a lot of interconnected systems and interactions occurring here.
Where is SpawnInPattern(SpawnPattern pattern) being run? Nothing is wrong with this section of code itself.
KornFlaks, I can give you the entirety of all the entity stuff if you want, there isn't much, but it'd take me about 10 minutes to format for you. You were asking for code after, and there was nothing executed after. Now you're asking for code before which I can provide. Is this your request?
I call it from another system, after a certain job operation is being completed, you think it's related?
Or perhaps... Would you like me to reduce the project minimalistically to the least amount of code in order to cause the error?
I've stripped projects down for this end before.
Im not good at debugging code that isnt mine. Im sorry but you'll probably need to ask someone else to go through it all with a comb because what it seems like is a race condition in standalone.
I don't believe it is a race condition
I used a dif tool and compared editor/standalone
Yes. I need that other system.
All my debug statements come out at the same time.
Well you know what... Lets try a hacky solution
Lets not even access the physics of the entity for a second
https://hatebin.com/asftnvuluq
line 37 calls SpawnPattern
Ah, I know the problem now. You're misunderstanding the concept of systems. It is not a "class" where you access and call functions with jobs in them.
The problem here is that the Dependency chain used in the EnemyPatternSystem is not the same as the one used in EnemySpawnerSystem, which results in jobs not scheduling correctly.
yes, i thought it might be my understanding of having systems operate in response to something
i was thinking to enable/disable EnemyPatternSystem whenever I want it's code to run
Yes, sorta. Systems operate upon Entities where they get their data from. If you need another system to begin working due to a change in the first system, you create a "flag" / singleton.
You do not manually find the system using World.GetOrCreateSystem and then call the function itself.
Here is what I'll do. Give me a sec to type something out.
so I should query a singleton value in OnUpdate?
Also, it's not [BurstCompatible], it's [BurstCompile].
Nope it can't be a race condition, waited 2 seconds
You first create an empty tag component. This is just a struct that extends IComponentData that has nothing in it like this:
public struct EnemyPatternSystemEnabler : IComponentData {}
Is there a way to print out an entity's name in Debug.Log? Right now all I get is: printing EntityManager: Unity.Entities.EntityManager
printing Entity: Entity(2:1)
Debug.Log(Entity.Name), so long as the entity has a name set.
Then in EnemyPatternSystem's OnCreate() function, you would add: RequireSingletonForUpdate<EnemyPatternSystemEnabler>().
entity doesnt have a name
Entity does not contain a definition for 'Name'
Is there some other data I could be viewing?
you can use EntityManager to query an entity name but it wont work unless you are in the editor
It doesn't matter the name, just something better than 2:1
I need something to compare a standalone to editor
Create a component that has a fixedstring32 property. Use that as a name.
if you need to debug a specific entity, id suggest you make a single tag, give that tag a name and query for the tags existence
The RequireSingletonForUpdate<>() will make the system only update if that singleton entity exist. Or at least a single entity with that component exists anywhere in that world.
What is the syntax to query a tags existence from an enity? I know how to set a tag.
Then in EnemyPatternSystem's OnUpdate(), do that section of code setting Translation.
so playerEntity.getComponent<tag>() ?
and lastly, need to add that component to somewhere when i want to execute that code?
and then to remove it in the following frame?
Yes, in the original system where you used GetOrCreateSystem, you will instead use the EntityManager to create an entity with a component EnemyPatternSystemEnabler.
EntityManager.CreateEntity(typeof(EnemyPatternSystemEnabler));
In the EnemyPatternSystem, you want to use the EntityManager to delete that entity to prevent it from continually running every frame:
var singleton = GetSingletonEntity<EnemyPatternSystemEnabler>();
EntityManager.DestroyEntity(singleton);
GameBoardModel.entityManager.GetComponentData<????>(GameBoardModel.playerEntity)); What is the ???? to get the tag data
nice, thanks for the explanation - shame it's not in the docs (or at least i couldnt find it)
one more thing - would it be better to just enable and disable a system at a time of need and have the one-time code run in OnStartRunning()?
You can... technically do that. But it's not intended in an ECS architecture. Systems are not supposed to be referenced and then have their internals modified externally. That creates spaghetti code. Systems are suppose to be as isolated as possible and using Singletons (Single entities) and Entities to communicate between them.
Isolation promotes code modularity. Which makes refactoring and debugging a lot easier.
you have to be careful with OnStartRunning(), it can be run more than once in a frame, you can end up with non desirable results with that
I see, gonna go with singletons then. thanks for your time and elaborate information!
True. I've had some really strange experiences with OnStartRunning that I just gave up on debugging and made everything work with OnCreate.
yeah same
No problem. Good luck. I learned this all trial and error over the past few years so it's not "official" unity DOTS intended design. Although, I'm pretty sure no one knows what unity's intended design is.
really? I had the opposite experience
regarding OnCreate
I assume it's also good practice to have data stored in the Singleton rather than iterate over entities to get them (if it's not volatile)?
This was back before an official implementation of FixedStepSimulationGroup. I was trying to make my own fixed step (because unity was lazy and didnt ship it with Entities back then) and OnStartRunning was running multiple times, running once, and not running at all. Couldn't make any sense of it.
OnCreate at least runs once since I dont touch GetOrCreateSystem with a ten foot pole.
Depends on the data. Generally, you want everything distributed between various entities simply because it's a lot easier to use and access with the Entities.ForEach lambdas.
However, if it's something massive like mesh data and largely not unique per entity, you'll use a BlobAsset in a singleton.
right, seeing how cheap Entities.ForEach is I guess it makes sense
hopefully I won't get to that kind of complications.. for now my meshes are similar and therefore accessed via SharedComponents
Yep. Typically singletons are for universal one off data. Something that you dont need to waste memory copying across all the entities.
interestingly enough, using the EntityManager.CreateEntity(typeof(EnemyPatternSystemEnabler)); doesn't add any enttiies to the EntityDebugger - is this intentional?
Are you sure? It should.
yeah, even tried replacing with
var e = EntityManager.CreateEntity();
EntityManager.AddComponent<EnemyPatternSystemEnabler>(e);
it's just instead of the line that used to call the other system, line 37 in EnemySpawnerSystem
Make sure you've cleared all the chunk filters.
Both All Entities in the systems list and the All Entities button above filter.
I found the culprit, my function that overrides convertanddestroy as instructed to be used by a few Youtubers. Basically I'm just trying to get a reference to an Entity that is in the scene. On the editor I get the reference. On the Standalone I do not get the reference: https://www.crystalfighter.com/code/racecconditionconverttoentity.txt
As I mentioned, race condition.
On the editor, it prints 123 for rotationAccelerationx
On the standalone, it prints 0
it's not something with the debugger as well - seeing as the OnUpdate on the now requiring singleton PatternSystem doesn't invoke Update
Yes, but I have no clue how to solve this. I thought it was due to convert and destroy, but I did convert and stay and it still won't get the 123
Put a Debug.Log("TEST"); before the EntityManager.CreateEntity. Make sure it's actually being run.
yes, done that, it's being run
Do you have the EntityManager.DestroyEntity also being used? That will destroy the entity the same frame as the creation and will not show up on the debugger.
i moved the CreateEntity to the start of the OnStartRunning and it worked. very weird
but I don't want it there
also, I removed the DestroyEntity from the last line of the OnUpdate from EnemyPatternSystem and it also worked. very weird
Man, this whole time I was stuck for a month and a half is because Unity couldn't figure out how to add indices to their scene elements in order to get an easy reference to an entity directly in code?
Right, make sure you have these three components: RequireSingletonForUpdate<>() in the OnCreate of the second system, EntityManager.CreateEntity() at the bottom of that OnStartRunning() of the first, and EntityManager.DestroyEntity() at the start of the second system.
So I guess the question is... Say I have a gameObject in scene that gets converted to an Entity. How do I store a reference to that Entity in a MonoBehavior Singleton?
This should be super super super super easy.
Like setting x=1;
Doesnt really exist. You'll need to create a unique tag struct or a component struct that sets a unique index for that gameobject to entity. Search using GetSingleton() if you use unique tag struct or Entities.ForEach and search for the unique index in a series of components, then output the resulting entity.
when you say EntityManager.DestroyEntity() at the start of the second system. you mean the first line of OnUpdate yes?
it appears that indeed the entity somehow gets destroyed before it manages to trigger the system, which is weird because the thing itself that deletes that is the system
Yes, the first line. Just because the entity does not exist does not mean the entire OnUpdate is canceled. That's not possible. If the EntityManager.DestroyEntity is run, the whole update is run.
added debug logs, made sure it was run once. but the parallel jobs did not complete ( the targets didnt move to their location)
could it be the destruction of the entity terminates jobs in progress?
Yes. Structural changes like CreateEntity and DestroyEntity result in all dependency completions. Try CompleteDependency() after the parallel job? If that doesnt work, try .WithoutBurst() of the parallel job then add Debug.Log() to check if the Entities.ForEach() is actually running.
Wait, Korn, how does it not exist?
Now, this is something that should not even be remotely difficult to do. THIS SHOULD BE SUPER SUPER SUPER SIMPLE, but it's not! UNITY DEVS should merely assign every scene object a unique index. Then in your code, on your monobehavior public ENITY variables, you should be able to just drag and drop the game object to be converted into the variable slot just like traditional unity. During the conversion, it matches the index of the gameObject to slot it in the proper entity variable. This should be super easy to understand, super easy for UNITY DEVS to code, but what we have now is a failure to communicate.
DOTS inspector support is barren at best, non-existent in reality. There is no drag and drop. You will have to code out finding the reference to GO -> Entity in a system after initialization.
I know. I'm just posting in case a dev sees.
Cuz the solution is brain dead simple.
So my question is
Exactly what code gets the reference?
Like where in my code can I find that reference, anywhere?
Maybe I search the
Ohyeah
I can search the EntityManager
And set one variable
I might be good to go.
Thanks KornFlaks bro
the best thing is to add a tag to the converted entity
weird
GameBoardModel.entityManager.GetComponentData<???????>().rotationAccelerationx
Okay, done that, the entities.foreach has no iterations to it for some reason
Use [GenerateAuthoringComponent] then set a unique random string or index for that game object. In a regular system, use a Entities.ForEach() to search for that unique string / index.
yah yeah yeah Korn, thats what I was saying
I know where to go now. I just had some code from Youtube that worked, but doesn't now in standalone, but works in editor.
freaky stuff
Ah, make sure the entities all have a AttackerComponent. Also, it's better to have a Translation component originally on the entity and not set it via ECB in a job. That's wildly inefficient.
you do something like Entitties.Withall<...TagComponent> or WithAny
Almost as bad as when I got my first pentium and my MMO I was making no longer worked...
TY Calabi, good to broaden my horizons, never had the need to use tags before.
Good to learn new stuff
no prob, tags don't contain any data on there own so you have to get other data with them
Until I realized the computer was wrong because of Pentium floating point division rounding errors
the parallel job in the other system instantiates prefabs that already have AttackerComponent with them. for some reason there's a race condition here even though I call Complete() on the job that instantiates those entities
Ideally, you never need to touch ECBs in general. My experience with them (admittedly a year ago) told me to avoid using them at all. ECBs are so sensitive to specific ways of coding and have the most illusive bugs. Personally, I would scrap all the ECBs then use EntityManager in a regular C# foreach loop and set them that way.
nevermind, there's no race condition here
something else is up
I have an initialization function that just creates entities with all possible components already attached. No adding or removing components during runtime.
using hybrid ECS here, got a prefab attached to the component it's iterating over
could something internally be delaying adding the components?
Ah. Also, if you're using SetComponent, why not just set the component directly using:
Entities
.WithAll<AttackerComponent>()
.ForEach((ref Translation translation) =>
{
translation = new Translation(100, 100, 100); // Or whatever debug position.
}.ScheduleParallel();```
yes, will change that
added more logs, and to my surprise, the first frame (the triggered one) does not have any iterations to it
BUT the second frame already detects entities with AttackerComponent
there's a one frame delay for some reason
I could do a coroutine that skips a frame, i guess
or set a flag that gets consumes in the following update invocation
is that right when the program starts?
yeah I've had similar weird behaviour when trying to run things immediately
unless theres a super efficient way to check if an entity with a non singleton component exists in the world? will GetSingletonEntity do?
I've got around it by running things a few frames later or just having buttons start things
with a non singleton entity wouldn't you use an EntityQuery otherwise it would just not work or come up with an error
can't find any references regarding using entityqueries in that manner
I'm not sure what you mean exactly, by "non singleton component" do you mean more than one exists?
yes
yeah then you would use an EntityQuery or Entities.Foreach
GetSingleton() will throw an error if more than one entity exists that has that singleton component.
basically I need to check if any entity in the world has that component, looking for a slim solution rather than using ECB again hehe
GetEntityQuery().IsEmpty. Returns true if that no entities exist with that set of components. Returns false if there is at least one.
yes, i've read that. entity queries are basically a nicer way of doing
Entities.ForEach with parameters
oh nice that could do
there's also CalculateEntityCount(), I think its called that
however, thinking into the future that might cause me bugs
so i have to skip that frame anyways
HybridRenderer is such a mess. Thats why I just ignore converting game objects to entities and manually communicate transform changes between GOs and DOTS.
yeah but the inspector needs to play a part otherwise things are too hard to change
how do you go about doing that exactly @robust scaffold π€
Hardcode your way to victory. My IDE is my inspector. What can possibly go wrong.
I've thought about trying that
Make a component with a float3 property called Position. Use IParallelForTransforms and set the transform position value using an array.
btw, do I also need to write my own delay systems? I see theres no support for coroutines in the main thread loop of systems
That kinda works. Right now, my DOTS is purely simulation. No moving game objects, just displaying numbers on the UI so I dont worry about that.
interesting thanks
You cant really delay. I guess you can skip one frame using this:
public class System : SystemBase
{
private int Counter;
public override void OnCreate()
{
RequireSingletonForUpdate<SystemEnabler>();
}
public override void OnUpdate()
{
if (Counter++ == 0)
return;
Counter = 0;
EntityManager.DestroyEntity(GetSingletonEntity<SystemEnabler>());
}
}```
There, skips one frame.
ehhh, yea
Real sad I typed that system out by memory. I really need to stop doing DOTS so much.
Soon, you'll get to the point where you can grab a sheet of paper and write out functional SystemBase classes. Maybe my CS professors were right. We do write code on paper.
every day we stray further from the goal of becoming game designers.
@karmic basin buddy?
sorry that's my cat
lmao
deleting all that
Protip: Shift displays the delete button on the message
I wish I didnt miss that π
Wondering if someone could help me out
In building a simple cube in ECS and Hybrid Renderer 2 for oculus quest 2
Everything is working in editor but the entities are not rendering on my quest
Any ideas ?
In building with Android-build build configuration
Using the platforms package? Check your player log in the AppData folder.
@robust scaffold can you run me thought that
Iβm running com.platform.unity.android
That seems correct. I'm on my bed so I cant really screenshot the process. Make sure you're using the build asset, not the traditional build button in the top left.
The build asset will have you building the project via inspector window, not a popup.
If you are doing that, check the logs. Google Unity Player Log Location to find the path. I cant recall it from the top of my head. Read it, see where the error is.
Debug it and fix it. Welcome to build debugging, where pain not optional but mandatory. Consider also regularly building your project to prevent the debugging process from being too painful.
Iβm running it on the quest 2 , simple ECS cube
I can see console now
Failed to load native plugins: Un
hello
seems copying MB position to entity position (rotation too) every frame is not very effective?
entities move smoothly
object with copied pos is shaking
its hard to explain
the shaking is only visible if you are child of that object, eg if you parent camera to it
If i use static function in bursted job will function be bursted too, or should i add [BurstCompile] attr?
it will be bursted too, only the entry point needs the attr
text file contains lines "type1", "type2"...is reflection the only (proper) way to attach "type1" component to entities according to file ?
You're not supposed to do so. The GO/Entity workflow at runtime is intended to be single-way from Entity to companion GO (at authoring time it's the opposite).
But I think it's still achievable what you're trying to do. You probably can hack your way if you manage to update after of before the ECS Transforms systems
But I never tried π€·ββοΈ
or maybe it's only a camera update order thing based on what you say here
ah it was unrelated to dots honestly
position updating will always break at higher speeds unless u use rb and interpolation
yeah you def need to smooth, interpolate or extrapolate or whatever :p
unless you have a big enough framerate
no way even at 60 fps it will break
if the speed is too high
without rb
but yeah then i added RB and in return ive got some parrenting problems where before there were none
gotcha, you'll need a huge framerate for it to work. As a side note, using transform pos + rb forces is even worse, the two would compete.
the rb is kinematic ?
sorry I'm just asking questions out of curiosity π
Every morning, I wake up and check the DOTS forum for updates and a changelog for 0.18. Every morning I am disappointed.
@robust scaffold I check the compatibility forum post every hour
i dont
Any ideas how to make it simpler using Unity.Mathematics functions? E.g. to avoid ifs
var buttonPos = float2(...);
var pos = float3(0);
if (r.Normal.x != 0) pos.yz = buttonPos;
else if (r.Normal.y != 0) pos.xz = buttonPos;
else if (r.Normal.z != 0) pos.xy = buttonPos;
You can use a switch statement. I cant think of an algebraic function that would do something like that.
I'm afraid a switch would be even more cumbersome.
You can use two for loops but that's even more code
text file contains key="type1", key="type2"...is reflection the only (proper) way to attach "type1" icomponent to entities according to file ?
Reflection? If it's a text file with strings, just use a switch statement matching the string.
tying to avoid that...hence the reflection
i don't know how that text->switch->class is called, but probably "dead cat"
I dont see how you can use reflection. That typically implies trying to access the internals of an externally provided class within the code. Like how I use reflection to access the int RGBA value of Color32 because Unity is evil and doesnt make that public. If you're trying to deserialize a text file into entities, that's not reflection. That's just a bunch of switch statements.
switch(keyText)
{
case "type1":
EntityManager.AddComponent(entity, typeof(Type1));
break;
}```
sure, sure...but that was I was trying to avoid
do you guys recommend HybridRendererV2 or is it too much headache? using V1 atm but want lit shaders..
ill recommend unity LTS...so v1
I dont think there's any other possible way to do this, unless you want to rip open the EntityManager and access the internals using reflection just to make serializing into one line rather than a switch statement. At that point, I would clone the Entities package and manually make all the components public.
which means I have to write my own lit shaders if I want them, right?
did someone say switch? xD
I dont recommend HybridRenderer at all. If you must use it, V2 is the way to go. V1 is no longer being developed and straight up can not do lit shaders. It can not access the Unity lighting engine. So if you want to write your own lighting engine, go for V1.
for that, ill go v2, but at this moment, unity editor is somehow "between" worlds...
wdym not use it at all? isnt it a must part of DOTS?
when I installed entities package, it came with it automatically
Yesssss, it technically is. But you can use Entities without HybridRenderer. You can not use HybridRenderer without Entities.
There are 3 levels of DOTS.
The base structure: Burst and Job System.
The implementation: Entities (the package) and Mathematics.
The abstraction: Hybrid Renderer and DOTS Netcode.
Abstraction is a buggy, inefficient, and horrible mess. I just stop at the implementation and do the abstraction myself.
what does "doing the abstraction yourself" include?
That is my package list. Notice the lack of Hybrid Renderer and an override of Burst package (to get the latest goodies).
Depends, adding the component can be done without reflection/modifying the source code. But if you want to give the component a value you have to expose the method for setting a component by it's typeindex or write a reflection extension for it.
Since I dont use that many visual entities (entities that need to be rendered), I instead just use IJobParallelForTransform to communicate any translation (positional and rotational) changes via a single job. Notice how HybridRenderer requires 5 to 8 ms of overhead not even rendering anything. With IJobParallelForTransform and regular old GameObjects, my game is already significantly faster rendering just a cube. And I have all the HDRP features without worry of HybridRenderer compatibility.
The netcode, ehhh, I dont use netcode so I can miss out. Also, there is a third abstraction: DOTS Physics. I also dont use entity physics or anything that needs collisions so I just use regular Physics for my raycasts.
what would you recommend if my game needs both lit shaders and 10-20k moving entities?
10,000 moving entities? Yea, hybrid renderer V2. Use IJobParallelForTransform if you're using a few to a dozen entities.
okay.. gonna have to struggle with the mess. just enabled it and already getting swamped with errors
Yea, you might want to start a new project with HybridRendererV2 enabled from the start. Then selectively transfer over script files and materials to make sure everything works.
thats crazy. really?
Eh, unless you want to start digging through the error log. Something major like enabling V2 is going to be an absolute pain to debug and fix starting from the top.
atm im only interested in setting compA when (key=)value is "compA". using a switch seems a crappy idea, but also the most straightforward to achieve that.
That's for a class but I doubt it'll be much different from a struct. That for a pre-existing class defined in the code. If you're trying to make a struct from a string using c#, consider instead researching into compilers.
interesting...
A warning though. It may have some unexplained or unexpected behavior between the Editor and Build. Reflection is very sensitive to the environment it is being used in and who knows what may be changed behind the scenes during the build process. If you need to use Reflection, build and test constantly to ensure that everything is working properly.
And you can not use IL2CPP with reflection. If I remember correctly, the compiler will strip the "unused" classes/structs even if it's referenced in the reflection code. Well, you can manually include them using assembly (not the language, the unity asset) tricks.
I don't understand the implications of this statement
Right, if you have no clue what I'm talking about, use the switch statement.
xd
ArgumentOutOfRangeException: sub array range 0-715 is outside the range of the native array 0-714
Parameter name: length
Unity.Collections.NativeArray`1[T].CheckGetSubArrayArguments (System.Int32 start, System.Int32 length) (at <10564ed154d647e194bef4aef8878649>:0)
Unity.Collections.NativeArray`1[T].GetSubArray (System.Int32 start, System.Int32 length) (at <10564ed154d647e194bef4aef8878649>:0)
Unity.Rendering.HybridRendererSystem.UpdateAllBatches (Unity.Jobs.JobHandle inputDependencies) (at
What are you doing, step hybridrenderer?!
RIP, something internal broke.
what a mess
has nothing to do with my own code at all, just attaching a mesh renderer to an object fucks everything
Isn't it easier to multiply with the normal ?
You can't multiply a float3 by a float2.
Do you mean the * operation? like float3(buttonPos, 1) * r.Normal?
It doesn't seem to be the correct result
The code requires that the float2 buttonPos be placed in the two values of a float3 that is not masked by the value of r.Normal prioritized by XYZ order.
was thinking of math.mul() but yeah there's a f3 on one side and a f2 on the other hehe
I can not think of a series of operations that can result in that outcome, let alone the final XYZ priority order.
basically, the point is to "convert" coords of the rect from 2d to 3d so that its surface will be perpendicular to normal
Nah, the first hurdle is somehow masking the float3 and filling two values with a float2. var mask = -(1-r.Normal) requiring that math.Length2(r.Normal) == 1. Then converting the float2 to float3 somehow, then you can multiply var outcome = mask * float3ButtonPos
Without using an if statement. I think it's impossible.
rotations stuff melt my brain. gonna go eat see ya
It ain't rotations. It's just basic linear algebra. You get real used to this exotic stuff when you try inlining everything in shaders.
So I have a SystemGroup that I need to update after (not in) SimulationSystemGroup, but [UpdateAfter] doesn't really work since Unity will complain that it's not in the same group. [UpdateInGroup(typeof(Update))] doesn't work either since it'll error, saying Update's not derived from ComponentSystem. What's the syntax for putting a system in the root of Update?
Have you tried [UpdateInGroup(typeof(LateSimulationSystemGroup))]? Check the EntityDebugger for the full list of systems and system groups you can use.
DOTS is decoupled from the traditional Mono/GameObject update loop, so you cant use Update.
That's not what I need
There is PresentationSystemGroup, for after rendering.
I need my systems to run after EndSimulationEntityCommandBufferSystem
I need it to run before rendering too
Three options, use PresentationSystemGroup, [UpdateAfter(typeof(EndSimulationEntityCommandBufferSystem))] although I'm pretty sure that will throw an error, or make your own systemgroup and add it to the list.
[UpdateAfter(typeof(EndSimulationEntityCommandBufferSystem))] does nothing, not even give an error. Making my own SystemGroup is exactly what I'm trying to do
Ah, you'll need to modify ICustomBootstrap somehow. I dont have much experience with it though so google is your best friend.
But I don't know how to order it between SimulationSystemGroup and PresentationSystemGroup since the normal syntax doesn't work
Normal syntax for [UpdateInGroup] and such are for already existing system groups. ICustomBootstrap is where you order the system groups. You will need to manually override this command: DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
This seem to work if consider that normal is axis-aligned
var temp = float3(0, button.Pos);
var n = abs(r.Normal);
var pos = n.x * temp.xyz;
pos += n.y * temp.yxz;
pos += n.z * temp.yzx;
Look inside this file: DefaultWorldInitialization.cs. Surprisingly, it doesnt look that complex.
private static void AddSystemToRootLevelSystemGroupsInternal(World world, IEnumerable<Type> systemTypesOrig, int managedTypesCountOrig)
{
var initializationSystemGroup = world.GetOrCreateSystem<InitializationSystemGroup>();
var simulationSystemGroup = world.GetOrCreateSystem<SimulationSystemGroup>();
var presentationSystemGroup = world.GetOrCreateSystem<PresentationSystemGroup>();
var managedTypes = new List<Type>();
var unmanagedTypes = new List<Type>();
foreach (var stype in systemTypesOrig)
{
if (typeof(ComponentSystemBase).IsAssignableFrom(stype))
managedTypes.Add(stype);
else if (typeof(ISystemBase).IsAssignableFrom(stype))
unmanagedTypes.Add(stype);
else
throw new InvalidOperationException("Bad type");
}
var systems = world.GetOrCreateSystemsAndLogException(managedTypes, managedTypes.Count);```
There ya go, that works. I bow to your shader abilities as it is beyond mine. I did not consider reordering the values. Although, it might be simplified with a multiplication.
how?
var temp = float3(0, button.Pos);
var n = abs(r.Normal);
var options = new float3x3(temp.xyz, temp.yxz, temp.yzx);
pos = math.mul(n, options);```
So the solution would be to implement ICustomBootstrap and copy-paste the default world generation? That seems like pretty bad design
hmm, it looks like you'd need to pass components in different order to the matrix. Just tested it and got a mess. Good idea, anyway, ty
Welcome to DOTS. It is your first time here?
Hrm, I may be misunderstanding how matrix multiplication works.
Try pos = math.mul(options, n);. The order may be wrong.
Yes, it works!
So the final solution is beautiful
var temp = float3(0, button.Pos);
var options = float3x3(temp.xyz, temp.yxz, temp.yzx);
var pos = mul(options, abs(r.Normal));
I'm having issues (low FPS) loading a quite large amount of entities (100k) and after trying a few approaches none of them seems to fit my needs.
So far, I have a nativehashmap<position,entity>. do you know if there's a efficient/fast way to get entities within a radius without needing to iterate through them?
Setting a Colliders/physics could work, but I dont know if putting so many entities would cause issues...
@raven grail @robust scaffold You shouldnt have to override ICustomBootstrap to add system groups. They are just convenience systems with a name and preferably an empty update
I feel that 100k is a lot. Did you try some spatial partitioning algorithm ?
in fact is what im trying to do
ie: draw only closer
i could iterate throught the map and check math.distance
or use sphere collider
...or... ?
-cough cough-
what do you mean by 'loading' them?
putting into world, creating entities, instantiating meshes...
you need to do everything in bulk, like preallocate array of entities and instantiate them all at once etc, its hard to say whats wrong without seeing your code
imho nothing is wrong, just putting tooo many entities on scene(100k)
so i probably need something like LOD
and ask for ideas:
iterating+math.distance
sphere collider
...
iterating what ? 100k items ? too heavy
collider okay, but this means you already have 100k entities in your scene in order to imply the physics system π€
iterating would be okay if you had a smart way to parse based on index
im using float3 position as the key for the entities hashmap
dont know if that could help
which is what spatial partitionning is. The gist of it is a 3d grid. Every entity register to a cell, you query your current cell + neighbors
so, dividing city in a grid, loading some of them...and when camera goes far, load more objects, but with low-poly scene?
you can study the boids demo, it could give you ideas
link, please?
looks a lot like megacity demo
but megacity demo is not "real scale" xD
What do you mean by real scale ? It's flying car scale
well...think in london scale xD
thx
that's huge, can't even picture it
are you on foot or flying above ?
don't need to have everything loaded ? unload as you move away
"god vision" mode
yep...but the first try was "load all roads", and my CPU started crying
if you wanna see cars, roads and traffic lights, surely your camera is not so far from the ground
you can move closer
so, LOD required
probably sphere collider
or splitting into "cubes", rather than grid
I would start from megacity rather than boids
yes, sure
im already there
but is quite complex to digest without making little steps xD
How many of the 100k do you plan on being dynamic?
100k its only roads. add triffic lights, cars...so at the end, a low percentage
but quite a large amount
your gonna need to construct the rendering yourself probably and it sounds like your aiming too high, but more power to ya
world entities are being created by instancing a prefab, but i cant select/move/interact with them on editor
whats the expected way to be able to move objects on editor scene...use GO+conversion?
using Handler class?
conversion
googling show people is coding a system raycasting/colliding to get the entity selected
but that sounds quite ugly
What's the appropriate collection type to use for writing a bunch of structs to in one ScheduleParallel(Dependency) foreach to then read in the next ScheduleParallel(Dependency) foreach within the same SystemBase?
It feels like I shouldn't need a separate Job between the two to convert the parallel-written collection into something that can be parallel-read - I'm sure I'm just being dumb!
Narrator: he was being dumb, and was later to find .AsDeferredJobArray() π€¦
i have test system like this
public class TestSystemC : SystemBase
{
protected override void OnUpdate()
{
if (HasSingleton<TestTag>()) return;
var e = EntityManager.CreateEntity();
EntityManager.AddComponent<TestTag>(e);
EntityManager.SetName(e,"TestTag");
Debug.Log("TestTag");
}
}
and getting strange thing for me. When destroy this "TestTag" entity. This system doesn't execute. Looks like HasSingleton<T> creating something like query filter? Any tips how to avoid this ?
Tag your system with [AlwaysUpdateSystem]
errr...when you destroy the object, has is false, hence return...
Other way around, it returns if it has the singleton, not if it doesn't have it
has anyone here tried writing directly to the SkinMatrix components of a converted skinned mesh renderer? (rather than using DOTS animation)
excuse me?
if entity is destroyed and doesnt exist any object with TestTag, hasSingleton is false, and hence it returns
The evaluated condition if no singleton of that component exists is the following if (false) return;
That won't execute the branch body
sorry. too tired to realize i was wrong sooner xD
That happens lol
Martin Gram once again decides to grace us with his presence. Bestowing upon the proletarian masses his wisdom and disappearing into the wind.
Also, does anyone have a blittable version if DateTime?
still irks me to be moving to lts when dots is so feature incomplete
Maybe work with a timestamp (as a big enough uint)
I just need Year, Month, and Date. So i'm just hardcoding a conversion system using a Ushort, Byte, and Byte respectively. Annoying honestly but eh.
that sounds good
public void AddMonth(byte months = 1)
{
for (var i = 0; i < months; i++)
{
if (Month == Months.January)
Month = Months.February;
else if (Month == Months.February)
Month = Months.March;
else if (Month == Months.March)
Month = Months.April;
else if (Month == Months.April)
Month = Months.May;
else if (Month == Months.May)
Month = Months.June;
else if (Month == Months.June)
Month = Months.July;
else if (Month == Months.July)
Month = Months.August;
else if (Month == Months.August)
Month = Months.September;
else if (Month == Months.September)
Month = Months.October;
else if (Month == Months.October)
Month = Months.November;
else if (Month == Months.November)
Month = Months.December;
else if (Month == Months.December)
Month = Months.January;
}
}```
Does it really sound good?
public void AddMonth(byte months = 1)
{
for (var i = 0; i < months; i++)
{
if (Month == Months.January)
Month = Months.February;
else if (Month == Months.February)
Month = Months.March;
else if (Month == Months.March)
Month = Months.April;
else if (Month == Months.April)
Month = Months.May;
else if (Month == Months.May)
Month = Months.June;
else if (Month == Months.June)
Month = Months.July;
else if (Month == Months.July)
Month = Months.August;
else if (Month == Months.August)
Month = Months.September;
else if (Month == Months.September)
Month = Months.October;
else if (Month == Months.October)
Month = Months.November;
else if (Month == Months.November)
Month = Months.December;
else if (Month == Months.December)
Month = Months.January;
}
}```
for date operations timestamp would be better yeah
Yeaaaa
but hey that works too :p
No it doesnt. That if statement is horrifying.
or maybe bit shift
Hrm, 12 bits. Fits in a ushort. Yea, might work.
public ushort Year;
public Months Month;
public byte Date;
public void AddDay(byte days = 1)
{
Date += days;
if (Date < (byte) Month)
return;
Date -= (byte) Month;
}
public enum Months : byte
{
January = 31,
February = 28,
March = 31,
April = 30,
May = 31,
June = 30,
July = 31,
August = 31,
September = 30,
October = 31,
November = 30,
December = 31
}```
I'm using the months as both the indicator of actual month and the number of days per month. If I were to convert that to a bit mask, how would I then determine the number of days per month?
don't forget leap years π¬
Yea, I gonna pretend that doesnt exist