#archived-dots

1 messages · Page 85 of 1

balmy garnet
#

yes, to your first question- that's what I'm trying to do. I am using a hybrid approach where I generate ECS "tags" from monobehaviors since the ECS physics are not 100% there yet

#

the collision is already made up into a "collidingWith" buffer and a "colliding" component that works as a tag

#

the reason for why I'm using buffers is that I can collide with multiple objects as well as multiple entities can transfer various amounts of units to a single entity

tawdry tree
#

If those collisions happen frequently, then the adding and removal of tags, and thus changing archetypes, might have a notable performance impact

#

I believe the 'proper' way to do communication like this would be to, instead, create a HealthTransfer entity on collision (remember, an entity is just data, it doesn't need to be an actual in-game thing).
So on collision, calculate how much each unit transfers to each other unit, then later you run a system which takes all these transfers and apply the effects to the correct entities. Dunno if that will have better perf, or is even reasonable to do (code efficiency and maintenance wise), but eh

balmy garnet
#

yeah I was thinking on creating a new entity per transfer as well, but then I would have to apply that back to the original entity, making this even more complex imo

tawdry tree
#

Potentially, yeah?
But the flow would be:
-Check for which effects(transfers) to create
-->(and create entities for them)
-Use transfer entities to apply changes (deleting the entities)
As for how to get the entities you want to change from the references you ought to store in the transfer entities, I haven't done that kinda stuff and don't know how easy/hard/simple/complex it is, but i know it's possible.

balmy garnet
#

hm, so how great is getting other entities from jobs? because the way I see it, ecs jobs are only optimized to work on a single entity, not multiple ones at the same time.

#

if I do the transfer I feel like i have to get references to the other entity twice

tawdry tree
#

The first time could potentially be lightning fast, it's the second time, grabbing by the entity ID that is questionable. Again, no experience with doing that kinda stuff, so can't really say. I'd probably go for whichever leaves the best code, in terms of readability and maintainability(debug/extend later), unless I'd profiled and found it to be a performance hog

#

Eep, it's suddenly september (meaning, too late), so unfortunately I can't answer any more questions you might have, but good luck!

balmy garnet
#

haha, thanks for your time though!

tawdry tree
#

No problem, I would want people to answer my silly questions when I butt my head into some wall and can't see the path around it (been there, done that...), so it's only fair

amber flicker
#

Yea, entity per collision sounds reasonable - I’d start with a simple job that uses a CDFE to add/subtract and then if it turns out not fast enough and you have many ‘leaches’ per entity, it might be worth having a job that sums the effects before writing results via a hashmap method or something #rambles

balmy garnet
#

what's a CDFE? ComponentDataFunctionalEntity?

amber flicker
#

ComponentDataFromEntity - allows you to access any component by entity

balmy garnet
#

i am already using them, or trying to

#

I'm getting this error though: "... is not declared [ReadOnly] in a IJobParallelFor job. The container does not support parallel writing. Please use a more suitable container type."

#

i do have to write to those tho

amber flicker
#

Cool... if you design it so you’re sure you never write to the same entity, you can disable that safety check but in your case you possibly write to the same entity multiple times?

balmy garnet
#

not sure actually

amber flicker
#

if you do, perhaps two jobs - one that sums the damage/health and a second to apply them

#

sorry, also got to disappear - a very common pattern is to fill a hashmap or multihashmap with job1 and then process that with job2

balmy garnet
#

hm, well thanks for all the hints. it's also way past midnight for me so i'd have to go soon anyways. cheers!

amber flicker
#

good luck 🙂

thorny halo
#

hello, does anyone know how to declare a new array inside a job's Execute method without allocating garbage? I tried float[], but it seems that declaring reference types like that causes an enormous amount of lag.

lament orbit
#

@safe lintel i finally figured out a way to approach parent child kinematic physics objects 😄

#

@thorny halo NativeArray might do it

thorny halo
#

@lament orbit ty

surreal rune
#

Anyone here has experience implementing the BoidSystem from the ECS samples into their own project?

#

Have some quick questions

frosty siren
#

I need to store static list of lists and i need to access it in a job, but job can't be bursted because of using managed collection. What can i use to avoid it?

wary anchor
#

Hi all,

Need some help conceptually again.

I want to run a series of jobs, passing data between them, but for each of an entityquery. It seems like I need to do a foreach of the entity query in OnUpdate (ie on the main thread?) and kick off the series of inter-related jobs, like the way the boids examples does for each set of boids with the same SharedComponentData, but this time just for each individual entity - which doesn't seem like the canonical ECS way.

thorny halo
lament orbit
#

@frosty siren you might try breaking out the relevant data for the job from the lists in the OnUpdate by passing that data as burst friendly variables to the job scheduler.

frosty siren
#

@lament orbit yeah but it really big extra work. I know what list of lists i need only inside of a job. Also the list of lists stores inside class which not only one.

#

I use it for RO, so maybe i can use something like UnsafeList ?

wary anchor
#

@frosty siren I had a similarish case - I now calculate my publicly-available NativeMultiHashMap and NativeArray data in a system, then other systems access those data as readonly in their jobs. Can burst that way.

surreal rune
#

@thorny halo Thanks a lot! Think thats exactly what i'm looking for

#

But that's not ECS specific right?

thorny halo
#

It's just the main logic of how the boyds work.

surreal rune
#

Hmm yeah I understand. I didn't really ask my question clearly i think. I was advised to take the Mapping of Entities to locations from the Boids project

#

So I just want to use their implementation for the Quadtree like grouping of entities

#

if that makes sense

wary anchor
#

I found that example incredibly difficult to understand, but worthwhile spending the time trying to. I watched the video by Mike Acton and had the source code up from the Unity Samples github, and made notes - I must have watched that section of his video like 5 or 6 times, pausing, writing everything down and making sure I understood in my head exactly what was going on with the data. It's really worth doing it

surreal rune
#

Yeah it's very difficult

#

And his explanation too

#

Feel like there's a ton of info/knowledge I needed leading up to it, even though i feel like i have a lot of unity experience

#

Like a lot of terms that he dismisses as common knowledge that i've never heard of

#

Do you think there's a simpler alternative if i want to implement it quickly or should i just power through?

wary anchor
#

I feel the pain! I'm still very new to ECS myself and currently trying to put together a project almost entirely in ECS. whoever said ECS isn't hard it's just different was, unfortunately, lying. It is hard - but mostly because there aren't any intermediate examples.

surreal rune
#

I definitely agree

#

It's such new territory

#

And lack of documentation

wary anchor
#

but it does get easier, like everything, with practice and repetition. I will probably go back over bits of that video again myself soon, with my notes to hand!

surreal rune
#

Yeah for sure

thorny halo
#

Hello, has anyone used "IJobParallelForTransform" jobs before for thousands of transforms? I'm having trouble with performance after partitioning my TransformAccessArray into multiple chunks and scheduling multiple jobs for each chunk instead of just a single one. There's spikes of 15-25ms every 5-10th FixedUpdate which come from job scheduling, however, i can't pin down why the spikes would occur as I'm sending the same amount of data with the same Transforms each FixedUpdate. If i don't partition my TransformAccessArray, the spikes do not occur, however, i then need to send all of my transforms into a single job, out of which i might need only 10% to actually be updated, it ends up wasting a lot of performance. Is it normal for these spikes to occur if I'm scheduling 100 jobs instead of one?

surreal rune
#

Can I pm you @wary anchor ?

wary anchor
#

sure, but bear in mind I'm really quite a newbie at this myself!!

dull copper
#

Looking at Unite schedule, Sept 24 has:

  • Creating games with a tiny binary footprint: Project Tiny Overview & Roadmap
  • Get moving: an overview of physics in DOTS
  • GameObject to Entity conversion
  • Wreaking Havok: an overview of Havok Physics in Unity
  • Unboxing DOTS: designing workflows for humans
  • Introduction to Unity.Mathematics
  • Unity Entity Component System for mobile: Metropolis Traffic Simulation
  • Using Entity Command Buffers
#

Sept 25 has:

  • What to expect in 2020: Unity roadmap (and they still talk about Unity's 3-year vision here)
  • Creating a third-person zombie shooter with DOTS
  • Converting your game to DOTS
  • Building a Turn-Based Game Protoype using ECS
  • Introducing Data Flow Graph, the graph data processing system for DOTS
#

and Sept 26 has:

  • Options for Entity interaction
  • Introducing the DSPGraph, the new audio rendering/mixing engine
  • Intrinsics: Low-level engine development with Burst
surreal rune
#

I want to have a box to check collision with, kind of like a bounds or AABB but it needs to be rotated

#

Maybe i'm stupid but I can't figure out if there's such a type or if I'm just using the AABB incorrectly

surreal rune
#

I'm looking for an OBB implementation but I don't think Unity has it right?

surreal rune
#

Basically i want to create box 2 for checking interesctions

#

I know the Quaternion for rotating it

#

Just need to know what kind of Type i can use for this

#

AABB is axis aligned and my google searches don't result in much

low tangle
#

- Using Entity Command Buffers

#

aaaaaaa please

safe lintel
#

Creating a third-person zombie shooter with DOTS - please let that mean dots animation

safe lintel
#

also summer is running out for havok physics, wonder what the hold up is

untold night
#

probably waiting for Unite Copenhagen + Unity Tokyo

#

best to just drop all the accumulated updates and examples in one fell swoop

safe lintel
#

let it rain dots packages galore 😃

surreal rune
#

Can anyone answer my question above?

#

About the OBB or rotated bounds object?

mint iron
#

or use ECS physics package

dull copper
#

@safe lintel ```Creating a third-person zombie shooter with DOTS

Far North Entertainment is working on a third-person zombie shooter using the Data-Oriented Technology Stack (DOTS), which has brought both great performance improvements and faster iteration time. This intermediate-level session will explain why DOTS is able to process data much faster, how the team increased iteration speed using the Entity Component System (ECS), and its experience learning and working with Unity's ECS package.```

#

so not an animation talk 😄

#

also


This session will provide an overview of the Havok Physics integration and workflows in Unity. Attendees will gain insight into how we've integrated the industry-leading Havok Physics system into Unity using our Data-Oriented Technology Stack (DOTS). This session will cover the shared data layout of our physics engines, the performance and fidelity benefits of Havok Physics, and future development plans, as well as showcasing several examples from the Unity community that leverage these systems.```
#

so... if past has taught us anything, they are postponing the release to be aligned with Unite

#

I feel that stacking upcoming feats like they do for these events is just silly

#

it used to serve a purpose when they were actually releasing major new engine versions, like Unity 4, Unity 5 etc

#

but now when we got software as a service model, it would make sense to just give people the things as soon as they are actually ready for distribution

low tangle
#

might be to also give buffer

#

when they announced megacity and the fps sample it sounded like they barely just finished those on time

#

then it took awhile after to finish up for proper release

dull copper
#

ah, for those projects, sure

#

but I mean like actual packages and systems now

#

I guess they could just set the milestones there

#

but they stack these suspiciously large amounts for these events

#

and if it's some crunch for the events, that's not good either

#

and I do feel Unity has lots of crunching all the time

#

they definitely have had such for late engine releases and I can feel the crunch stress here already few months before next big events are up

low tangle
#

Yeah I'm not a fan of them waiting for big events either

#

But they are doing some good shit, so I hope they keep at it

wary anchor
#

hi all. I'm at a decision point and need a sounding board...
I've written a movement system for my 3D protein planets project, but the collision and gravity systems are not working quite how I'd like yet. The gravity is furthest along and I can probably get that sorted fairly soon, but collision detection and correction is a bit more tricky.

I could return to try to use the ECS Physics package now I'm a bit more au fait with ECS. It might pose some problems for gravity (gravity's per object and local) but I could probably overcome those.

#

I'm just not sure if it's worthwhile pursuing my in-theory lighter weight solution or get to grips with the more out of the box complete system

amber flicker
#

imo that depends on how complex your collision system could be - can you get away with pretty much just sphere colliders?

wary anchor
#

Yes, it's in fact only sphere colliders!

#

But for some reason my first attempt at it isn't working right and I'm in the middle of troubleshooting

#

it is sort of working so I'm not a million miles off

amber flicker
#

even if ecs physics was stable and easy to use, I might expect a custom solution to be better suited and faster in your case... given I don't think you can say that about ecs physics at this point (although tbf I haven't played around with it yet), I'd say it's a no-brainer - likely to spend longer trying to get ecs physics working than fixing whatever issues you have I would guess

