#archived-dots
1 messages ยท Page 13 of 1
just entities.foreach and componentsystems. hardly any burst ๐คฎ
and lots of add/remove haha
Overall a good case of what you should not do
is burst 1.8.0-pre.2 usable?
works fine for me
ok great. thanks ๐
it sucks so hard that partial methods can't have return values -.-
i don't quite know how to get around that. basically i use methods that could or could not be source generated. but yeah, i need some form of placeholder. one of these methods is a get value. can't do it, it seems :/
hmmm, SO says ref works. that would be okay
can't you use out?
no
It doesn't have any accessibility modifiers (including the default private).
It returns void.
It doesn't have any out parameters.
It doesn't have any of the following modifiers virtual, override, sealed, new, or extern.
could potentially change field
and wrap it all in some getter
get{ PartialMethod(); return _field;}
seems dumb but partial is just a merge basically so you could have 2 methods that return. i don't see the issue though. compiler should complain. done
i don't care if enterprise coders can't get their shit together ๐
sure, but why? just cast to your struct or do you need some generic method?
yeah, it's generic
I need to make a callback for ISystem through interface
foreach (var system in World.Systems)
{
if (system is IUILoadedCallback callback)
{
callback.OnUILoaded();
}
}
For managed it's simple
yeah casting should work. not sure about the ptr though. never done it but in theory i see no problem
get the system struct through World.Unmanaged
huh? i mean get the struct and cast to your interface
not on my computer. look at the return value
SystemHandleUntyped
var sys = World.Unmanaged.GetExistingUnmanagedSystem(type);
unsafe
{
var sysPtr = World.Unmanaged.ResolveSystemState(sys);
}
ok I got direct pointer to system state
now
bruh
cannot do direct cast either
hmm
maybe I can make a call through reflection?
ITestInterface test = (ITestInterface)system.Struct;```
why don't you? ๐ your code isn't a black box to you. reflection won't work i think. the isystem is all in unmanaged space.
for generics i'd stay with systembase
or you register the type somewhere to find it out through the handle
{
if (_unmanagedSlotByTypeHash.TryGetFirstValue(BurstRuntime.GetHashCode64<T>(), out ushort handle, out _))
{
var block = _stateMemory.GetBlock(handle, out var subIndex);
var sysHandle = new SystemHandle<T>(handle, block->Version[subIndex], (uint) SequenceNumber);
void* ptr = (void*)(IntPtr)block->SystemPointer[subIndex];
return new SystemRef<T>(ptr, sysHandle);
}
FailBecauseSystemDoesNotExist();
return default;
}```
that's how you get a block and the ptr
the untyped handle has all the info
i think you were on a good track with ResolveSystemState. you could use an empty struct that implements your interface
then call it through the struct as the interface isn't working for T
oh right, they are partials. there might be some trick here
eh
I scrapped the idea
I figured other way to have async
way to handle this
public abstract class UIAddon
{
protected World World { get; private set; }
internal void Create(World world)
{
World = world;
OnCreate();
}
protected virtual void OnCreate() { }
}
Kek
They are created on demand
through reflections
and then cached in some system
so later I once UI is loaded I can supply them with OnCreate virtual
sadly it's only managed
but so far, it's only managed types that need it
You can have on start running in isystem
I'm getting loads of these when churning meshes with the Mesh API System.InvalidOperationException: Mesh data does not have {0} vertex component, any idea what that means?
that's with BURST on, with BURST off i get InvalidOperationException: Mesh data does not have Position vertex component
I would guess that your Mesh data does not have Position vertex component ๐
๐ช lol
might be a mesh that is empty then
voxel engine makes loads of crap output
added a test and it's fine now, thanks haha
In a situation where I need to use the managed debugger on standalone player from DOTS build using Rider. I can't seem to get it to work. Can someone help me troubleshoot this?
Can't debug bursted code with managed debugger
Not in 2021 hahaha
Even 2022 simply disables burst
It's just that it does it in a convenient way without a need to rebuild
But you can still debug
has anyone tried source generators? I can't get any output. just testing my generator with a test project, not unity. any special sauce needed?
read this generator https://github.com/PhilSA/PolymorphicStructs/tree/master/SourceGenerators/PolymorphicStructsSourceGenerators and have set it up similar
oh wow, missed the [Generator] tag ...
that sounds important
kinda ๐ here i thought ISourceGenerator is enough
i built myself a nice rabbit hole. first i generate a cs file with data and then i need the analyzer and source generator to use some templates to write the actual code with the relevant data types, stats and methods ๐
sadly c# is not very versatile when it comes to numeric data types being generic. total pain and honestly, kind of unexpected. even c++ is more versatile
fascinating, what in particular would be the language support you'd ideally add
using simple data types as T for generic methods would make it a lot easier. couldn't get it to work and using the struct version of the data types is a pain and hurts performance afaik
does it?
public struct JobInt : IJobFor
{
[ReadOnly]
public NativeArray<int> Input;
public NativeArray<int> Output;
public void Execute(int index)
{
this.Output[index] = this.Input[index] + 4;
}
}
[BurstCompile]
public struct JobIntOperation : IJobFor
{
[ReadOnly]
public NativeArray<IntOperation> Input;
public NativeArray<IntOperation> Output;
public void Execute(int index)
{
this.Output[index] = this.Input[index].Add(4);
}
}```
these 2 jobs generate the exact same burst for me
where T : unmanaged
{
T Add(T b);
}
public struct IntOperation : IOperation<int>
{
private int value;
public struct IntOperation : IOperation<IntOperation>
{
private int value;
public static implicit operator int(IntOperation i)
{
return i.value;
}
public static implicit operator IntOperation(int i)
{
return new IntOperation { value = i };
}
public IntOperation Add(IntOperation b)
{
return this.value + b.value;
}
}```
i'll test it as a generic in a sec
cool thanks, but that's what i mean you have to write all these implementations
Generic types is fine in burst. Burst just compiles all possible usages of the type
maybe that particular path is even worth exploring. sure implementing all this is tedious but once done it works. 2nd time i want to set foot in source generators and there are other (better) solutions
but this rabbit hole goes much deeper now and i want to strip/add whole code ๐
just to confirm for you
where T : unmanaged, IOperation<T>
{
for (var i = 0; i < input.Length; i++)
{
output[i] = input[i].Add(v);
}
}```
generates the exact same code as just using int
the struct is just completely stripped (as i expected)
single field structs are basically just treated as the field
ok i'm investing a bit more into this. maybe you have successfully kept me from going with source generators ๐
i prefer not using SG ๐
is it possible to profile a build?
which tool? it works for me
have used superluminal and vtune
you can even profile the editor
i've literally never tried just curious.. well i was thinking maybe a debug build and standalone unity profiler or something
no idea about debugging builds, never did so. unity profiler attaches just fine
just feel all the editor stuff gets in the way when for example sorting for whats taking longest etc in hierarchy view
so i was thinking, can i avoid all that by profiling a build
yes
you can attach unity debugger to development builds
yes i just use this setting
the EditorOnly taking up a chunk of time and skewing the sort order in the hierarchy view
i guess i'll just try it out right
well i guess
never noticed this before
damn, my project is kind of broken. why is unity not compiling my asmdef that has updates to the source generator?
can i force someway to just compile the asmdef? it will compile. reimport doesn't work
this is dumb. compilation stops before getting to the asmdef. making another project then ...
im not sure about 2021
but in 2020 you had to add 2 labels to your source gen asmdef for it to trigger
i believe this isn't required in 2021 though
not using any real source gen dlls. just a simple script that evaluates a scriptable object
well, i'm generating it now in a new project. i don't get it why it just stops compiling.
maybe i can get away with just htis. that would be nice ๐
Hi guys, anyone can point out what low hanging fruit can I benefit from using C# Jobs in a done traditionally with Monobehavior/GO ? thanks
Wondering if anybody can explain this to me because i don't fully understand it..
If i spawn a lot of physics bodies into my scene i'll see multiple build and step physics worlds inside the frame like this:
I'll get more build/steps per frame the more bodies etc i have in the scene:
100%. That's what I'm doing.
Fixed step death spiral.
If fixed step time becomes larger than frame time, fixed step enters a death spiral where it keeps iterating per frame
Only way to fix is disable unity's automatic fixed step ticker and implement your own:https://gafferongames.com/post/fix_your_timestep/
Yeah this is the part i'm struggling with
The issue with implementing your own and fixing the death spiral is that it loses the "stateless" feature of unity physics
If you dont care about it being stateless, then yea. Go ahead.
I mentioned this a while back but i did notice it's possible to just null out the RateManager and it forces one build/step per frame, but i'd rather 'understand' what's going on
hmm ok, i need to get my head around this
What is the spiral of death? Itโs what happens when your physics simulation canโt keep up with the steps itโs asked to take. For example, if your simulation is told: โOK, please simulate X seconds worth of physicsโ and if it takes Y seconds of real time to do so where Y > X, then it doesnโt take Einstein to realize that over time your simulation falls behind. Itโs called the spiral of death because being behind causes your update to simulate more steps to catch up, which causes you to fall further behind, which causes you to simulate more stepsโฆ
The fix is now "caching" the uncompleted fixed step event that took longer than FPS and not locking graphics update. Finishing the fixed step next frame and so on
Well, there is another option. Which is cutting fixed step time even more so it lands under framerate. And then interpolating the results.
That retains stateless but it may result in wonky physics with high time steps. And mandatory continuous collision detection which may be even more expensive
god damn that's a head-f*&^
but i think i understand what you're saying re caching the step and completing later ie it becomes stateful in that case
Yep. Physics is a wild rabbit hole.
what i was thinking was:
say in some old school game, if it started to lag, the physics itself would also lag ie it would slow down in accordance with your fps slowdown
so you have say an explosion that takes 20 seconds to complete or whatever
can't the step simply be locked to display fps in that way?
Old school may have framerate locked physics.
say if it's not networked, and you don't care about determinism or any of that
but you also don't want death spiral
lock to just 1 timestep?
does nulling out the RateManager achieve that or is there more to it
Basically, this line of code gives me my fps back:
World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<FixedStepSimulationSystemGroup>().RateManager = null;
Because it then only does a single build/step per frame
If it takes 20 seconds to complete. You have 2 options. One: Framerate lock it. Prevent graphics update until the explosion completes. That means 20 seconds of not moving, 20 seconds of unresponsive game, and about 2 seconds before the user alt-f4s.
Alternatively, you can unlock frame update but that means the user can run around, do whatever, then 20 seconds later a very delayed explosion happens and what the user did to physics objects will not match what the computation expects
and the physics go wild, moving in unexpected ways since the user changed the state of the physics while it was computing
or the user cant move, which is just option 1.
Well what i mean by 20 seconds is, the simulation plays back in 'slow motion' because it plays back at say 2 fps or something, in an extreme lag situation
You really cant play a physics in "slow motion" It doesnt work that way
reducing the time step doesnt reduce the computation cost
In fact, it increases it exponentially
The cost of physics is determining overlaps from axis aligned bounding boxes and then determining if, yes, this object does collide with this other object.
That is required per time step. Regardless of the length of it.
So i think my idea is basically what you were suggesting, ie frame locking it
Then yes, setting rate manager to null will frame lock it
But the issue is that now, the physics might not simulate correctly with variable timesteps
So if it takes x ms to compute the step, it does that and does not move on to render the frame until it's done with that
@devout prairie i might have missed something but is that from editor or build?
Yep
that's editor
do you have physics integrity checks on?
uhh
Dots -> Physics -> Integrity checks
yeah
turn that off
yes
but from your profile
to me you have like every safety feature on
which really kills physics in editor
i do yeah, in editor
turn off safety, jobs debugger and integrity checks and how does it compare
if you want to run these in editor it's often worth just dropping your fixed step to 20 or 30 in editor
to avoid killing your machine
If you can keep physics update less than framerate, then you dont need to change the default physics simulation
But lower time steps results in higher changes for object tunneling and collision misses for fast objects. Might be worth it for generally better performance.
tbh it's pretty much the same with those off:
make sure you dont have more than one PhysicsStep in your scene like I did ๐คก
sure you dont have full stack leak detection on?
seeing a lot of GC
no it was just set to On, trying with off
so Off is definitely a bit better:
How many objects?
a few ๐
so 3-7?
because that's a useless response
i have absolutely no allocations when i have all safety systems off
so as far as i can tell
you have something on
Entities count on the StepPhysicsWorld system is 7204
all dynamic i assume?
i can handle up to about 40k dynamics
before it breaks down
almost all using joints
well that might be the problem then
thats alot of joints
are they all on screen? because i see half simulation rate on far away objects a lot
not all at the same time but i'm assuming they're all being simulated either way
what's your sim speed? i see 14.5ms for 1 physics step alone. that's almost at the 60fps limit for just a step
speed is just the default
hm, not that the sim speed matters much here. is 1 step always this high or just when you instantiate?
the way i see it, to solve this problem is to get the step down at least to 7-8ms. 7ms or lower would be better, you want to have leeway for 1 extra step before spiraling.
instantiate is pretty quick to be honest for what it is.. this is after spawning and just letting the ragdolls settle, so it's a good average
i've early exited my other systems with 'return' just so that i can focus on what physics is doing on it's own
some form of staggered instantiate could also work. not all at once but one by one
your physics is taking your entire frame budget (17ms of 16ms for 60fps)
so if you do anything else in your entire frame you will spiral down
to be clear i'm deliberately spawning a lot of these, to obviously stress test it
so my original question was why does it repeat these build/steps multiple times per frame
i think KornFlakes kindof answered it in a way that made some kind of sense
physics often runs with a fixed small timestep
which is looped until you hit some convergence threshold
i guess the next question was, what's a good approach to combat that spiral or should i just limit how much i'm spawning basically
because with discrete physics you're handling the collision response at the same time as your contact point generation, so you want to make sure you don't miss an intersection that might happen with a big timestep
also because it leads to more consistent convergences. You can imagine just doing one giant physics step would be much less stable than 10 little ones
so would simply locking the physics step to the frame be a bad idea?
ie the frame doesn't render until the step calculates
whether it takes the step 1ms or 50ms
I wouldn't expect to see that in a real game
putting aside the concept of the simulation running in 'realtime' ie locked to the world clock
basically if it takes longer to sim the step, then it takes longer
is that a) possible and b) a bad idea ๐
kinda like how an oldschool game might have done it
say if you have too many explosions, everything slows down including the explosions/physics
the obvious and unsatisfying answer to this problem is, never ever let it happen ๐
that's really the problem with fixed timestep physics. what older games did was have a variable rate of step time.
afaik they were bound to render time
(this is not a new problem either btw, this is how the regular physics works in unityengine)
yep, and it's pretty much how all modern physics engines work. i'm not aware of any other method
unless you step manually with your own timestep
the physics engine doesn't really care
i guess coming from an animation/cgi background i'm kindof used to seeing it like this:
you run an animation with dynamics simulation in the viewport, if it's not too heavy it'll playback at a nice 30-60fps
when it gets bogged down the simulation plays back slowly
wdym slowly? how would it ever catch up? i guess they only run 1 step each frame. at least that's what would i do when realtime framerates are not the issue
that's what i mean yeah i guess it runs 1 step per frame
so if that step takes 30ms to simulate then you wait 30ms until the next frame update in the vp
@rotund token i'm generating now a bunch of those. need to see how this solution holds. right now it looks pretty good
no need for any generics that way ๐
should components have any sort of logic? I get that the system or jobs are supposed to handle that, but couldn't I just stuff all the relevant methods in the component and call them when necessary?
also, I noticed that a lot of components dont even have constructors
yeah no
hehe, i've been a pretty big opponent of using var. then i've started to use it while learning entities a lot more because types got so verbose. now i love it because it enables me to return any dataType i want without changing any code
It helps to have an IDE that shows you the type info selectively (like Rider).
i've turned that feature off in rider ๐ no idea why, i don't like it
well I use emacs so don't consider this a personal endorsement
using this struct solution, the code got cleaner than i imagined. good thing tertle brought this up. even though i'm using something completely different, it held me off enough to get knee-deep in source generators. and considering what i have now. it would have been a total waste. still code generating but no ISourceGenerator, just good old stringbuilder ๐
are you deving on linux or is emacs just a personal preference?
personal preference, I've long since committed to emacs for everything
Has anyone done any performance benchmarks of (both using burst) IJobEntity vs a normal job? To be more specific, Im interested in raycasting performance using the Unity Physics package.
IJobEntity just code gens into IJobEntityBatch
wait what
ISystems are not created during OnCreate phase?
var ccb = World.Unmanaged.GetExistingUnmanagedSystem<CollisionCommandBuffer>();
yes
an ISystem?
yes
yes, I need to get it in managed system
yeah
i believe all managed systems are created
then all unmanaged systems are created
But I need bursted update
and ISystem can do that
well yeah, and I need it to work with ManagedSystem
why
as command buffer
nothing you have said indicates you need to access an ISystem
how am I supposed to get reference to same collection?
a) i have many times very strongly expressed my disagreement with ever accessing collections in other systems
b) use a systembase
you know you can't store a native container in a ISystem anyway right?
even unsafe?
sure
an unsafelist won't work though externally
only the hashmaps really will work
but again b) use a systembase
how can I burst it then?
by putting it in a job
or calling a function pointer
which is all ISystem is doing
are you that pressed that you need to save 0.05ms by converting SystemBase to an ISystem?
I'm learning my tools, cause I wanted to use that approach in future
I guess what I could do instead
is create entity with Buffer
and store all data here
kek
WAIT WHAT
since when Unity Physics debug view works in game view?
pooog
brrrrruuuuh
it's "GIzmos"
I never turned it on in play mode
why my float3x2 variable won't change after completing a IJobParallelFor ?
bounds = new float3x2( math.min( v[i], bounds.c0 ), math.max( v[i], bounds.c1 ) );```
executing the same exact line on a normal loop outside of a job would work exactly as expected
you gotta share more code than that
[BurstCompile] struct ComputeBounds : IJob
{
[ReadOnly] public NativeArray<Vector3> verts;
public float3x2 bounds;
public void Execute() {
for (int i = 0; i < verts.Length; i++) {
var v = verts[i];
bounds = new float3x2(
math.min(v, bounds.c0) ,
math.max(v, bounds.c1) );
}
}
}
static readonly float3 MAX3 = new float3(float.MaxValue, float.MaxValue, float.MaxValue);
static readonly float3 MIN3 = new float3(float.MinValue, float.MinValue, float.MinValue);
var job = new ComputeBounds { bounds = new float3x2(MAX3, MIN3), verts = vertices };
job.Schedule().Complete();
that's it ...
tried both IJobParallelFor and IJob
your job works with a copy of your bounds variable. you need to work with native containers or have the data on entities to actually get the data out of the job
can u give me an example of a native container for a float3x2 ?
there is none :/. AFAIK you have to use something like a NativeArray<float3x2> with a size of one
how do you read bounds afterwards?
lol
this.bounds = job.bounds;
after Complete()
should be it
ยฏ_(ใ)_/ยฏ
can't you just share whole code block from start to end?
ill use array[1]
var job2 = new ComputeBounds { bounds = new float3x2(MAX3, MIN3), verts = vertices };
job2.Schedule().Complete();
this.bounds = job2.bounds;
that's all there is
i'm not even scheduling it on the previous job , made sure its a separate one
verts.Length
Are you certain it's not 0?
when should i check if not 0 , before schedule or after ?
well its not
not before , nor after
just checked
ill try with NativeArray[1]
yes ?
nvm
and you do only ever want to calculate bounds for one object?
i see
its been a while since i used burst , had been using nativeArrays just now
Burst is life
that problem you had had nothing to do with burst though
ye i love it , gotta say the whole setup and dispose is very messy code
it nearly triples the lines of code for the same task
well, for one you don't really need Schedule, if you instantly check for result - just run
from laggy 10fps down to 2ms ๐
ye after i merge ill just do
Schedule().Complete()
Run() is faster equivalent of that
i don't have it
why complete at all? just schedule the second job after the first with a dependency on the first
that's what im doing rn
that's not faster
but i want to move the code inside the first one
yeah if you want it single threaded
what was that [Decorator] which allows writing to the same array-index in parallel ?
[DisableNativeParalellRestrictions] or smth like that
if i would do something like single var container
use intellisense to figure actual name xD
yes i did ๐
was looking up Parrallel but no intelisense
btw
Run has no innerLoopBatchCount
what will it do if i just Run( arrayLength ) ?
but it is faster than scheduling if threads not worth it
I sometimes implement double job system which checks for amount of data to process
if it's small amount, I just do Run with IJob
if it's big - parallel
ye i figured
actually making it parallel reduced 1/2 ms
from 2 miliseconds to 1.5 miliseconds
but im doing a big innerLoopBatchCount
the test mesh im playing around with don't have too much verticies ( ~ around 4k verts )
so im guessing the parallel will help with larger meshes
finally got some bounds
now ill go read about Graphics.Draw API ๐
Does DOTS have support for pooling or like documentation on pooling with dots?
Like an example with projectiles for example?
DOTS doesn't need pooling
all memory is preallocated on chunks
if you mean ECS
yeah, any idea where i can read on the differences of memory just a very basic explanation
Just so i know why pooling is not needed in DOTS
I'd start with ECS basics
https://docs.unity3d.com/Packages/com.unity.entities@0.51/manual/ecs_core.html
I am reading through it and does it determine the size of the chunks based on the components an entity has
chunks are fixed size
chunk capacity depends on archetype
basically, how much can you fit in fixed byte array
i see, i think i understand it a little better now but not yet that much
But i am waiting for it to go to 1.0 before i will do something with it so i have time
ECS is a whole new concept that requires a lot of time to invest, before you can finally understand it
syntax is not much of an issue
it's literally "thinking" that is most of the problem, kek
yeah, i think from how it works the biggest thing is the way stuff interacts and how you should make your systems
one thing that annoys me most: OOP best practices are worst for ECS xD
yeah, that's a big adjustment i think/hope they make some good examples for how you would do something in ECS that was first done with normal gameObjects when 1.0 is out
ECS is not unique to Unity
it was made long before Unity has even started making engine
best practices of ECS are already available, basically hehe
But it's all conceptual
I'm trying to load a subscene using LoadSceneAsync. It doesn't load in a standalone build but it does work in the editor. Is there something I've missed?
Here's the relevant loading snippet. The async loading task is started but isSceneLoaded never returns true in a standalone build.
var world = World.DefaultGameObjectInjectionWorld;
var sceneSystem = world.GetExistingSystem<SceneSystem>();
// Hard coded for testing. This is a subscene guid copied from the editor.
Unity.Entities.Hash128 subSceneGUID = new(
x: 3353769547,
y: 1097787817,
z: 3813202594,
w: 44277289);
Entity sceneEntity = sceneSystem.LoadSceneAsync(subSceneGUID);
// This will load in the editor's play mode but will never succeed in a standalone build.
while (sceneSystem.IsSceneLoaded(sceneEntity) == false)
{
Debug.Log("waiting for prefabs scene to finish loading");
yield return new WaitForFixedUpdate();
}
For the standalone build I'm using the platforms package. The subSceneGUID above is a subscene of SimulationEntityPrefabs in the Scenes Info list.
why not just get guid dynamically?
is subscene part of scene?
That's what I intend to do but I wanted to make it work first.
Yes, it's part of SimulationEntityPrefabs in the Scenes Info list (Element 1).
just make serialized references in some mono to subscenes you need
and then grab all guids from it
I think this way you can even save this mono as prefab, serialized too
haven't tested it though
Thanks, although won't that ultimately lead to the same issue? I'm eventually going to pass a guid to SceneSystem.LoadSceneAsync, so it'll essentially function like the snippet above?
in case of game object serialization, it'll be generated during build
which might be the case
why guid is different
I replaced the hardcoded GUID with:
Unity.Entities.Hash128 subSceneGUID = sceneSystem.GetSceneGUID("Assets/Scenes/SimulationEntityPrefabs/PrefabsSubScene.unity");
According to the documentation that will look up the GUID in StreamingAssets/catalog.bin so it should be correct (and it did match the guid I hard coded).
So unfortunately the issue seems to be caused by something else.
The subscene is inside the "SimulationEntityPrefabs" scene. However, that scene isn't loaded at runtime. I only attempt to load the subscene through Unity.Scenes.SceneSystem. There's no references these scenes in gameobjects.
What's currently happening is:
- Game starts with
bootscene, which is an empty scene. RuntimeInitializeOnLoadMethodcreates a new monobehaviour gameobject which starts a loading coroutine.- In the loading coroutine:
a. Create a new emptySimulationRuntimescene (Used for gameobjects created at runtime).
b. Unload all other scenes.
c. Additive loadSimulationscene using addressables. This is a regular scene with some gameobjects created in the editor.activateOnLoadis set tofalse. Wait until loaded.
d. The snippet above is entered to load the entities subscene.
e. ActivateSimulationscene.
It was my understanding that step d would load the entities subscene into the default entities World and it's not really related to the other scenes there.
Well, most of that shouldn't really matter. Loading an entities subscene should be an isolated step, right?
are you loading a subscene or a scene dynamically? because you should load a scene with a subscene monobehaviour that references the subscene
the subscene itself does only exist as serialized data in a build
I'm dynamically loading a subscene. Thanks, I'll look into that.
netcode ghosts don't support doubles....?
damn i got kind of addicted to generate source code. all my very generalized source that runs on spell data could be turned into specialized source code
and it's pretty much the only way how i could get the timings down even more because right now i have 3 sources of slowness. a) target stats b) source stats c) blob data. i could eliminate the blob data but i honestly doubt i would gain that much from it.
how do you access a component from a parent entity?
Im using IJobEntity and I cant seem to find where ComponentFromEntity is. The Parent component doesn't have anything to invoke relating to getting a component.
ComponentFromEntity is passed in
call GetComponentFromEntity on the system
and pass it into the job
using the mouse hover/pick code from the physics samples, i noticed that they're using shared component to store material references, and i get a non blittable error when trying to do the same thing on a standard component - i take it only shared components allow managed object types?
i did kinda wonder why they'd used a shared component for a singleton
Shared components types that implement the ISharedComponent interface can only be modified on the main thread, without burst or in jobs because they're technically managed types. IIRC they're going to eventually be replaced with normal struct types that can be accessed everywhere.
Yeah that's what it was. Also, it's GetComponentDataFromEntity<T> and ComponentDataFromEntity<T>
you can have a class based IComponentData
That makes sense thanks. The samples hover/pick code does run on the main thread.
as i say i get this blittable error when i try use a UnityEngine.Material inside an IComponentData
is it a class
or a struct
because you can store managed objects in a class based IComponentData
not a struct based IComponentData
ahhhhhhh
public struct UnmanagedComponent : IComponentData
public class ManagedComponent : IComponentData
i don't think so
trying to store a buffer of materials
no
hmm
but just store a list
on a class icomponentdata
not really sure why you'd need a class based dynamic buffer
as i say, just trying to store a list of mats
and i get the same managed error with buffer
ahhh ok
hell
so because it's a class IComponentData i can use a list ?
skip the IComponentData
just attached the list to the entity
var list = new List<Material>();
EntityManager.AddComponentObject(entity, list);
DOTS works on 2021 unity?
netcode still death?
death?
I mean if it works also
netcode works fine
tbh i considered just storing this stuff inside system members, rather than the singleton component approach unity have used
it's all main thread anyway
not sure if there's any benefit to having it on a singleton entity/comp
kinda breaks the paradigm of ecs if you store data inside systems
i guess so
Far easier to access managed component data using entity manager and queries than to be dipping into systems from systems too
When I tried this I got an error saying it couldn't find the entityheader. If I look in the StreamingAssets folder in the build I see my subscene files in there but nothing related to the authoring scene. The examples I see in forum posts are passing the subscene guid to SceneSystem.LoadSceneAsync.
true in some ways i guess yeah
are you building with build configurations?
Yes, here's the config:
"SimulationEntityPrefabs" contains the entities subscene I'm trying to load.
they aren't your subscenes though correct?
Correct
have you overridden automatic boot strap?
Nope
No matter what I do I cannot get rid of this error: error CS0102: The type 'WheelColliderJob' already contains a definition for '__Rocket_Scripts_ECS_WheelCollider_AsymptotePointTypeHandle'
error is caused by the source generator
I don't even have a typeHandle anymore
code?
I figured out what the issue was here. In step c activateOnLoad was set to false. This caused subsequent calls to SceneSystem.IsSceneLoaded(subSceneEntity) to always return false. Activating the scene on load in step c fixes this. SceneSystem.IsSceneLoaded will now return true once the subscene is loaded.
If smth is on entity - then anything can access it
This works fine:
public partial struct TestForceJob : IJobEntity {
public void Execute (in PhysicsMass mass, in TestForceData forceData, ref PhysicsVelocity velocity) {
velocity.ApplyAngularImpulse(in mass, forceData.force);
}
}
// Seperate file
[GenerateAuthoringComponent]
public partial struct TestForceData : IComponentData {
public float3 force;
}
But this does not work:
public partial struct TestForceParentJob : IJobEntity {
public ComponentDataFromEntity<PhysicsVelocity> velocityComp;
public ComponentDataFromEntity<PhysicsMass> massComp;
public void Execute (in Parent parent, in TestForceData forceData, in ApplyForceToParentTag tag) {
if (velocityComp.TryGetComponent(parent.Value, out PhysicsVelocity velocity)) {
if (massComp.TryGetComponent(parent.Value, out PhysicsMass mass)) {
velocity.ApplyAngularImpulse(in mass, forceData.force);
UnityEngine.Debug.Log("Applied force: " + forceData.force);
} else {
UnityEngine.Debug.Log("Failed to get PhysicsMass component.");
}
} else {
UnityEngine.Debug.Log("Failed to get PhysicsVelocity component.");
}
}
}
// Seperate file
[GenerateAuthoringComponent]
public partial struct ApplyForceToParentTag : IComponentData { }
No exception is thrown, and it does reach the "Applied force:" log so it is working.
Here's what the system looks like:
protected override void OnUpdate () {
//TestForceJob job = new TestForceJob();
TestForceParentJob job = new TestForceParentJob {
massComp = GetComponentDataFromEntity<PhysicsMass>(),
velocityComp = GetComponentDataFromEntity<PhysicsVelocity>()
};
job.Schedule().Complete();
}```
velocity.ApplyAngularImpulse(in mass, forceData.force);
you haven't written the velocity back
you are just modifying the local copy of the struct
velocity.ApplyAngularImpulse(in mass, forceData.force);
}```
this case is passing it in by ref
you need to do
velocityComp[parent.Value] = velocity;
after you apply changes
what a weird way to write the velocity back
I wonder if it's possible to get a ref value with component data from entity
Just like with entity manager
Yep, works now thanks
yeah unfortunately you have to write your own copy as the fields are private
can't write an extension with asmref
nothing is private with hacks ๐
Publicizers rule
yes thats what i mean
you have to write something
it's much clearer to just have an extension method to add support
which you can do for most things in entities as for the most part everything is marked as internal
so it only takes a few seconds to add
public T this[Entity entity]
{
get
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
var ecs = m_Access->EntityComponentStore;
ecs->AssertEntityHasComponent(entity, m_TypeIndex);
CheckComponentIsZeroSized();
void* ptr = ecs->GetComponentDataWithTypeRO(entity, m_TypeIndex, ref m_Cache);
UnsafeUtility.CopyPtrToStructure(ptr, out T data);
return data;
}
well, tbh all of that is available easily through other means
most complex I guess is EntityComponentStore
because you don't want EntityManager in jobs
yep, feels bad it's private
well, one solution I see
use publicizer, build assembly
load as dll
this way it will bypass accessability I think
since dlls are not recompiled
Im really hoping 1.0 will fix all this API garbage that doesn't make much sense. It feels "messy" and overly complicated when it comes down to doing something simple. I can understand the requirements to access the components, that im fine with, but it's everything else that is annoying to work with at times.
but, it's not API garbage
it's literally language limitations
which are quite same in c++
what I simply tried to do here: make a hack with pointer
Doesn't sound like a language limitation if you can bypass it with a hack
plus, that was kinda my point
the API in some areas is sloppy, I'm absolutely certain that 1.0 will bring a lot of needed changes to the API the will mentally make more sense. I really dont care if I have to do 3 extra steps to make something work so long as it makes sense doing it
Naming conventions is a major aspect of any API. Personally, since a lot of people are going to be familiar with MonoBehaviour, having a similar naming convention for obviously similar components, behaviours, and systems would be best.
but it is xD
things that are passed by value are passed by value
pointers are not meant to be standard C# workflow
they require unsafe context
even Unity tried to avoid user from unsafe context
by wrapping it all in safe methods
with tons of checks
yes, as does 90% of DOTS logic, which suggests that using unsafe is a standard practice for unity's ECS
"safety and performance first" but they still provide pointers to be used, and even promote it in some scenarios
it is if you aim for maximum perfomance and you are advanced in C#
but I don't find it as a requirment
For DOTS/ECS it absolutely is a requirement
meh
maybe not for the developer making a game, but for the library it is
I personally prefer using pointers over objects since the logic flow is far more in tune with the logic of how a processor works (linearly)
managed logic is part of Unity ECS too
yes, and Im perfectly fine with that. Some managed memory on a core aspect of a library is perfectly acceptable
https://github.com/enzi/Entities.Exposed i've posted this quite a few times since you are here. ๐ it has a lot of these extensions to get ref or pointers
yeah long time ago. can't live without it ๐
i was begging on the unity forum since i dunno, before 0.17 or smth and they did discuss it internally but then never did bother adding it
Lets hope 1.0 they do, because now it's going to start getting much easier to add features after 1.0 is released
yeah they should. i consider the default CDFE implementation pretty trash because it returns a struct copy
using the ptr or ref is a pretty substantial increase in performance when you use it for the whole project. also, no copying back needed which results in much nicer code
it goes through the same checks as CDFE but the EntityManager.GetUnsafeCDFE doesn't add a reader/writer because i didn't bother getting the systemState. the ISystem/Systembase version does though ๐
i suppose, don't use the entityManager version. i just needed it to write tests
no, it's about adding dependency
internal
for systemstate
internal void AddReaderWriter(ComponentType componentType)
{
if (CalculateReaderWriterDependency.Add(componentType, ref m_JobDependencyForReadingSystems, ref m_JobDependencyForWritingSystems))
{
CompleteDependencyInternal();
}
}
this one
i literally just said it did so above and you have the code ๐
yeah it's a weird method name ๐
i have no idea what you consider a hacky extension. i think the important part it that it'll still be usable after entities updates, easy to integrate and doesn't require any rewrites or local versions of entities
hacky extension is compilation with publicized values
so you just access private fields without any regards for it's accessability
i think the answer is pretty obvious if you use words like hacky ๐
what's the upside of the "hacky extension"?
no need to have your own implementation
just use native one
you won't get very far with an extension as the fields are private and not internal
that's why it's hacky
publicizer makes everything public
publicizer?
i'm baffled you are even thinking about it ...
well
normally you'd use reflection
but publicizing is fast
and it's native
feel free to do it. idc ๐
How could I instantiate a specific entity to a location that a raycast hits? I'm pretty new to DOTS & ECS.
instantiate it and then set component of your choice
if (collisionWorld.CastRay(input, out RaycastHit closestHit)) {
Entity entity = EntityManager.Instantiate(prefab);
EntityManager.SetComponent(entity, new Translation { Value = closestHit.Position });
}
Thanks a lot ๐ But I guess I gotta learn some of the actual meanings of the stuff used by reading the docs before I start playing with the code.
rarely hurts
I honestly dont know what Im doing wrong...
just, trying to keep it hovering has been an absolute pain
How Im applying force:
velocity.ApplyImpulse(
massParent[parent.Value],
translationParent[parent.Value],
rotationParent[parent.Value],
local.Up * force.strength,
local.Position
);
What I do not understand is why it's bouncing when the rays are not even making contact with anything. It just bounces without input from the rays
console will log when a ray makes contact... multiple times I see it make contact and bounce without the log increasing at all
Here's what it looks like hovering (Hasn't made contact with the collider yet, which IMO is causing the bouncing)
that behaviour looks correct to me based on the fact that you always apply the same force per frame if a ray hits the ground. you will need to do something like vary the strength based on distance to ground and current downwards velocity. You could look at PID controllers
The behaviour in the first video is the issue. The second one is expected.
Yes, I completely disabled my system and it still bounces like crazy
they are set inlined if you don't give it asset
It does it with a normal cube wtf. Something is wrong with the physics engine
Here's the components the cube has:
what about ground
Just a physics shape:
and what's inside template?
Default:
do you have any special logic for filters?
no custom system is running atm. it's pure ECS logic if there is, other-than some gizmo stuff
Im about ready to give up on ECS and go back to GOs
this shit dont work
Making a new project with 2021.3.8f to see if there's a difference, otherwise, I will be postponing the usage of ECS until at least 1.0
shot in the dark: but what about that physics step component? maybe you get penetration over multiple physics frames and it adds forces to push out the collider multiple times
first time i see that component
physics step afaik just syncs it to the fixed update
the same
try enabling continuos collision detection
@solemn hollow what editor version are you using?
2021.3.6f1
same as me atm
I dont see an option for CCD in either of the components
i think dynamic + interpolation is CCD
cube is in its own subscene
still happens with CCD
also tried using a Rigidbody and Box Collider components but same effect
have you removed physics step component alltogether?
yes
but its not the cube doing the bouncy collision right? its the round shapes
all colliders do it
try box
YOOO
something's fucked with plane colliders
zero issue with convex
for the ground plane*
i just tried to replicate your scene. no issues at all
plane collider or box collider for ground both works
let me try something
can you set the scale of the plane to 100x100x100 and see if it bounces?
using scale ๐ค
yeah that is the issue kek
no bounce
all colliders i use have a nonuniform scale too
can you also set Size under the physics Shape to match the size of the plane? I think the issue has to do with the Size property because setting it to 1, 0, 1 works as expected, while having it match the scale causes the bouncing
for example, I set the plane to 100x100x100, and the plane Size property to 100x0x100
you mean with the button fit to rendermesh? works for me
yeah works for me as well
i cant reproduce your bounce at all :S
set your plane to this:
no problems
huh weird
im going to move the ground outside of the subscene
either way it turns out to be the Size property causing the issues. anything greater-than 10 causes the bouncing
my entities are not in a subscene
i had the size 10 times larger even and nothing happend
@rotund token is burst 1.8.0 pre2 good to use? im still on 1.7.2.
seems fine
"Setting a breakpoint in an attached managed debugger (Rider/VS Unity Debugger...) on a method that is burst compiled, will switch off the burst code path for that method, allowing it to be debugged as normal." this seems great
I've been using 1.8.0 and it seems to work fine
only works in 2022.2+
T_T
is the hybrid renderer required?
not unless you have your own rendering solution
My entities are invisible without the hybrid renderer, so im going to take that as a yes
Did you let the cube plop straight down or did you bounce it off of a corner/edge?
because in a new project it does the same bouncing
straight down. but i rotated it so it would land flat
needs to land on an edge
yes it did land on an edge
that's so weird
that im the only one with this issue so far
brand-new project and editor install as well (2021.3.8f1)
might be time to post in the physics forum.
try what happens if you switch to havok
good idea, ill try that
I'll make a post and submit a bug report to see if someone can reproduce it
my guess is when the cube penetrates the plane, the Size property somehow alters the rate of de-penetration... going to have a look at the sourcecode
hi all, probably been asked before, can you (schedule) instantiate/destroy with C# Jobs ?
do you work with entities or just gameobjects+jobs?
with entities you can use commandbuffers to schedule instantiation to a syncpoint in the future. with gameobjects youd need to create a list of all the objects you want to instantiate inside the job and then later outside of the job run through the list and instantiate them
GO + Jobs, no Entities
is it possible to use Jobs, (to use another thread) for only this purpose ?
the instantiation of gameobjects needs to happen on the mainthread
whats your usecase? something that an objectpool cant solve?
right, good point. Honestly, was tinkering wiht the idea of using different threads for different tasks
you shouldnt need to care about what thread does which tasks if you use the job system. it just uses as many threads in parrallel as possbile. what you need to care about is how many syncpoints you introduce where jobs need to be finished.
you can schedule it
make a list
add it to job
and if you need to destroy smth
add it to list
after job is completed
do whatever you want with that list in managed code
is there a quick way to convert Vector3[] to NativeArray<float3> and back ?
no quick
I mean, you'd need some unsafe extension for that
but it is possible to do very fast conversion between two
lol
Publicizer crashed PC when I tried to compile
attempt #2
eh, it won't compile
oh wait
I know
how to make it actually convinient
Instead of creating publicized dll extension with useful stuff
I can do it with only field that are required for useful stuff
basically, just make a extension for every private field that needs to be publicized
lemme test whether publicized dll works in editor
yep, it works
no crashes
that seems so much worse than the asmref trick ...
you are not using the lookupcache btw.
has to be resolved every time
this is literally copy of [int] getter
with different return
besides
I decided to do it differently
I will make a library with methods like this
public static void* m_access<T>(this ComponentDataFromEntity<T> cdfe)
where T : struct, IComponentData
{
return cdfe.m_Access;
}
providing access to private fields in different objects
through extension methods
this way it'll be so much easier to make good extensions
without a need to recompile anything
if you go for that, why not publicize the entityComponentStore? just access in cdfe will not be interesting to any other struct
I can publicize anything this way
but I want to do it through extensions for each field
the only problem - I'm struggling to get good reference to Unity API
what happens if you share your library? it won't compile, right?
wdym?
it can only be compiled with nugget
I tried to drop sources to project
but Unity does not recognize anything regarding publicized fields
I have no idea what's up
it won't build anymore xD
it did build hour ago
i don't get you, why you are going through this. there's a perfectly valid solution in front of you that has no drawbacks or eleborate setup and is shareable. yet you are wasting time on this. ๐ค
wdym solution?
you can't asmref smth that is private and not partial
most private variables are gettable in some other way. i never found a roadblock yet and i've gone balls deep into extensions. yes sometimes you just have to copy parts of unitys code but you need to do that anyway if you are extending.
well I want ComponentDataFromEntity as ref
most important stuff is internal
I don't want to reimplement my own cdfe
and the solution is to make something more complicated? the cdfe code is like what, 200 lines?
but it's not more complicated
it's actually so simple
and in case unity will make them internal instead
It'll be as easy as just remove old library
and fix naming for properties/fields
yet you are not finished yet. i had the cdfe ref done in like half an hour because i was just copying unitys cdfe and adding my methods to it.
well, I work kind of slow after actual work xD
and other people can just install the package in their project and done. no nuget or any other dependencies
well
that's my goal
I just build dll
and people can just install it in their project
and done
they can make their own extensions with it
using private fields
if I would want to add new private fields to it - this is when you need to build with nugget, yes
and that dll has the publicizer in it or how does that work?
that dll is already compiled publicized
access restrictions exist only in IDE
in compiler
after it's compiled - it'll work just like that
the publicizer modifies the entities dll, yes?
no
well, kind of
it simply makes everything public
all fields, methods, properties
so during compilation of dll, you can use it all
but it does not modify any actual dll
it's only for building
so if i want to use your dll i have to use a modified entities dll?
in runtime there is no such thing as private
no
you simply use my dll
that's it
any idea where can I get a good reference of ECS packages?
for Class Library project
I don't want to make it inside Unity project
so, that's it
public static unsafe ref T AsRef<T>(this ComponentDataFromEntity<T> cdfe, Entity entity)
where T : struct, IComponentData
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(cdfe.m_Safety());
#endif
var ecs = ((EntityDataAccess*)cdfe.m_Access())->EntityComponentStore;
ecs->AssertEntityHasComponent(entity, cdfe.m_TypeIndex());
CheckComponentIsZeroSized(cdfe);
void* ptr = ecs->GetComponentDataWithTypeRW(entity,
cdfe.m_TypeIndex(),
cdfe.m_GlobalSystemVersion(),
ref cdfe.m_Cache());
return ref UnsafeUtility.AsRef<T>(ptr);
}
And now I built my own extension method
If anyone wants to try xD
https://github.com/bustedbunny/UnityECSPublicized/releases/tag/0.1
Doesn't this just break all conditional code
tbh, idk
I'll try to build
ah yes
it is indeed breaks
hmm
how can I deal with it
I guess I can't
sucks
I wasn't even implying builds that's a whole other can of worms
I was thinking more things like turning off automatic bootstrap etc
I tried build because most of those conditionals don't exist in build
feels bad
Anyone here have issues with unity using more RAM each time it recompiles? Just trying to rule out experimental burst / dots stuff as the cause... ๐ฆ
hmmm
fixed is only usable on managed objects or?
btw, are NativeArrays or other collections pinned in memory or they can be subject of reallocation in heap during defragmentation?
How can I update a SystemBase in the equivalent FixedUpdate loop? adding the attribute [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] throws job dependency errors (trying to write to the same native array)
what kind of dependency errors?
InvalidOperationException: The previously scheduled job Solver:ParallelBuildJacobiansJob reads from the Unity.Collections.NativeArray`1[Unity.Physics.RigidBody] ParallelBuildJacobiansJob.World.CollisionWorld.m_Bodies. You are trying to schedule a new job WheelColliderJob, which writes to the same Unity.Collections.NativeArray`1[Unity.Physics.RigidBody] (via WheelColliderJob.JobData.collisionWorld.m_Bodies). To guarantee safety, you must include Solver:ParallelBuildJacobiansJob as a dependency of the newly scheduled job.
there isn't any dependencies. Just scheduling a IJobEntity in OnUpdate
well IJobEntity is subject for dependencies
static RayGizmo[] rays;
protected override void OnUpdate () {
NativeList<RayGizmo> rayList = new NativeList<RayGizmo>(4, Allocator.TempJob);
WheelColliderJob job = new WheelColliderJob {
velocityParent = GetComponentDataFromEntity<PhysicsVelocity>(),
translationParent = GetComponentDataFromEntity<Translation>(),
rotationParent = GetComponentDataFromEntity<Rotation>(),
massParent = GetComponentDataFromEntity<PhysicsMass>(),
collisionWorld = World.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld.CollisionWorld,
deltaTime = Time.DeltaTime,
rayDebugger = rayList.AsParallelWriter()
};
job.Schedule().Complete();
rays = rayList.ToArray();
rayList.Dispose();
Debug.Log(Time.DeltaTime);
}
every time you access any entity and their components you create a dependency
job.Schedule().Complete();
doing this in OnUpdate
Not supposed to?
it is a sync point, at very least
that results in more main thread idling
but you also
when you Schedule
you don't write Dependency
to it
so what happens
is that it simply runs
try this protected override void OnStartRunning() { this.RegisterPhysicsRuntimeSystemReadOnly(); }
and Unity notices it and shouts at you for that
meanwhile during that moment, some other jobs can access component data you requested
Schedule(Dependency)
would probably solve it
yeah, and additonaly schedule with Dependency
yeah two jobs try to write to the same memory, which is obviously not allowed or safe. That's what job dependencies are for, but I didn't know how to fix the error
but first you have to register the dependency with the code i posted
yeah let me try it
World.GetExistingSystem<BuildPhysicsWorld>()
๐ค
there's also readWrite to adjust accordingly
yeah, that should be cached in create
yeah I havent touched the system since last night. Been trying to figure out other things
Alright, so the system is correctly running on the fixed loop, but I get this error: InvalidOperationException: Adding/removing components or changing position/rotation/velocity/collider ECS data on dynamic entities during physics step
add true to all CDFEs
if you only read them
and assign readonly attributes to fields in job
Im writing to the PhysicsVelocity component on the parent entity, which is causing the error still.
I've set everything else to readonly
idk how else I'm supposed to apply a force to a rigidbody
Just this: [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
๐ค
should I specify an after as well?
try to add
hmm
what is it called
in world system
AddInputDependency
or smt hlike that
oh wait
you still do Complete
right?
yeah
add
UpdateAfter( ExportPhysics...
just make sure
your system runs
after physics step is fully done
near FixedStep ECB
Yep that's what it was
so many weird requirements to get something to just update in fixed lol
Like, I understand what they're doing
update order is very important in ECS
you need to know where your systems need to be called
Yeah, but having to use attributes makes it very messy sometimes. It would be nice if there was a system execution order window in the actual editor (like script execution order)
you can still have constraints if it was done through the editor
instead of specifying the attribute, you just add it to a group and set its order accordingly in the editor
you can still have attributes
it's just to visualize it and manage it the editor approach is better
but it's already visualized
when you create new system you simply just figure where it needs to be
kek
assuming you assign order as soon as you create system
That's the problem. Maybe you dont know the order it should actually be in
there's nothing to reference it after
most of the time
you don't care about the order
so you just let Unity do it
and when you do care, you probably know where it needs to be
well see, when working on prediction and networking it is absolutely critical you have full control over the order of execution.