wary anchor
#

Hmm yeah that seemed to be my impression when I first played with it, but I was even newer to ECS then so had even less of a clue what was going on! 🙂

#

Thanks @amber flicker I'll push on with my own and try to get this nailed!

amber flicker
#

Caveats - just my opinion and I wouldn't normally advise doing all your own physics but if you have local gravity and simple spherical collisions, I think it's the better route. Good luck 🙂

wary anchor
#

For version 2 it'll be raymarching. We live for tomorrow's tech today, right

dull copper
#

new Burst preview I see

#
## [Burst 1.1.3-preview.3] - 2019-09-02

- Query android API target level from player settings when building android standalone players.
- Add calli opcode support to support bindings to native code.

## [Burst 1.1.3-preview.2] - 2019-08-29

- Fix to allow calling [BurstDiscard] functions from static constructors.
- Correctly error if a DLLImport function uses a struct passed by value, but allow handle structs (structs with a single pointer/integer in them) as these require no ABI pain.
- Upgraded burst to use LLVM Version 8 by default, bringing the latest optimisation improvements from the LLVM project.
- Added support for multiple LLVM versions, this does increase the package size, however it allows us to retain compatability with platforms that still require older versions of LLVM.
- Fix bug in assembly caching, subsequent runs should now correctly use cached jit code as appropriate.
- Add support for Lumin platform

## [Burst 1.1.3-preview.1] - 2019-08-26

- Add support for use of the MethodImpl(MethodImplOptions.NoOptimization) on functions.
- Fix an issue whereby static readonly vector variables could not be constructed unless using the constructor whose number of elements matched the width of the vector.
- Fix an issue whereby static readonly vector variables could not be struct initialized.
- Improve codegen for structs with explicit layout and overlapping fields.
- Fix a bug causing SSE4 instructions to be run on unsupported processors.
- Fix an issue where storing a pointer would fail as our type normalizer would cast the pointer to an i8.
- Begin to add Burst-specific aliasing information by instructing LLVM on our stack-allocation and global variables rules.```
#

they upgraded the LLVM

mint iron
#

nice @ explicit/unions improvements

#

im hoping one day my xmas presents will all come at once and ECB processes commands in burst

wary anchor
#

uhm, this is madness... I just bypassed all my spatial partitioning code to try to get to grips with a rotation bug I'm seeing, and I see exactly the same frame rate and system calculation times for cycling over 33k positions and calculating the average vector based on (pos - targetPos)/sqDist for all of them

mint iron
#

so your spatial partitioning code is super fast ? 😄

wary anchor
#

Or super irrelevant 😄

#

Having a weird bug and I think I may see what's causing it but I'm not sure. When I move left/right, the up axis seems to update every frame as expected. When I move forwards, I don't get the same local rotation of the player. I think it's because I'm referencing the LocalToWorld in several places during my calculation but setting the Rotation.Value manually but I'm not 100% sure. Does anyone have any simple code showing how to set LocalToWorld directly? The docs are kinda dry on this and while I understand quaternions reasonably, I'm not good with matrices yet

mint iron
#

I don't unfortunately - only setting translations/rotations and letting the default systems do the rest. Are you wanting to set the LTW before the TransformGroup does its things with it in order to get the result updated sooner or something?

wary anchor
#

whoa I've screwed something up, sorry hang on eek

#

whoa okay found it that was a bit hairy for a moment.

#

Sorry, so I'm modifying the gravitational axis per frame based on nearby objects, but it seems to be screwing with the movement in different directions. I am now pretty sure I'm not ensuring my vertical velocity is actually perpendicular to my horizontal movement, so they're interfering with each other. I can't get over how fast ECS is though.

mint iron
#

yeah its pretty good 🙂

#

when u see benchmarks 50x faster than standard c# code doing the same thing its like woah.

wary anchor
#

Hmm now it appears if I change how I calculate my up axis (which gets normalized afterward!), it changes the mouse rotation and the graviational pull. THat's weird, I have really screwed something up here! Time to get a coffee and get stuck in

mint iron
#

i have something that might help you, i updated my debug drawing script to run in jobs and discard in burst

wary anchor
#

Oooo this looks shiny, thanks let's have a butcher's

mint iron
#

never heard that expression before, are you english? sounds english

wary anchor
#

yeah

#

Butcher's Hook => look

mint iron
#

haha, classic

#

actually, i only updated some of the methods. i know drawline works, but anything with Debug.x in it like DrawWireCube and Cone etc woudl need to have that moved into a new IDebugDrawing type, so that it gets passed into the queue for main thread.

wary anchor
#

I tried DrawArrow and it said it only runs in the main thread

#

All my movement code is currently in 1 job struct because I was having no end of trouble with jerkiness and it was getting overly complicated before. I'm very close to a working solution here!

mint iron
#

hold on then i can fix it for u quick

wary anchor
#

var tempRotation = quaternion.LookRotation(localToWorld.Forward, upAxisThisFrame); This is the problem. If the up axis rotates such that up/down is no longer orthogonal to forward, I don't get the rotation I want. Hmm I need to think on this. It's a shame not all of the Quaternion methods are available in quaternion, actually have to think a bit!

mint iron
#

you could always do it with Quaternion and then convert it to quaternion 😄

wary anchor
#

not inside a job, I can't!

#

surely?

#

I think I need the quaternion equivalent of Quaternion.FromToRotation()

#

No need to on my account, @mint iron! But of course I'll gladly use it if you have it!

#

yes, I have narrowed down my problem.
What is the Burst/Job compatible version of Quaternion.FromToRotation(axisFrom, axisTo)?

mint iron
#

so i'm not really that strong with this stuff, but maybe its just a multiplication to * from (with quaternions) ?

wary anchor
#

I solved it. This is pre-refactoring:

            var tempRotation = rotation.Value;
            float3 oldUp = math.normalizesafe(localToWorld.Up);
            float3 newUp = math.normalizesafe(upAxisThisFrame);
            float3 cross = math.cross(oldUp, newUp);
            float dot = 1 + math.dot(oldUp, newUp);

            var fromToQuat = math.normalize(new quaternion(cross.x, cross.y, cross.z, dot));
            tempRotation = math.mul(fromToQuat, tempRotation);
            rotation.Value = math.mul(math.normalize(quaternion.AxisAngle(upAxisThisFrame, inputComponent.RotationHorizontal * 0.0174532925f)), tempRotation);

Ugly, but works 🙂

green dune
#

0.0174532925f this hurts

wary anchor
#

then don't look inside Unity.Mathematics.math 😉

surreal rune
#

If i want to use a NativeArray in a job but don't know yet what size it is going to be, what can i do?

#

NativeList can't be used in a job right?

#

Oh only not in parallel jobs hmm

surreal rune
#

I want to remove entities in an IJobForeachWithEntites, but if i do that I can't use burstcompile because it's not compatible with the commandbuffer right?

#

Are there any alternatives?

#

Like somehow marking it for removal or adding a component so it gets deleted later

pliant pike
#

@surreal rune you can convert a list to a nativearray as well

prisma anchor
#

I am having trouble getting my player to render, I read that you need to have LocalToWorld matrix, but my player isn't rendering. I'm using a cube to render the player and a default material:

                var playerMesh = new RenderMesh() {
                    mesh = playerMeshFilter.sharedMesh,
                    material = playerMaterial.Result,
                    subMesh = 0,
                    castShadows = ShadowCastingMode.On,
                    receiveShadows = true
                };

                EntityArchetype playerArchtype = manager.CreateArchetype(
                    typeof(PlayerInputData),
                    typeof(MoveableData),
                    typeof(PlayerMovementData),
                    typeof(Translation),
                    typeof(LocalToWorld),
                    typeof(WorldRenderBounds),
                    typeof(RenderMesh));

                var playerEntity = manager.CreateEntity(playerArchtype);

                manager.SetComponentData(playerEntity, new Translation { Value = Vector3.zero });
                manager.SetComponentData(playerEntity, new PlayerMovementData { Speed = 0f });
                manager.SetSharedComponentData(playerEntity, playerMesh);
pliant pike
#

Rendermesh should look like this

#
EntityManager.SetSharedComponentData(Currentrobot, new RenderMesh { mesh = RobotCustomerMesh_1, material = RobotCustomerMaterial_1 });```
prisma anchor
#

I am setting the RenderMesh, I updated the first comment. See above. I also checked, and made sure they are not null

pliant pike
#

ok then I have no idea, the code is fine, its the way your getting the mesh and material perhaps

surreal rune
#

@pliant pike Thanks

prisma anchor
#

I just tried GameObject.Instaniate and assigned the material. And that worked. ┬─┬ ノ( ゜-゜ノ)

honest dirge
#

Is there an accepted standard way to represent child entities in terms of gathering all nested children and using them to produce a result. Much like the hierarchy, one element can point to many which in turn can point to many. I have a working system but it's very top level (child elements always belong to a single root so the root just stores a list of them).

tardy locust
#

Isn't that just recursion?

#

Given the name of the method here, I don't really know how I could achieve what I want to do.
I want to find all entities in my world that can be associated with one type of component.

public static NativeArray<Entity> GetAllEntitiesWithComponent(Type T)
{
    NativeArray<Entity> entities = m_EntityManager.GetAllEntities(Allocator.Temp);
    // What now?
}```
#

Is that even possible?

#

Because the entity manager only has "GetAllEntities"

#

But no way to get all entities with types

#

And using LINQ would likely not be the way to go

#

Lol

honest dirge
#

An entity query will return you the entities that have the component you want.

#

Recursion isn't a thing in ECS. It's all about getting flat.

#

So you need a linear representation. I probably need to dig deep into their hierarchical transform code for an answer.

tardy locust
#

Okay, and thanks

honest dirge
#

No problem. Just remember that your best performance will be running through the component data in a job rather that just retrieving them all on the main thread.

tardy locust
#

I'm trying to use jobs yea

#

I'm making a very simplistic and naive "life" simulator with varied creatures

#

Something I'm trying to figure out right now is "collision" in the sense that, if a piece of food has a distance of less than any given creature plus its scale

#

Then it is consumed by that creature

#

And so what I was thinking was

#

"What if I make a job for each piece of food? to test that?"

#

Does that sound insane?

low tangle
#

not really no, but why not do it differently

tardy locust
#

I'm all for ideas

#

I'm just trying out ECS to get it

#

I've so far not made any GameObjects and that's ultimately the goal

low tangle
#

its kind of a pain in the ass to multi thread it because you basically need locks when you consume food

tardy locust
#

Right.

#

What is your suggestion to do instead?

#

Just a traditional system?

low tangle
#

well, that would be the easiest for making sure you dont eat the same food twice

#

you are just doing a distance check after all

#

hm

tardy locust
#

Yea

low tangle
#

you could do three passes actually

#

on the creature put a position and a, for the lack of a better term, mouth component

#

and the mouth stores a entity ref of closest, and distance

tardy locust
#

Right now they are just circles moving about. No sense of "front".

low tangle
#

then first pass, populate all the mouths with closest bit of food and the distance to it

tardy locust
#
[UpdateAfter(typeof(CreatureConsumptionSystem))]
public class MoveTowardsFoodSystem : ComponentSystem
{
    private EntityManager m_EntityManager;
    private float deltaTime;

    protected override void OnCreate()
    {
        base.OnCreateManager();
        m_EntityManager = World.Active.EntityManager;
    }

    protected override void OnUpdate()
    {
        deltaTime = Time.deltaTime;
        Entities.ForEach((ref CreatureComp creature, ref Translation transComp) =>
        {
            if (creature.IsIdle == false && creature.FoodTarget != null)
            {
                float3 pos = m_EntityManager.GetComponentData<Translation>(creature.FoodTarget).Value;
                transComp.Value = ((pos - transComp.Value) * creature.Speed * deltaTime);
            }
        });
    }
}```

This is what I've set up.
low tangle
#

then do another pass to remove duplicates, then a final pass to actually consume the ones in range

tardy locust
#

Then the idea for each creature to find food was to run a job for each creature to simply look for a piece of food.

low tangle
#

the second pass is the only tricky one

#

yeah no, you cant think like that

#

you have to think in passes over data

#

not actions or logic

tardy locust
#

=_=

#

I thought I had it figured out..fuck

low tangle
#

you achieve logic though data transformations

#

I want this thing to move closer:
pass over all things and take the direction vector and add a delta towards it to the position on the thing

#

thats the logic vrs the data transformation

tardy locust
#

I thought I did that

#

Looking at my movement system

low tangle
#

yeah I'm not saying thats wrong

#

thats just a example of logic vrs the actual data transformation you need to think of

#

so when you say, I want all my creatures to eat the closest thing

tardy locust
#

But then, wouldn't it make sense to just use jobs for finding the nearest thing..?

low tangle
#

you now need to think of how to achieve that with data passes. thats why 'a job for each to find food' isn't correct, thats the desired logic you want

tardy locust
#

They will be competing for food regardless.

low tangle
#

you will be doing that in the first pass actually

#

first pass, distance check all food or spatial structure to find it faster instead of checking each, storing the closest food and distance onto the creature

tardy locust
#

For every piece of food in the world, check distance to that object.
Store the shortest distance Entity in the creature and keep moving towards it.

low tangle
#

second pass, make it so you wont try to eat the same food twice, this is the tricky one
third pass, actually do the consumption on each creature, though the first pass entity reference, if its close enough

#

second pass basically, you keep a thread safe native hashmap and try to add to it, that you are going to eat this thing (the hash map has a lock internally so it will be safe but thrashy to do this)
if you succeed in adding to the hashmap, you are the first one to try and eat this thing
if not, you cant eat this because another thing is going to eat it
optionally you can distance check (which could be your value in the hashmap) and overwrite the other creature as you are closer

#

in the final pass you can then take the final collection of keys in the hashmap in a job and pass over them, doing the consumption there, so that any overwrites are ignored and only the final, closest stored one is the one who eats

#

something like that should be close

tardy locust
#

I'm back to hating ECS again.

#

sigh

low tangle
#

hahah yeah

tardy locust
#

It's not enjoyable to use

low tangle
#

soon as you get conditionals, and want to do them multi threaded it gets nasty

tardy locust
#

And I dread that this is the future.

#

I know ECS has existed long before Unity but geez..

low tangle
#

multi threaded shit is hard even with a framework

#

this isn't really ECS, more of jobs and safety system

tardy locust
#

I mean..

low tangle
#

its the same reason rust is annoying

tardy locust
#

You know what I mean.
This is Unity's ECS

#

Whatever you want to call it

low tangle
#

just think how easy this would be in a regular component system

#

just do the consume, delete the target if its empty, go to the next creature

#

because theres only one thread ever accessing all foods and creatures

#

but if you multi thread, you can have race conditions and try to delete the same food at the same time

#

or eat a food value into the negatives

#

on the main thread thats super easy, but multi threading you have to rework things so that you can't do that by design

honest dirge
#

Half my pain with ecs it's just figuring out the right way to do things. Like... currently there's not a nice way to dispose NativeMultiHashMap so still having to do it in silly ways. And moving from 2018 ECS to 2019 ECS where they settled on some naming.

low tangle
#

actually someone pointed out they have a special version of dispose now you can chain

#

produces a jobhandle

#

so just use that as the final job handle in the chain when you schedule

honest dirge
#

Where and how? Have some infos?

tardy locust
#

Is it possible to get a component via the EntityManager in a job?

honest dirge
#

I tried to do that myself and it yelled at me that I can't dispose in a job

#

Yes. GetComponentDataFromEntity<>. Pass that to your job and you can query it for what you want.

tardy locust
#

So I have to pass a manager to the job?

honest dirge
#

It's not a manager it's more a pointer to where it can find those entities.

low tangle
#

no, thats only for a special type of job thing

#

yeah

#

you want to get a ComponentDataFromEntity<T> that you store as a public field

tardy locust
#

I have an array of entities that contains all my creatures.
The job then gets that array so it can look for the creature closest to itself.

honest dirge
#

@low tangle do you happen to know where that special dispose is?

tardy locust
#

But I can't call GetComponentDataFromEntity in the job because, well, there is nothing to call it on

honest dirge
#

No call that in OnUpdate and pass it in. It's function that's part of the job system.

tardy locust
#

I have 1 entity.
It represents a Creature.
The Creature has Translation on it. I need that.
But I also need the Scale which is on the same creature.

#
public struct ConsumptionJob : IJobForEach<FoodComp, Translation>
{
    public NativeArray<Entity> CreatureArray;
    public EntityManager m_EntityManager;

    public void Execute(ref FoodComp c0, ref Translation c1)
    {
        Scale creatureScale;
        Translation creatureTrans;
        float shortestDistance = float.PositiveInfinity;
        float distance;
        Entity winningCreature;

        for (int index = 0; index < CreatureArray.Length; index++)
        {

            distance = math.distance(c1.Value, (creatureTrans.Value + creatureScale.Value));
            if (shortestDistance > distance)
            {
                winningCreature = CreatureArray[index];
                shortestDistance = distance;
            }
        }
        CreatureArray.Dispose();
    }
}```
#

This is what I'm attempting to do

#

I'm not done yet, but that is the general gist...

#
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
    EntityQuery query = GetEntityQuery(typeof(CreatureComp), typeof(Translation));
    ConsumptionJob job = new ConsumptionJob
    {
        CreatureArray = query.ToEntityArray(Allocator.Temp)
    };

    JobHandle handle = job.Schedule(this, inputDeps);
    return handle;
}```
#

I need to change that query to just CreatureComp

low tangle
#

@honest dirge yeah one sec

low tangle
#

@honest dirge

honest dirge
#

That's hilarious. It's literally what I was doing but it's removing the safety checks around it so it doesn't spit out errors. Thanks!

low tangle
#

no problem :)

tardy locust
#
var sscale = GetComponentDataFromEntity<Scale>(true);```
#

I don't understand what this does

#

I don't know what entity it's getting this information from

#

Inside of an OnUpdate()

#

In a JobComponentSystem

low tangle
#

thats a way to get a accessor to other entities

#

with that component on them

#

var scale = sscale[aentitythatyouknowhasone];

tardy locust
#

I have this:

EntityQuery query = GetEntityQuery(typeof(CreatureComp));
NativeArray<Entity> entities = query.ToEntityArray(Allocator.TempJob);```
So I thought I could do something like, make 3 arrays with the components I wanted, attached to that entity...
low tangle
#

oh no, if you want a array attached to a entity, thats a DynamicBuffer

tardy locust
#
EntityQuery query = GetEntityQuery(typeof(CreatureComp));

NativeArray<Entity> entities = query.ToEntityArray(Allocator.TempJob);
NativeList<Scale> creatureScales = new NativeList<Scale>();
NativeList<Translation> creatureTranslations = new NativeList<Translation>();
NativeList<CreatureComp> creatures = new NativeList<CreatureComp>();

Scale scale;
Translation translation;
CreatureComp creature;

for (int index = 0; index < entities.Length; index++)
{
    var sscale = GetComponentDataFromEntity<Scale>(true);
}```
#

I wanted to do something like this...

#

That GetComponentDataFromEntity method is not clear in what it does

low tangle
#

it gives you a tool

#

to get other componetdatas by indexing using a entity

#

its not a thing, or a method

#

its like a magic array you can pull any of the component out of, using a entity

tardy locust
#

oof...magic in programming.. <.<

low tangle
#

its actually just a chunk + size offset calculator like a 1d to 3d array stride

tardy locust
#

okay

#

I am not a fan of magic in programming

#

Makes me nervous

#

xD

#

New question

#
[DeallocateOnJobCompletion]
public NativeArray<Entity> EntityArray { get; internal set; }```
#

Why is this not valid?

#

It says that it has to be used on type "field"

#

Isn't that exactly what that is..?

keen forge
tardy locust
#

Yeah it's too late for this. I forgot the distinction.

keen forge
#

👌

tardy locust
#

thanks though

keen forge
#

all good!

tardy locust
#

So

#

Can I use the Addressable System to just load in a Scriptable object?

#

Because it looks like it's more for like

#

World objects

worthy parcel
#

So uh, forgive me for walking in blind and not knowing if there's a FAQ or not but, what is the Entity - complete - system?

green dune
#

component*

#

this page has a v quick overview

worthy parcel
#

Neat.

tardy locust
#

IndexOutOfRangeException: Index 50 is out of restricted IJobParallelFor range [0...49] in ReadWriteBuffer. ReadWriteBuffers are restricted to only read & write the element at the job index. You can use double buffering strategies to avoid race conditions due to reading & writing in parallel to the same elements from a job.

#

hm

#

These are the so-called race conditions I suppose

#

But the actual error message of "out of range" doesn't really make much sense to me

coarse turtle
#

50 is the 51st element in a 0th based array

tardy locust
#

I get that

#

The issue is I don't understand the "range" thing it talks about

#

It shouldn't be raised...

#

Back to the drawing board I guess

coarse turtle
#

Looks like a new thread is trying to process something outside the bounds of the array, maybe something in the schedule function was wrong?

tardy locust
#
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
    EntityQuery query = GetEntityQuery(typeof(CreatureComp));

    NativeArray<Entity> entities = query.ToEntityArray(Allocator.TempJob);
    NativeArray<Scale> creatureScales = new NativeArray<Scale>(entities.Length, Allocator.TempJob);
    NativeArray<Translation> creatureTranslations = new NativeArray<Translation>(entities.Length, Allocator.TempJob);
    NativeArray<CreatureComp> creatures = new NativeArray<CreatureComp>(entities.Length, Allocator.TempJob);

    var scales = GetComponentDataFromEntity<Scale>(true);
    var translations = GetComponentDataFromEntity<Translation>(true);
    var creatureComps = GetComponentDataFromEntity<CreatureComp>(false);

    for (int index = 0; index < entities.Length; index++)
    {
        Entity entity = entities[index];
        creatureScales[index] = scales[entity];
        creatureTranslations[index] = translations[entity];
        creatures[index] = creatureComps[entity];
    }

    ConsumptionJob job = new ConsumptionJob
    {
        EntityArray = entities,
        Scales = creatureScales,
        Translations = creatureTranslations,
        Creatures = creatures
    };

    JobHandle handle = job.Schedule(this, inputDeps);
    return handle;
}```
#

I should preface this by saying that I don't really know what I'm doing here

#

I just have an idea of what the end result should be

#

As I understand it

#
public struct ConsumptionJob : IJobForEach<FoodComp, Translation>```
#

This grabs every entity with those components on it

#

Correct?

coarse turtle
#

yea

tardy locust
#

right.

#

So

#

I want to get every entity that has the FoodComp on it (I need to remove the Translation thing)

#

And for every one of those food items

#

I want to check the distance between itself and all possible creatures that can eat it

#

Now the job looks as follows:

public struct ConsumptionJob : IJobForEach<FoodComp, Translation>
{
    [DeallocateOnJobCompletion]
    public NativeArray<Entity> EntityArray;
    [DeallocateOnJobCompletion]
    public NativeArray<Scale> Scales;
    [DeallocateOnJobCompletion]
    public NativeArray<Translation> Translations;
    [DeallocateOnJobCompletion]
    public NativeArray<CreatureComp> Creatures;

    public void Execute(ref FoodComp foodComp, ref Translation foodTrans)
    {
        float distance;
        int winningCreature = 0;

        for (int index = 0; index < EntityArray.Length; index++)
        {
            try
            {
                Entity entity = EntityArray[index];

                distance = math.distance(foodTrans.Value, (Translations[index].Value + Scales[index].Value));
                if (distance <= 0)
                {
                    winningCreature = index;
                    foodComp.IsEaten = true;
                    break;
                }
            } catch(Exception e)
            {
                Console.WriteLine();
            }
        }

        if (foodComp.IsEaten == true)
        {
            CreatureComp creature = Creatures[winningCreature];
            creature.Energy = creature.AbsorptionRate * foodComp.Energy;
        }
    }
}
#

I just added the try/catch

#

And it makes little sense with the exception

#

Because the Index is 50, yet the size of the array it is trying to operate on is 100

coarse turtle
#

which line is the error talking abt mainly? just the entity array?

tardy locust
#

Entity entity = EntityArray[index];

#

This one

#

When I double click the error it takes me to that line

coarse turtle
#

hmm

tardy locust
#

It looks to me that this is something to do with "IJobForEach" itself

#

As if it had some sort of arbitrary limit on it of 50

coarse turtle
#

that might be the case 🤔

#

dumb question, what happens if you limit your array size of 51?

tardy locust
#

I can try

coarse turtle
#

or if its < 50

#

wondering if it still throws that same error

tardy locust
#

I set it to 50

#

Does not throw error

#

That is actually stupid

coarse turtle
#

ah dang 😐

#

okay so I can definitely reproduce what you had

#

so my thinking is, because there is no read safety insurance on the collection and the compiler can't determine that

#

if you ensure that the native array is considered ReadOnly, you can ensure parallel reading and it doesn't look like you need to modify the data of the arrays in the jobs

tardy locust
#

The "creatures" one is the only one that I have to write to, potentially..

#

I can't give any of these the "readonly" attribute

coarse turtle
#

The entity array can be read only, unless you intend to grow and shrink the array or change its elements mid job, as for the creatures one, if you really need to write back into an array - NativeDisableParallelForRestriction is an option

tardy locust
#

I can see that this warning is stacking up:

Internal: JobTempAlloc has allocations that are more than 4 frames old - this is not allowed and likely a leak

coarse turtle
#

but if every food is modifying that array, you'll certainly have a race condition - and that warning has been there for quite some time, afaik Joachim did say it was a bug in the editor

tardy locust
#

oh okay

#

I guess the problem is that

#

I'd need some way of marking food and have a main thread system

#

Like

#

Do the actual consumption

#

But that would be changing food

#

Instead of creatures..

#

I thought I was clever with this but...I guess the job system just fucks me over once more.

#

-.-

coarse turtle
#

yea consumption might be a main thread thing, especially if you want creature a and creature b to not eat food x when food x can only be consumed by 1 creature

tardy locust
#

That's super disappointing...

coarse turtle
#

the other possible way i can think of is if you used some sort of bloomfilter or a concurrent native hash map/set so that for each creature you process on you pick a food to store and check if the food is owned by some creature

then in a separate job, based on your constructed mapping of creature -> food, you can do your consumption and perform your calculations on energy acquired or so

tardy locust
#
public class MoveTowardsFoodSystem : ComponentSystem
{
    private EntityManager m_EntityManager;
    private float deltaTime;

    protected override void OnCreate()
    {
        base.OnCreateManager();
        m_EntityManager = World.Active.EntityManager;
    }

    protected override void OnUpdate()
    {
        deltaTime = Time.deltaTime;
        Entities.ForEach((ref CreatureComp creature, ref Translation transComp) =>
        {
            if (creature.IsIdle == false && creature.FoodTarget != null)
            {
                float3 pos = m_EntityManager.GetComponentData<Translation>(creature.FoodTarget).Value;
                transComp.Value = ((pos - transComp.Value) * creature.Speed * deltaTime);
            }
        });
    }
}```

I'm trying to make this into a job instead as that seems rather straight forward at least...but I can't quite wrap my head around how to approach that.
#

I've come this far and I'm blanking

public class MoveTowardsFoodJobSystem : JobComponentSystem
{
    public struct MoveJob : IJobForEach<CreatureComp, Translation>
    {
        Entity FoodTarget;
        
        public void Execute(ref CreatureComp c0, ref Translation c1)
        {
            if (c0.IsIdle == false && FoodTarget != null)
            {
                float3 pos =
            }
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        
        MoveJob job = new MoveJob();

        JobHandle handle = job.Schedule(this, inputDeps);
        return handle;
    }
}```
#

I'm having an issue here because I store the Entity to the food I wanna get to

#

But I'd still need to get the Translation for the food I'm heading towards

#

And I don't really know how to achieve that

#

The job system is really not intuitive

coarse turtle
#
    public struct MoveJob : IJobForEach<CreatureComp, Translation>
    {
        Entity FoodTarget;
        [ReadOnly] ComponentDataFromEntity<Translation> FoodTranslation;
        
        public void Execute(ref CreatureComp c0, ref Translation c1)
        {
            if (c0.IsIdle == false && FoodTarget != null)
            {
                Translation foodPos = FoodTranslation[FoodTarget]; 
                float3 pos = (c1.Value - foodPos.Value) * some_speed * some_delta;
        c1.Value = pos;
            }
        }
    }
#

might be what you're looking for

#

the job system will certainly take some time getting used to

tardy locust
#

ComponentDataFromEntity<Translation> FoodTranslation;

#

This I was unaware was a thing

#

And it's not something I would have guessed just by looking at it

#

Because it feels like I am declaring something that I should populate

#

But from the way you write it, this is not the case.

coarse turtle
#

well when you schedule the job

#

you will certainly populate it via the constructor or short hand constructor

tardy locust
#

Alright then..

#

Problem now is that

#

Unity says I didn't declare shit ReadOnly

#

When I did

#

InvalidOperationException: The NativeContainer ConsumptionJob.Data.EntityArray has been deallocated. All containers must be valid when scheduling a job.

#

fun

tardy locust
#

Well

#

It's all just systems now, no jobs

#

Though I can see that my implementation is pretty faulty somewhere

#

The creatures move insanely fast, like jittering

wary bough
#

Is there a way for entities to use light probes or lightmaps in LWRP? Both static and dynamic game objects which I convert to entities are just black at runtime

safe lintel
#

nope 😦

wary bough
#

That's a pretty major limitation, isn't it? Are the plans to have it implemented at any point?

amber flicker
#

AFAIK we don't know any specific plans but for sure, they'll support it eventually - it is a major limitation - hopefully we should find out more when Unite hits

wary bough
#

Hm okay thanks for the info. Just to double check it's not something that a custom SRP could handle?

safe lintel
#

im sure a custom srp could do it but that sounds like way too much work for something unity should get around to doing themselves

mint iron
#

anyone here going to Unite Cophenhagen?

safe lintel
#

not me 😦

mint iron
#

😦

safe lintel
#

are you going?

mint iron
#

i'm considering it, i have relatives coming from NZ on the 26th so i'd have to cut it short.

tawdry tree
#

Hmm, if I had thought about it earlier I could probably use my employer's standing offer to pay for relevant conferences, especially since the trip itself wouldn't be particularly expensive (from Norway), but it's a bit short notice now, having a contract out september and all.
Then again, I did give it some thought earlier, and essentially came to the conclusion that it would probably not be worth it with most important talks being available online (recordings or summarized) and I don't particularly like traveling.

safe lintel
#

i enjoy travelling, but im bad at networking so i guess the main point of these conferences is wasted on me 😄

tardy locust
#

Question for you folks

#

I have the following job system to move my creatures around:

public class MoveTowardsFoodJobSystem : JobComponentSystem
{
    public struct MoveJob : IJobForEach<CreatureComp, Translation>
    {
        public float deltaTime;
        [ReadOnly]
        public ComponentDataFromEntity<Translation> allTranslations;

        public void Execute(ref CreatureComp creature, ref Translation translation)
        {
            if (creature.IsDead == true || creature.IsIdle == true || creature.FoodTarget.Equals(Entity.Null))
            {
                return;
            }
            else
            {
                float3 foodPos = allTranslations[creature.FoodTarget].Value;
                float3 moveDir = Vector3.Normalize(foodPos - translation.Value);
                translation.Value += moveDir * creature.Speed * deltaTime;
            }
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        ComponentDataFromEntity<Translation> translations = GetComponentDataFromEntity<Translation>(true);
        MoveJob job = new MoveJob
        {
            deltaTime = Time.smoothDeltaTime,
            allTranslations = translations
        };

        job.Schedule(this, inputDeps);
        return inputDeps;
    }
}```

But when I run the code, I get the following error:
> InvalidOperationException: The writable NativeArray MoveJob.Iterator is the same NativeArray as MoveJob.Data.allTranslations, two NativeArrays may not be the same (aliasing).
#

And I suppose I understand what this means but

#

I don't really

#

How would I possibly get around this issue?

amber flicker
#

oh wait, no I see you're taking it as a component into the job as well

tardy locust
#

I just tried that any way. Didn't work

amber flicker
#

yea you can't take it as a component in a job at the same time as a CDFE (as far as I know) - so if you instead use IJobForEachWithEntity, you can then lookup your translation component via that entity

tardy locust
#

That's what I just thought of too actually. So will try that

#

See if it works

amber flicker
#

cool - yea it should work fine but report back if there are errors

#

fyi I also think you should do inputDeps = job.Schedule(this, inputDeps); as otherwise you're not passing on the dependencies of your job - also you can [readonly] to your creature ref I think

tardy locust
#

new problem

#

Now it seems that the issues I had are at least solved

#

But

#

The creature is looking for food

#

Yet the entity that is used for the food on the creature

#

Might not exist

mint iron
#

Could you post your new system code

tardy locust
#

Okay I got around that

#

I just check my array of translations if the food entity exists in it

#

If it does, then the creature can move towards it

#

But one thing that's weird now is that even though I assign a delta time to the job

#

DeltaTime is 0

#
public class MoveTowardsFoodJobSystem : JobComponentSystem
{
    public struct MoveJob : IJobForEachWithEntity<CreatureComp>
    {
        [ReadOnly] public float deltaTime;
        [ReadOnly] public ComponentDataFromEntity<Translation> allTranslations;

        public void Execute(Entity entity, int index, ref CreatureComp creature)
        {
            if (!allTranslations.Exists(creature.FoodTarget))
            {
                return;
            }
            else
            {
                if (creature.IsDead == true || creature.IsIdle == true || creature.FoodTarget.Equals(Entity.Null))
                {
                    return;
                }
                else
                {
                    float3 foodPos = allTranslations[creature.FoodTarget].Value;
                    Translation creaturePos = allTranslations[entity];
                    float3 moveDir = Vector3.Normalize(foodPos - creaturePos.Value);
                    creaturePos.Value += moveDir * creature.Speed * deltaTime;
                }
            }
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        MoveJob job = new MoveJob
        {
            deltaTime = Time.smoothDeltaTime,
            allTranslations = GetComponentDataFromEntity<Translation>(true)
        };

        inputDeps = job.Schedule(this, inputDeps);
        return inputDeps;
    }
}```
mint iron
#

interesting

#

i had pretty much the same aliasing issue earlier this week and ended up splitting it into multiple jobs 😦 this approach is probably better! the part i was missing was to remove the Translation from the IJobForEachWithEntity and use only the ComponentDataFromEntity

tardy locust
#

But why my delta time be 0 now? ;_;

amber flicker
#

yea - the error's much more obvious when you use IJobChunk - bit of a shame you can't iterate over some of the components linearly with rand access to the rest but I guess it makes sense because of the type lookup stuff

tardy locust
#

Okay so

#

DeltaTime is higher than 0...

#

But my creatures are not moving

#

Yet I do make it into the job that is supposed to apply movement

amber flicker
#

missing an allTranslations[entity] = creaturePos; perhaps

tardy locust
#

Translation creaturePos = allTranslations[entity];

amber flicker
#

when you change creaturePos.Value you're just changing the local struct - you need to assign it back

tardy locust
#

ah fuck

#

But how am I supposed to do that from the job?

#

The translation collection is readonly

amber flicker
#

if you want to write to it, you have to remove the readonly

#

then it will likely give you an error because from a job you might be writing to the same entity more than once

tardy locust
#

Yeah it says I need a different collection...

#

fuck this =_=

#

InvalidOperationException: MoveJob.Data.allTranslations is not declared [ReadOnly] in a IJobParallelFor job. The container does not support parallel writing. Please use a more suitable container type.

amber flicker
#

either you can be totally sure you won't (because you only ever set each creature's translation) - in which you can just add [NativeDisableParallelSafetyChecks] (not that but something similar - I forgot the exact name)

#

or you have to go down the route of two jobs

#

NativeDisableParallelForRestriction

low tangle
#

Or a entity command buffer

amber flicker
#

ah yes good point

tardy locust
#

Well NativeDisable worked at least

#

The creatures are just moving around now

amber flicker
#

cool cool

tardy locust
#

The job is supposed to only work on a single creature at a time so

#

It shouldn't be a problem as none of the other jobs would touch other creatures

amber flicker
#

yea, that's exactly why that attribute exists - to make sure you think and understand that you gotta be careful

#

but that if you know, you can just do it

tardy locust
#

Though performance is still abysmal

#

So much for threading =_=

amber flicker
#

have you enabled burst?

tardy locust
amber flicker
#

[BurstCompile] above your job?

#

would also try with safety checks disabled when looking at performance at all

tardy locust
#

Oh forgot the attribute

#

Let me try that

amber flicker
#

should be night and day difference

tardy locust
#

Just the struct right?

amber flicker
#

I think so

tardy locust
#

Is there any reason you wouldn't want the attribute?

#

On jobs

amber flicker
#

if you do things like add or remove components (via a commandbuffer) for example, that's not supported by burst atm

tardy locust
#

Okay but so

amber flicker
#

eventually you won't have to add it I would guess - they've just been taking an 'opt-in' approach so far

tardy locust
#

It's just because burst is under development atm that you'd not want the tag on all jobs then

amber flicker
#

I believe so

#

it's been asked previously - I think they just want to feel 100% about it before they make it default

#

any faster?

tardy locust
#

was away trying now

amber flicker
#

do you have 1mil creatures and 10mil foods? :/

#

even then... that looks odd

tardy locust
#

No

#

250 Creatures
300 Food

amber flicker
#

yea there's something odd going on - did you post the full system above?

tardy locust
#

I haven't posted all of my code, but one system in particular is taking a ton of resources

#

And I'm pretty sure I know why

#

It's because each piece of food tries to check if it's colliding with any creature so it can be marked "Eaten".

#
public class ConsumeFoodSystem : ComponentSystem
{
    private EntityManager m_EntityManager;

    protected override void OnCreate()
    {
        base.OnCreateManager();
        m_EntityManager = World.Active.EntityManager;
    }

    protected override void OnUpdate()
    {
        NativeArray<Entity> creatures = GetEntityQuery(typeof(CreatureComp)).ToEntityArray(Allocator.TempJob);

        Scale creatureScale;
        Translation creatureTranslation;
        CreatureComp creature;

        Entities.ForEach((ref FoodComp foodComp, ref Translation trans) =>
        {
            if (foodComp.IsEaten == false)
            {
                for (int index = 0; index < creatures.Length; index++)
                {
                    Entity entity = creatures[index];
                    creature = m_EntityManager.GetComponentData<CreatureComp>(entity);
                    if (creature.IsDead == false)
                    {
                        creatureScale = m_EntityManager.GetComponentData<Scale>(entity);
                        creatureTranslation = m_EntityManager.GetComponentData<Translation>(entity);
                        float distance = Vector3.Distance(trans.Value, creatureTranslation.Value);
                        if ((distance - creatureScale.Value) < creatureScale.Value)
                        {
                            foodComp.IsEaten = true;
                            creature.Energy += creature.AbsorptionRate * foodComp.Energy;
                            if (creature.Energy > creature.IdleThreshold)
                            {
                                creature.IsIdle = true;
                            }
                            creature.FoodTarget = Entity.Null;
                            break;
                        }
                    }
                }
            }
        });
        creatures.Dispose();
    }
}```
#

It's the one task I'd like to try and jobify

amber flicker
#

ah ok

tardy locust
#

So for every 1 piece of food

#

It needs to check a potential 100 creatures

#

Or well

#

250 creatures in this case

mint iron
#

you can put the GetEntityQuery(typeof(CreatureComp)) into OnCreate() and store it to a field rather than creating it every update

tardy locust
#

Problem is

#

I might wanna start destroying creatures at some point

#

And adding new ones

amber flicker
#

eventually you can do that by using a new system but anyway, yea jobify and burst away I guess

tardy locust
#

As you can see

#

Takes all the time

#

The rest of the processes are under 1 ms

surreal rune
#

I want to remove entities in an IJobForeachWithEntites, but if i do that I can't use burstcompile because it's not compatible with the commandbuffer right?

#

Are there any alternatives?

tardy locust
#

Aight @amber flicker Now my FPS is 270

surreal rune
#

Like somehow marking it for removal or adding a component so it gets deleted later

tardy locust
surreal rune
#

nice

amber flicker
#

much better @tardy locust nice

tardy locust
#

yea

amber flicker
#

@surreal rune ideally you would use a bulk query call.. e.g.. EntityManager.DestroyEntities(myEntitiesToDeleteQuery) or something - usually you have to preselect a subset of entities from an archetype so you can either fill a nativequeue in parallel then read one by one or you could look into NativeStream's which are supposed to read and write in parallel but I'm not familiar with them

#

you can also just use command buffers

surreal rune
#

Ohh so i can make a nativearray

#

In my jobforeach i fill the nativearray with entities to delete

#

So not delete them there and then

amber flicker
#

yea

surreal rune
#

and then delete the stuff in a seperate job?

#

So i can burstcompile the first job

#

and the second one has less entities

#

So its faster i guess

amber flicker
#

yea exactly

surreal rune
#

Hmm sounds good

#

I'll try that

#

Thanks!

amber flicker
#

np

surreal rune
#

Hmm

#

One more question

#

I dont know before the job how many I'm going to need to delete

#

So i can't use a nativearray

#

And i cant use a nativelist in parallel

#

do you have any tips for that?

tardy locust
#

@amber flicker

#

In case you were curious

low tangle
#

nativequeue supports parallel add, so does dynamic buffer If I remember correctly @surreal rune

surreal rune
#

Alright which of those 2 would you recommend?

low tangle
#

queue but I'm not really thinking too fast yet today

#

just woke up

safe lintel
#

er anyone getting issues with building stuff with dots and 19.3b1?

#

specifically a resulting build has entity conversion and (so far) rendermesh entities appearing in the wrong place/not getting the right translation/rotation/scale data as compared to an in editor play result(which appears correct)

surreal rune
#

Thanks @low tangle

#

So I have a NativeQueue Parallel writer i want to use in a IJobForeachWithEntity

#

After completing the job, i want to use the same NativeQueue in a job

#

But in a normal job, I can't or don't need it as a parallel writer

#

Should i convert it back somehow?

safe lintel
#

ok just tested in 19.2, definitely a 19.3 bug 😩

#

also anyone know why static objects dont get converted, only destroyed? this has been a thing for a while, dunno if this is by design or what

low tangle
#

can't just chain the queue though multiple jobs?

surreal rune
#

But it's a parallel writer

#

Wait I think I misunderstood

low tangle
#

right, but you just put the base queue as a varable, then bring in the parallel for one, and direct for the second

surreal rune
#

Yeah I gotcha now

#

Thanks I'll try that

vale stream
#

why might this be slowing down my game so much? I'm getting less than 40 fps with only 30 entities

Entities.ForEach((ref Position2D pos,ref Velocity velocity,ref MovementData moveDat,ref Radius radius) => {

    Vector2 velocityDir = math.normalize(velocity.value) * radius.value;
    Debug.DrawLine((Vector2)pos.value,(Vector2)pos.value + velocityDir,Color.black);

    float speedPercent = ((Vector2)velocity.value).magnitude / moveDat.moveSpeed;
    Debug.DrawLine((Vector2)pos.value,(Vector2)pos.value + velocityDir * speedPercent,Color.green);
});
#

its in a ComponentSystem

low tangle
#

Debug.DrawLine is pretty slow iirc

#

so is .magnitude

solar spire
#

so is normalize

#

could definitely combine a lot of the maths and remove the lines

untold night
#

You might want to create a deferred buffer for the debug draw lines based on color.

The Debug and Gizmo draw functions work better when you don't change the color between calls, wheras with what you're doing you're doing it every time.

If this is for editor only code, I suggest the Gizmo drawing routines.

You may also get more perf out of the low level GL drawing commands instead of debug.draw, as the Debug.Draw functions are ancient and aren't built for speed.

surreal rune
#

I'm getting this error: InvalidOperationException: The NativeArray GetPlantsShouldBurn.Iterator must be marked [ReadOnly] in the job PlantUpdateSystem:GetPlantsShouldBurn, because the container itself is ma

#

What's weird is that GetPlantsShouldBurn is an IJobForeachWithEntity

#

So i have no clue what to mark as readonly

void dirge
#

Hey guys can sombody help with one script

surreal rune
#

It errors on creation of the GetPlantsShouldBurn Job

#

Can anyone help me with this?

void dirge
#

I can't help you im very bad at scripting and i need help to

surreal rune
#

ah

#

What do you need?

void dirge
#

I need help with one 2d ball moving mechnaic

#

i can show u

glacial bolt
#

This is ECS channel

surreal rune
#

Yeah

#

@glacial bolt Do you have any idea about my problem?

void dirge
#

ik

surreal rune
#

Mentioned above

glacial bolt
#

Sorry, I haven't touched ECS and jobs yet 🙂

surreal rune
#

Ah alright

void dirge
#

Did u whatc tuturoial

#

or did u make it yourself

surreal rune
#

Make what?

#

My code?

mint iron
#

@surreal rune put [ReadOnly] before the read only arguments in your Execute method,
public void Execute([ReadOnly] ref BoardPosition boardPosition, // etc

surreal rune
#

I just figured that out as you said it

#

so wait

#

If i don't write to an argument, it must be readonly?

#

I thought the readonly was optional

#

Just to increase performance or something like that

#

@mint iron Thanks for the tip btw!

mint iron
#

np! i've been caught by that one a few times, its a pretty confusing exception message. If you're using a query then it seems to be based on the ComponentType.ReadOnly / ReadWrite used in the query declaration. If you're passing in the system then i'm not sure how it decides.

surreal rune
#

Hmm I get it now thanks!

#

One more question

#

And up to now ive been trying to manually find the NativeArray to blame

#

Is there a consistent way to find the issue?

mystic mountain
#

How would you go about matching an entity to another by a value of component? Say I random value for a component on an entity, and want to add it to a separate archetype which holds same value. (which I know existst)

surreal rune
#

Setting the define TLA_DEBUG_STACK_LEAK in script defines doesnt seem to wrok

#

@mystic mountain you mean like a component has a bool with true and you want to find all entities with that bool set to true?

mystic mountain
#

Sort of, I have a player entity which chooses a faction, and I want to place him on a ship with that faction.

surreal rune
#

Seems like it would be easier to just make a Component from the faction

mystic mountain
#

You mean one for each?

surreal rune
#

Yea

mint iron
#

if the player has the faction entity, then you could loop through the players, lookup a buffer on the faction entity with ComponentDataFromEntity/BufferFromEntity and add the player to it. So now the faction knows all the players assigned to it. Then you could have a ship grab the players from the faction that the ship is assigned to. It just depends on where you want to store the data.

surreal rune
#

So you can use the builtin ecs functions

#

I should look into these buffers

#

@mint iron Do you have a tip for my last question maybe?

#

sorry if im asking a lot lol

mystic mountain
#

I don't like it since then they will become separate archetypes

mint iron
#

@surreal rune no sorry i've never seen that exception before

surreal rune
#

Really?

#

I get it all the time if i don't dispose a nativearray

#

But i kind of have to guess which array it is

mystic mountain
#

Did you enable full stack traces?

surreal rune
#

In Leak Detection?

#

Its set to full in there

mystic mountain
#

Then no idea.
Anyone know how in what order Translation, LocalToWorld, LocalToParent are applied? If I add LocalToParent, will it be using that matrix to calculate Translation, or other way around etc?

wooden canopy
#

the basic is that the location, rotation, scale, etc, are used to make the local matrix

#

then using local to parent, they calculate local to world

#

but there are a lot of combinations in that manual

#

like you can have only some of those components, or variations of those, and what gets calculated, or calculated only once changes a bit

mystic mountain
#

I see, so if I have my wanted position locally, I need to first convert it with parent localToWorld.

#

From quick overview it looks like LocalToWorld is calculated last.

surreal rune
#

Good info!

#

So what is the best way to render a ton of entities?

#

I have 3 types of entities which should be represented by a green box, red box and black box

#

Now i just use sharedRenderMeshes but it still impacts performance a ton

#

What is the most efficient/performant way to render simple stuff like this?

#

Just turned on GPU instancing on my materials which made some difference but not a lot

#

Rendering the entities made my fps go from 300-600 to 40-70

amber flicker
#

What quantity of entities?

pliant pike
#

I dont suppose anyone knows how/if I can use a dynamicbuffer with HasSingleton

#

I get a boxing error conversion, I think the method can only take Icomponent data

amber flicker
#

if you're after a dynamicbuffer with a singleton couldn't you just use a NativeList or similar as a public property of the singleton system or something?

#

@surreal rune typically rendering about 100k cubes takes very roughly ~4ms on my i5 - if you want it to be faster I think you need to look into calling DrawMeshInstanced directly

pliant pike
#

can you use nativelist or nativearrays in Icomponentdata's?

amber flicker
#

no

#

if it's a singleton, why do you want it to be part of an IComponentData?

pliant pike
#

it's easier? I only need one set of the data, their waypoints stored in a buffer

#

that seems like the simplest cheapest way to store the waypoints on a single entity in a buffer

amber flicker
#

There might be a way but imo it doesn't make a lot of sense - I don't see the benefit of tying it to an entity or how public NativeList myWaypoints is much harder

surreal rune
#

@amber flicker Couple thousand

amber flicker
#

with Burst enabled, what does your profiler look like? it shouldn't be that expensive with instancing on

surreal rune
#

Burst for rendering?

amber flicker
#

I assume RenderSystemV2 (or whatever it's called - the hybrid render stuff) needs you to have Burst enabled in the menu for you to see decent performance in editor

pliant pike
#

I see so you mean store it in a system instead of an entity, that probably is better your right, thanks

surreal rune
#

Burst is enabled

amber flicker
#

yea with something like waypointSys = entityManager.GetExistingSystem<WaypointSystem>() on create then waypointSys.waypoints

surreal rune
#

And this is with only 170 entities

amber flicker
#

safety tests off? and can you show the timeline view?

#

you're just rendering basic cubes right? no complex meshes

surreal rune
#

Basic cube mesh

#

which i get from a primitive

#

this material

amber flicker
#

that looks like a lot of gc

surreal rune
#

hmm

#

Could be

amber flicker
#

safety tests on by any chance? they generate a lot

surreal rune
#

Safety checks now off

#

But doesnt seem to make much of a difference

#

Safety Checks off this time

#

Hmm

#

This time it seems just my systems

amber flicker
#

that last screenshot doesn't seem to show anything happening on your other threads - worth expanding 'jobs' and extending down the 'main thread' area a little too

surreal rune
#

nvm its not the systems

#

More like this

#

Not really used yet to reading the timeline

#

only the hierarchy lol

amber flicker
#

yea it's such a useful view

#

esp for multithreaded stuff

#

how many lights do you have in the scene? might be worth disabling them just as a comparison

surreal rune
#

Yeah

#

Only 1 directional

#

Its an insanely simplistic scene lol

#

but i'll disable it one sic

#

sec

#

I also still get these

#

Which i find hard to track down

#

Might be related?

amber flicker
#

oh well yea.. that'll be killing your perf and probably explains the gc 🙂

surreal rune
#

So

amber flicker
#

they're a pain to debug as everytime you get one of those you need to restart the editor to see if you fixed it

surreal rune
#

Yeah true

#

But is it all manually looking for it?

#

Is there no way to see which nativearray?

#

it says to enable a define

#

but when i do that in script define in player settings it doesnt do anything

amber flicker
#

afaik that message about the define isn't useful.. full stack traces is sometimes useful (from the jobs menu)

surreal rune
#

Thats on already

amber flicker
#

but mostly just enable systems one by one and look for any time you create a NativeArray or similar

#

not something I've ever had much trouble with but if you find it difficult, perhaps you could add the tag above every system that stops it being automatically added to the world and then re-introduce them one by one

surreal rune
#

How do you enable a system?

#

Just return in the onupdate?

#

Oh gotcha

amber flicker
#

yea that's probably as easy as anything... they do have a .enabled as well

surreal rune
#

your last message

#

ah

#

Gotcha!

amber flicker
#

👍

surreal rune
#

Thanks!

#

I have one more question for after this

#

I have 2 systems, one which updates a nativearray

#

One which uses that nativearray in a job

#

Now it says I need to add the first one as a dependency to the second one

#

Because it reads from the same NativeArray

#

Is there a way around that?

#

Because it feels iffy to have to add a dependency to another system

amber flicker
#

yea that never feels great... easiest solution is to move both jobs into the same system (thus limiting your scope of concerns) but sometimes that's undesirable

surreal rune
#

@amber flicker, Maybe i should consider that, thanks

#

I think they can be in the same system

amber flicker
#

you can also create a persistent NativeList or something OnCreate and destroy it in OnDestroy but you will still have to call .Complete on the first job

surreal rune
#

Ah so if i call .Complete, it won't be an issue?

#

guess that makes sense

amber flicker
#

correct, but at the cost of some potential performance

surreal rune
#

Ok

amber flicker
#

that profiler shot still looks suspicious with all that garbage

surreal rune
#

so adding as a dependency would be preferable?

amber flicker
#

yea usually

surreal rune
#

You mean the spikes in the graph?

amber flicker
#

it's all the red under everything

surreal rune
#

I'll show you how I instantiate the entities

#

maybe thats wrong

#

Im gonna clean it up when it's functional so dont judge me :p

amber flicker
#

looks fine at a quick glance - that profiler isn't showing you instantiating a bunch every frame is it?

surreal rune
#

Instantiating what?

#

Can I dm you?

amber flicker
#

sure

pliant pike
#

I have a basic stupid question how do I use a permanent nativearray in a job?

#

I keep getting mem leak errors and it saying not deallocated nativearray properly

#

I've tried both [DeallocateOnJobCompletion] inside the job and .Dispose(); outside of the job

tardy locust
#

Show me what you are trying to do

#

If you declare a native array outside of a job, and include it in its construction, then you use the attribute [DeallocateOnJobCompletition]. Make sure the NativeArray has "TempJob" as its allocator.

pliant pike
#
public class WayPointMoveSystem : JobComponentSystem
{
    public float MoveSpeed;

    public NativeArray<float3> MoveWaypoints;

    protected override void OnCreate()
    {
        MoveWaypoints = new NativeArray<float3>(2, Allocator.Persistent);
        MoveWaypoints[0] = new float3(-47, 2.2f, -50.65f);
        MoveWaypoints[1] = new float3(-47, 2.2f, 43.8f);

    }

    struct MovetoJob : IJobForEach<Translation>
    {
        public float movespeed;
        public float deltatime;
        [ReadOnly]//[DeallocateOnJobCompletion]
        public NativeArray<float3> tempwaypoints;

        public void Execute(ref Translation currmover)
       {
            //if(gothere.)

            float3 movedir = math.normalize(tempwaypoints[0] - currmover.Value);
            currmover.Value += movedir * movespeed * deltatime;
       }

    }


    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        MoveSpeed = 5;
        var movetoobjob = new MovetoJob
        {
            tempwaypoints = MoveWaypoints,
            deltatime = Time.deltaTime,
            movespeed = MoveSpeed
        };

        
        inputDeps = movetoobjob.Schedule(this, inputDeps);
        //MoveWaypoints.Dispose();

        return inputDeps;


    }
}```
tardy locust
#

The attribute is put on the native array field in your job

#

hm

pliant pike
#

I get the error "InvalidOperationException: The NativeContainer MovetoJob.Data.tempwaypoints has been deallocated. All containers must be valid when scheduling a job." if I use deallocate inside the job

tardy locust
#

er

#

Why is the allocator "persistent"?

pliant pike
#

because I need it for the life of the system

tardy locust
#

It seems like it expires at the end of the job though?

pliant pike
#

I need it to permanently store the waypoints

#

jobs can only use temp arrays though cant they?

#

maybe I could just cast the permanent array to a temp array?

tardy locust
#

Considering how you populate that array, with static numbers, why not just create it in the OnUpdate, pass it to the job struct and use the Deallocate attribute inside the job?

#

From the way your code is written there is no reason for the array to be persistent.

pliant pike
#

I dont if I put it in the onupdate then its doing unnecesary work surely?

#

having to set up the variables constantly

tardy locust
#
public class WayPointMoveSystem : JobComponentSystem
{
    public float MoveSpeed;
    struct MovetoJob : IJobForEach<Translation>
    {
        public float movespeed;
        public float deltatime;
        [DeallocateOnJobCompletion]
        [ReadOnly] public NativeArray<float3> tempwaypoints;

        public void Execute(ref Translation currmover)
       {
            float3 movedir = math.normalize(tempwaypoints[0] - currmover.Value);
            currmover.Value += movedir * movespeed * deltatime;
       }
    }


    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        NativeArray<float3> MoveWaypoints = new NativeArray<float3>(2, Allocator.TempJob);
        MoveWaypoints[0] = new float3(-47, 2.2f, -50.65f);
        MoveWaypoints[1] = new float3(-47, 2.2f, 43.8f);

        MoveSpeed = 5;
        var movetoobjob = new MovetoJob
        {
            tempwaypoints = MoveWaypoints,
            deltatime = Time.deltaTime,
            movespeed = MoveSpeed
        };

        inputDeps = movetoobjob.Schedule(this, inputDeps);
        return inputDeps;
    }
}```
#

If you want, I suppose you could have a reference to the MoveWayPoints outside, but considering what you are doing here I think the array has to be TempJob

#

So regardless it'll need to be deallocated

pliant pike
#

yeah, thanks, that seems a bit weird having to duplicate the data like that though

tardy locust
#

Well to be honest

#

ECS in Unity is a lot of repetition

#

Of code

#

From what I can gather at least.

#

Because one thing you have to consider in this scenario

#

Is that you cannot ensure when you are actually done with array if it's persistent

#

It could sit in memory forever

pliant pike
#

yeah I know its going to sit for the life of the system basically

tardy locust
#

The point of jobs is that you isolate what you are working on

#

So it only really exists during the lifetime of the job, I think

#

So when the job is deallocated after compleition, then so is all of its other references.

#

At least that's how I understand it

pliant pike
#

yeah

amber flicker
#

@pliant pike what you were doing should have been fine if you just put the dispose in OnDestroy instead of the job I think

#

(though I only quickly looked)

tawdry tree
#

For the most part, components are for data, organized into entities, and systems are for behavior.
Of course, putting a helper function on a component, or caching an archetype on system start isn't that big of a deal, but it all depends on how close you want to follow the principles and/or best practice, and of course, how easy it is to code and maintain.

pliant pike
#

yessss! I think it works, no errors, thanks @amber flicker

tardy locust
#

@tawdry tree Well yeah, but then you look at something like the FPS Sample and you find ECS violations all over the place xD

tawdry tree
#

Yeah, hence the last sentence

#

I imagine the samples will over time get closer to ECS principles. Or at least closer to the best practices, once we actually figure those out...

narrow field
#

what happened to GetEntities? It doesn't exist for me, for some reason. Yes, I am using the entities namespace (Unity.Entities)

coarse turtle
#

Might've been deprecated

#

if it's an entity query, you can do query.ToEntityArray(Allocator)

#

Btw, has anyone got GameObjectAfterConversionGroup attribute working to successfully modify a converted gameobject -> entity

#

e.g. let's say I'd like the ConversionWorld to cleanup some entities, like remove the LocalToWorld component datas

#

I can definitely log that the cmd buffer ran bu the entity when transferred back to the default world still has the LocalToWorld componentdata

safe lintel
#

i have a really simple system that removes the PhysicsVelocity component during conversion,i dont know about the 'GameObjectAfterConversionGroup' attribute but heres the code. it should still work but I havent used it in a while

using Unity.Entities;
using Unity.Physics;
using Unity.Physics.Authoring;

namespace Game.Modules.Conversion
{
    
    /// <summary>
    /// This System tells the conversion system to remove any PhysicsVelocity during conversion.
    /// Uses the RemoveVelocity component.
    /// </summary>
    [UpdateAfter(typeof(LegacyBoxColliderConversionSystem))]
    [UpdateAfter(typeof(LegacyCapsuleColliderConversionSystem))]
    [UpdateAfter(typeof(LegacySphereColliderConversionSystem))]
    [UpdateAfter(typeof(LegacyMeshColliderConversionSystem))]
    [UpdateAfter(typeof(PhysicsShapeConversionSystem))]
    [UpdateAfter(typeof(LegacyRigidbodyConversionSystem))]
    public class PhysicsAdditionalConversionSystem : GameObjectConversionSystem
    {
        protected override void OnUpdate()
        {
            Entities.ForEach(
                (StaticFractureAuthoring removeVelocity) =>
                {
                    var entity = GetPrimaryEntity(removeVelocity.gameObject);
                    DstEntityManager.RemoveComponent<PhysicsVelocity>(entity);
                }
            );
            Entities.ForEach(
                (RemoveVelocity removeVelocity) =>
                {
                    var entity = GetPrimaryEntity(removeVelocity.gameObject);
                    DstEntityManager.RemoveComponent<PhysicsVelocity>(entity);
                }
            );
        }
    }
}
coarse turtle
#

Ah thnx @safe lintel , maybe I'll jst keep it in the GameObjectConversionGroup instead

spring hare
#

Just how split-up do chunks for archetypes reasonably get in practice? Looking at the character controller physics sample, the components there got up to 96-ish bytes all together (there might be some padding in there but I just gave it a quick glance). I can imagine the total component count per component per chunk getting kind of slim after giving an archetype enough systems, but what are the reasonable averages and maximums in practice?

#

And if the total entity count per archetype chunk ends up getting low too easily, what are some ways of getting around the issue?

#

Like if you had two large subgroups of related components that could be split (conceptually) easily, where the two subgroups were associated by basically one system that took a component from each set, could you divide those component sets into different chunks somehow? Would it be advisable to do so? And if so, what would be the common strategies for doing so? I imagine things get difficult when you have two supposedly parallel archetypes and have to match their entities with different entity counts per chunk, not to mention the added complexity for copying/removing/safely scheduling/etc

#

TLDR how likely is it for component-heavy archetypes to bog down entity counts per chunk, and are there ways to deal with the problem?

low tangle
#

basically slim down the problem you are solving at any one step, along with using more tag components

#

archtype and fragmenting only effected me ever once

#

that one time, was to squeeze the maximal out of a distributed compression and decompression algo across sets of 60 entities

#

the difference was making it work for 1000 of those at a very reasonable frame rate cost vrs 100s of ms

#

outside of that one case I haven't had to pay much attention to my arch types other than a asset request system lately where I noticed my type is growing a lot

mint iron
#

@coarse turtle i've had success using the new EntityManager.SetArchetype inside an IConvertGameObjectToEntity Convert() to get it to discard all the default transforms and stuff.

coarse turtle
#

Ah cool never thought of that

mint iron
#

anyone else having really bad stability on the latest versions + editor 0b1? i tried upgrading everything today because i need a newer version of shadergraph but it broke all my addressables, and all my shaders, and now crashes the editor randomly every 5 minutes.

coarse turtle
#

for the shaders (if it's the LWRP) I did do these instructions to upgrade to the universal render pipeline https://docs.google.com/document/d/1Xd5bZa8pYZRHri-EnNkyhwrWEzSa15vtnpcg--xUCIs/edit

#

im still upgrading the entities side atm and fixing up some deprecated things

#

but with shader graph, I just opened the shader graph file and resaved the assets to regenerate the shaders for the universal render pipeline

spring hare
#

@low tangle so how did you slim down your archetypes when it mattered that one time?

#

Or more generally, what are the known/recommended strategies for doing so?

frosty siren
#

I'm perplexity about computing some data. I have methods that i need to call very rarely. But the problem is i can't predict how many entities will need to call those methods in 1 frame. It can be about 10 in a same frame or 100 in a same frame, or even 1, but 99% of frames methods will not be called. So i want to make it all with jobs.
The first solution for me was to separate logic to IJobForEach jobs that executes every frame and IJobParalleFor for rare logic. But it cause using CDFE/BFE with slow data accessing.
Another way is to use IJobChunk and access all possible data and dazzle together all logic without any troubles with data transfer and using slow data accessors

What the better way u think. And maybe i just misunderstood something

vagrant surge
#

what about only calculating a few at a time?

#

you can use the chunks version number to only calculate things every 4 frames or similar

frosty siren
#

i can't predict when i need to update it

surreal rune
#

@vagrant surge what do you mean using the chunks version number to only calculate things every 4 frames?

safe lintel
#

@mint iron I get a lot of crashes on recompiling or entering/exiting playmode. None during just play mode or working in editor when not compiling though.

#

also that SetArchetype looks very handy

low tangle
#

@spring hare basically I just reworked how I was thinking about the problem to split the data better, and make more fit into one chunk (less fragmenting)

spring hare
#

So you didn’t move data out of the archetype and process some of the data elsewhere

low tangle
#

split some entities and just kept refs

#

but for the most part I could just slim down the entity and make it simpler

spring hare
#

When you split the entities, how did you manage the refs? Did you have to eat the per-ref pointer chase cost, or did you manage to iterate different component chunks in semi-parallel, or did you maintain your own parallel nativearrays, or something different?

low tangle
#

eat the pointer cost, awhile back I was weary about it, but joachim said on the fourms, paraphrasing 'if it comes down to it and you need to random access some data, the best way is the simplest way of just accessing it though a ref/pointer, its about as fast as you can get'

#

basically, its okay, just accept the random access and focus your efforts elsewhere. if you really cant eat the performance (hyper critical performance stuff) you will have to rework your design to be more dots / bulk iteration friendly. but that can be super costly and non trivial

#

simple > complex and slightly faster

spring hare
#

That makes sense, thanks for giving a breakdown of your process there

low tangle
#

yeah np

safe lintel
#

Just declined my unite invite 😦 I dont suppose anyone else got one?

coarse turtle
#

I got declined the other day lol

#

wait unless, I totally misunderstood what you mean 🤔

safe lintel
#

did you get a free unite invite for community engagement?

coarse turtle
#

Oh no, I applied to do a pop up talk at unite

safe lintel
#

ohh - what was the proposed talk about?

coarse turtle
#

I wanted to talk about a testing pipeline on production assets with unit/play mode tests

#

before shipping a project

#

with workflows using the conversion pipeline for ecs

safe lintel
#

i wouldve attended 🙂

coarse turtle
#

lol thnx, it's something I've been doing working on art simulations with artists

safe lintel
#

are you still going to unite then?

coarse turtle
#

No ):

#

it's a tad too pricey for me to travel there

#

I think if there was one in NA, I certainly would've gone

safe lintel
#

yeah, same

coarse turtle
#

booking wise, I kind of waited until Unity gave me a response on the pop up talk application, and the prices just jumped a few hundred on plane tickets

#

but hopefully they'll stream a few of the ECS talks 🤞

dull copper
#

@safe lintel I just accepted my invite

#

Flights are relatively cheap for me, it's the hotels that cost more

#

@coarse turtle they usually only stream the keynote live if anything

coarse turtle
#

yeah, i expect that much, i dont remember things being streamed at the talks last year

dull copper
#

otherwise it'll be ~3 weeks until they start uploading talks to their youtube channel

coarse turtle
#

well, guess I'll just be patient haha

#

enjoy unite 👍

dull copper
#

thanks :) never attended these live before but couldnt pass the offer as it cant come much closer to me

#

Unless they somehow do event in Helsinki some year :D

#

But we have only tiny local Unity office here

#

We do have one of those smaller 1 day community events here tho

coarse turtle
#

yea same here

mint iron
#

@safe lintel @dull copper accepted my invite yesterday 😄 should be fun!

pliant pike
#

stupid question, I cant use things like transform.lookat, or vector3.movetowards in jobs so am I going to have to figure out the maths to do these things?

coarse turtle
#

Transform.LookAt(...) no you wouldnt be able to run in a job, possibly you can run Vector3.MoveTowards in a job

#

but you can likely do linear interpolation for Vector3.MoveTowards

#

As for looking at something, i'd imagine its computing the angle between 2 vectors and easing 1 vector towards the other until the angle is less than some threshold

pliant pike
#

I didn't think you could use vector3s in jobs, I guess it doesn't matter the maths are pretty simple, I'd just prefer it when they are predone, thanks

dull copper
#

I wont paste the full changelog here, it would fill 3 discord screens as it's so long with all the deprecated things so I'll just paste these parts:

## [Unity Physics 0.2.2-preview] - 2019-09-06

### Fixes

* Added internal API extensions to work around an API updater issue with Unity 2019.1 to provide a better upgrading experience.


## [Unity Physics 0.2.1-preview] - 2019-09-06

### Upgrade guide

* A few changes have been made to convex hulls that require double checking convex `PhysicsShapeAuthoring` components:
    * Default parameters for generating convex hulls have been tweaked, which could result in minor differences.
    * Bevel radius now applies a shrink to the shape rather than an expansion (as with primitive shape types).
* Mesh `PhysicsShapeAuthoring` objects with no custom mesh assigned now include points from enabled mesh renderers on their children (like convex shapes). Double check any mesh shapes in your projects.
* Due to a bug in version 0.2.0, any box colliders added to uniformly scaled objects had their scale baked into the box size parameter when initially added and/or when fit to render geometry. Double check box colliders on any uniformly scaled objects and update them as needed (usually by just re-fitting them to the render geometry).
* The serialization layout of `PhysicsShapeAuthoring` has changed. Values previously saved in the `m_ConvexRadius` field will be migrated to `m_ConvexHullGenerationParameters.m_BevelRadius`, and a `m_ConvexRadius_Deprecated` field will then store a negative value to indicate the old data have been migrated. Because this happens automatically when objects are deserialized, prefab instances may mark this field dirty even if the prefab has already been migrated. Double check prefab overrides for Bevel Radius on your prefab instances.```
#
### Changes

...

* Run-Time Behavior
    * `BoxCollider.Create()` is now compatible with Burst.
    * `CapsuleCollider.Create()` is now compatible with Burst.
    * `ConvexCollider.Create()` is now compatible with Burst.
    * `CylinderCollider.Create()` is now compatible with Burst.
    * `MeshCollider.Create()` is now compatible with Burst.
    * `SphereCollider.Create()` is now compatible with Burst.
    * `TerrainCollider.Create()` is now compatible with Burst.
* Authoring/Conversion Behavior
    * Converting mesh and convex shapes is now several orders of magnitude faster.
    * Convex meshes are more accurate and less prone to jitter.
    * `PhysicsShapeAuthoring` components set to convex now display a wire frame preview at edit time.
    * `PhysicsShapeAuthoring` components set to cylinder can now specify how many sides the generated hull should have.
    * Inspector controls for physics categories, custom material tags, and custom body tags now have a final option to select and edit the corresponding naming asset. 

### Fixes

* Body hierarchies with multiple shape types (e.g., classic collider types and `PhysicsShapeAuthoring`) now produce a single flat `CompoundCollider` tree, instead of a tree with several `CompoundCollider` leaves.
* Fixed issues causing dynamic objects to tunnel through thin static objects (most likely meshes)
* Fixed incorrect behavior of Constraint.Twist() with limitedAxis != 0
* Fixed regression introduced in 0.2.0 causing box shapes on uniformly scaled objects to always convert into a box with size 1 on all sides.
* Fixed exception when calling `Dispose()` on an uninitialized `CollisionWorld`.
safe lintel
#

@dull copper @mint iron I look forward to living vicariously through your experiences 👍

dull copper
#

lol

#

tbh, if you only care about the sessions, you'll probably get most of them by looking at the recordings anyway

#

also as I quickly glanced the schedule, some of the things I would have wanted to attend overlapped already

safe lintel
#

i meant the dinner, tour and allure of swag 😍 also meeting everyone wouldve been nice

dull copper
#

now everyone will find out that I'm an old fart, I kinda enjoyed just being an anonymous nickname here 😄

safe lintel
#

you will still be anonymous to me 😀

surreal rune
#

Is there something like a NativeSet?

#

A unique NativeArray?

#

Right now I just use a NativeHashmap and don't use the values but that's not ideal

vestal hatch
#

i was doing the exact same thing with a nativehashmap, but then i found i was overthinking the problem and didn't even need a set in the first place

surreal rune
#

I think i do need it though

#

Or what otehr way did you find?

#

Might be specific to your scenario

#

But thanks, that seems like what im looking for!

vestal hatch
#

it's specific to my scenario, i'm sure you have a valid reason

#

mine was basically trying to keep a set of dirty blocks in a chunk, but i found that just regenerating a chunk's mesh every time was already really fast so there was no need for the complexity

surreal rune
#

Ah alright

#

Question: when i import the file, i get errors saying i can only use unsafe if i'm compiling with /unsafe

#

Is there some setting i need to enable?

#

oh maybe in player settings

vestal hatch
#

ya it's under player i think

surreal rune
#

InvalidOperationException: PlantGridUpdateJob.Data.LocationsContainingBurningPlants uses the [NativeContainer] but has no AtomicSafetyHandle embedded, this is an internal error in the container type.

#

Don't think this works

dull copper
#

I guess they are close to releasing updated megacity sample

coarse turtle
#

ooh that's nice 👍

mint iron
#

@dull copper good, im an old fart too (by games industry standards), at least that means we wont be partying till 3am?

dull copper
low tangle
#

sweet

dull copper
#

ah, next physics package release going to happen around Unite

#

so in few weeks

#

kinda weird to target such near target right after this release

#

from forums:


    Collider Create() methods are now Burst compatible.
    Mesh and convex conversion is now much faster.
    Convex shapes now have wireframe previews in the scene at edit time
    Fitting shapes to render geometry and/or generating automatic convex hulls now accounts for skinned meshes

Please let us know if you encounter any major issues. Barring any critical issues that arise, our plan is for our next release to fall around Unite. ```
low tangle
#

damn

#

I wish they could just god dang release it

#

but I get it

dull copper
#

yeah, we had discussions about this

#

they stack these things for the events

#

or at least heavily schedule them to be out by the time the events are live

#

that being said, it's kinda weird they put that 0.2.2 out at all if they plan to release a new one in 2-3 weeks

#

considering they've been quite slow between the releases otherwise on this

surreal rune
#

Sucks for developers but makes a ton of sense from a marketing/sales standpoint

surreal rune
#

I want to get a IJobForeachWithEntity on entities that have either component A or component B

#

Is there any way to do this?

#

RequireComponentTag only works on All components given right?

#

Or should i just make an entityQuery with the Any in the description, get the entities and then manually put the resulting NativeArray into an IJob?

#

I also need to use the translation in the job

left oak
#

I think RequireComponentTag is like an inclusive or

#

i.e., like "Any"

coarse turtle
#

the other way is to use GetComponentForEntity<T>

#

from the JobComponentSystem and pass ComponentDataFromEntity<T> to your job

amber flicker
#

I think @surreal rune was looking for IJobChunk

coarse turtle
#

oo yea, that works too

surreal rune
#

Thanks for the suggestions everyone

#

Currently trying with IJobChunk like @amber flicker said

#

Is there a way to add and set componentdata in a single operation?

amber flicker
#

yea you just pass new Burning as the second arg

#

AddComponentData(entity, new Burning{blah})

surreal rune
#

Oh wow

#

I only just realized there's a AddComponent and AddComponentData

#

Thanks, that worked!

frosty siren
#

I see AsParallelWriter() in NativeList. But what is AsParallelReader() for?

pliant pike
#

Does anyone have any idea how/if I could turn the below code into a JobCompSyst or even whether it would be a good idea?

#
[AlwaysUpdateSystem]
public class TimeTickSystem : ComponentSystem
{
    //1.0f is about equal to 1 second 0.5 is about half a second
    private const float TICK_TIMER_MAX = 0.0001f;

    private int tick;
    private float tickTimer;

    protected override void OnStartRunning()
    {
        tick = 0;
        tickTimer = 0.0f;
    }

    protected override void OnUpdate()
    {
        if (HasSingleton<TimeTickEvent>())
        {
            EntityManager.DestroyEntity(GetSingletonEntity<TimeTickEvent>());
        }
        tickTimer += Time.deltaTime;
        if (tickTimer >= TICK_TIMER_MAX)
        {
            tickTimer -= TICK_TIMER_MAX;
            tick++;
            Debug.Log("tick" + tick);
            if (!HasSingleton<TimeTickEvent>())
            {
                EntityManager.CreateEntity(typeof(TimeTickEvent));              

            }
        }
    }    
}```
tawdry tree
#

What's happening with that entity? It seems to me like you don't use it? Or is it used elsewhere?

#

And for that matter, what are you trying to accomplish here? What's the use case/goal?

pliant pike
#

I use it elsewhere to create other entity's

frosty siren
#

What the problem to use IJob and ECB?

pliant pike
#

its a time tick system so I can have events happen at specific rates, like once a second or 1 every tenth of second

#

I'm wondering how low I can get the time bits down to

tawdry tree
#

Well, that depends on framerate

#

You can't have it run more than once per frame

pliant pike
#

whether a job would make any difference

tawdry tree
#

Which also, by the way, means that whatever uses that would be non-deterministic, since it would be framerate-dependent

#

It seems like a clunky/awkward way to do that, too, though I shan't complain since I don't have any better suggestions.

pliant pike
#

its framerate independent though, with time.deltatime isnt it?

tawdry tree
#

Well, yes no sorta

#

Depends on other things, too

#

If it's just, say, moving in a straight line, nothing else? Sure.
Except you get floating point inaccuracies.

pliant pike
#

my frame rate fluctuates like crazy and the time tick seems to be pretty consistent

tawdry tree
#

But what if you suddenly use the position to check something? For example, if X > 100, do something? the first frame after it crosses that line, it'd activate

#

Of course, you might not care about fully deterministic code, but you should be aware of it

pliant pike
#

I'm not sure what you mean, but I'm just using the above code to create one entity in another script every second

#

I'm guessing a JCB wouldn't make much difference, I cant run time deltatime in a job so it would keep stopping and starting the job which would be more overhead than a ComponentSystem

tawdry tree
#

That system seems like overkill for that. If you want to scale it up you would likely (it seems to me) want to have potentially different timers, ie. something goes every 1s, something else every 10s, another every 0.2s)

#

For using deltatime in a job, you just send it in as a parameter, though?

pliant pike
#

yeah its cached and you need delta.time updated every frame

#

I'm not sure how you would do it with less code and different timers

tawdry tree
#

In the other system, the one depending on the timer, in OnUpdate:

if(Time.time % run_every_X_seconds != 0) 
  return; //Skip
//Implied else
//run system logic/job
#

That should have the desired effect?

pliant pike
#

yeah I'll see how that works thanks

tawdry tree
#

KISS principle at work :P
We all fail at it occasionally, miserably at times...

pliant pike
#

yeah

#

I get the error "% cannot be applied to bool" with the above code

tawdry tree
#

Ah, sneaky extra start-parenthesis

#

You want to modulo the time, of course, and check if it's not whole, ie. one 'cycle' has passed

#

Though thinking about it, it likely won't work because floats

pliant pike
#

oh I changed it to this

#
if (Time.time > nexttimer)  
        {
            Debug.Log("Tick" + nexttimer);
            nexttimer = Time.time + TickTimerMax;        
        }```
tawdry tree
#

That looks better, yeah

#

I'd save the time it triggered, rounded to the nearest whole cycle, though

#

That code can slowly 'drift'

pliant pike
#

how so?

tawdry tree
#

Greater than.
Say, for example, that the cycle is 1/sec, and the time is 0.99s for one frame.
Then, the next frame, it is 1.01s. The next tick would then come no sooner than 2.01s

#

Something like this?

int previousCycle=0;
const float tickRate = 1f;

//Update
int currentCycle = (int)Mathf.Floor(Time.time/tickRate);
if(currentcycle <= previousCycle)
  return; //Skip
//Implied else
DoStuff();
previousCycle = currentCycle;
#

Cycles being integers intentionally, such that you can say for sure whether you're at a new one or not.
Also, I use Floor here, but you can use Ceil to start at cycle 1 instead of 0 (if my head-math is right)

pliant pike
#

ok I think I get it, thanks a lot for that

tardy locust
#

Would it make sense to use ECS to make a hex grid and maintain it?
Or would it make more sense to keep that as gameobjects?