#archived-dots

1 messages · Page 268 of 1

rotund token
#
        private struct GatherRenderMeshJob : IJobEntityBatch
        {
            [ReadOnly]
            public EntityTypeHandle EntityType;

            [ReadOnly]
            public SharedComponentTypeHandle<RenderMesh> RenderMeshType;

            [ReadOnly]
            public ComponentTypeHandle<LocalToWorld> LocalToWorldType;

            public NativeList<Chunk>.ParallelWriter Output;

            public NativeHashMap<Color, Entity>.ParallelWriter Map;

            public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
            {
                var colors = new UnsafeList<Vector4>(batchInChunk.Count, Allocator.Persistent);
                var transforms = new UnsafeList<Matrix4x4>(batchInChunk.Count, Allocator.Persistent);

                var entities = batchInChunk.GetNativeArray(this.EntityType);
                var localToWorlds = batchInChunk.GetNativeArray(this.LocalToWorldType);
                var mesh = batchInChunk.GetSharedComponentIndex(this.RenderMeshType);

                for (var index = 0; index < entities.Length; index++)
                {
                    Vector4 c = IndexToColor(entities[index].Index);
                    colors.AddNoResize(c);
                }

                transforms.AddRange(localToWorlds.GetUnsafeReadOnlyPtr(), localToWorlds.Length);
                this.Map.AddBatchUnsafe((Color*)colors.Ptr, (Entity*)entities.GetUnsafeReadOnlyPtr(), entities.Length);

                this.Output.AddNoResize(new Chunk
                {
                    Mesh = mesh,
                    Colors = colors,
                    Transforms = transforms,
                });
            }
        }```
#

anyway let me package it all up

rustic rain
#

2nd shader? for what?

rotund token
#

it nearly certainly has dependencies on my core library for some extension methods or something

rotund token
rustic rain
#

ah

rotund token
#

there's a weird issue that i could never figure out

#

commandBuffer.DrawMeshInstanced
commandBuffer.DrawRenderer
end up in different color spaces

#

so i had to convert the skin mesh render color space in the shader (did it that was just for performance reasons)

#

i don't know the issue, i couldn't figure out wtf was going on so i gave up and just went with the fix

rustic rain
#

here I go again xD

rotund token
#

chunk is a struct in this class

#
        {
            public int Mesh;
            public UnsafeList<Vector4> Colors;
            public UnsafeList<Matrix4x4> Transforms;
        }```
#

it's not a unity thing

rustic rain
#

ooh

solemn hollow
#

Thank you very much! helped me a ton the last 2 days 🙂

#

need to be afk for now

rustic rain
#

Vector4 c = IndexToColor(entities[index].Index);
Hmm

#

somehow

rotund token
#

my IndexToColor returns Color not Color32

#

(for this reason)

rustic rain
#

oh

#

lol

#

return new Color32(r, g, b, a);

#

that confused me

rotund token
#

😄

#

i should probably just directly do it myself

#

rather than like 2 implicit casts

#

probably be faster as well

rustic rain
#

AddBatchUnsafe

#

What is this method?

#

seems like some utility

rotund token
#

justs you add a lot of elements to hashmap at once

#

i've posted it here a few times

#

you can just iterate if you dont want to deal with pointers

rustic rain
#

oh, c'mon

#

it accesses internal fields

#

lo

#

lol

rustic rain
#

oh well
AddRangeNative

#

kek

#

what is this extension?

#

I assume it's cool one

#

since it works with pointer

#

kek

rotund token
#

was just heading off

#

is that on the list<T>?

rustic rain
#

normal List

rotund token
#
            where T : struct
        {
            if (length == 0)
            {
                return;
            }

            var index = list.Count;
            var newLength = index + length;

            // Resize our list if we require
            if (list.Capacity < newLength)
            {
                list.Capacity = newLength;
            }

            var items = NoAllocHelpers.ExtractArrayFromListT(list);
            var size = UnsafeUtility.SizeOf<T>();

            // Get the pointer to the end of the list
            var bufferStart = (IntPtr)UnsafeUtility.AddressOf(ref items[0]);
            var buffer = (byte*)(bufferStart + (size * index));

            UnsafeUtility.MemCpy(buffer, arrayBuffer, length * (long)size);

            NoAllocHelpers.ResizeList(list, newLength);
        }```
#

probably doesn't help as you probably don't have NoAllocHelpers

#

😄

#

(which is actually an internal UnityEngine static class)

rustic rain
#

hmm

#

how can I get it?

rotund token
#

if you can't tell, i have layers and layers of this stuff by now >_>

muted field
#

Does utility let you have conditions like getting a axe to cut the wood or would that be goap

solemn hollow
#

That makes the action basically chain automatically so thats why i tried to convince Issue to not use Actionqueues

rustic rain
#

at very minimum it's a must for literal queued player actions

solemn hollow
#

true.

#

i was able to skip action queues because i let my playerinput be processed by the UtilityAI too. kind of weird case

#

player basically defines the Action that should be executed and UtilityAi handles how its done

#

but i see why youd want that queue for your playerinput

covert lagoon
#
        public static BlobAssetReference<Collider> Create(NativeArray<float3> vertices, NativeArray<int3> triangles) =>
#

Why

#

Why NativeArray<float3> vertices, NativeArray<int3> triangles

#

Why not NativeArray<MyVertexType> vertices, NativeArray<ushort> triangles

#

Now I have to populate 2 vertex arrays and 2 triangle arrays when generating my meshes

rustic rain
#

Can I add DynamicBuffer as value?

#

to Entity

coarse turtle
covert lagoon
#

I have a NativeArray<MyVertexType> for vertices and a NativeArray<ushort> for triangles, not a NativeArray<float3> and a NativeArray<int3>

coarse turtle
#

Sorry what's MeshCollider.Create? is this related to Unity.Physics?

covert lagoon
#

Yes

#

I'm making a game with Minecraft-like procedurally generated terrain

coarse turtle
#

Ah mb then, I'm still not very familiar with Unity.Physics and thought you were talking about plain old meshes

covert lagoon
#

Anyway, what Unity Physics do I need to add to the terrain chunk entities I create at run-time for players to be able to walk on my terrain and not fall through it?

#

Just adding Translation, LocalToWorld, and PhysicsCollider components isn't enough, players still fall through terrain with this:

        var meshColliderReference = MeshCollider.Create(vertices, triangles);
        EntityCommandWriter.SetComponent(entityIndex, entity, new PhysicsCollider
        {
            Value = meshColliderReference,
        });
covert lagoon
#

All my terrain chunk entities are from this archetype:

        var chunkArchetype = dstManager.CreateArchetype(
            typeof(LocalToWorld),
            typeof(Translation),
            typeof(PhysicsCollider),
            typeof(PhysicsWorldIndex),
            typeof(TerrainChunkTag),
            typeof(TerrainChunkToGenerateTag),
            typeof(TerrainBlock)
        );
  • components added by Unity.Rendering.RenderMeshUtility
drowsy pagoda
#

Hey guys, can someone give me a quick lesson on using local methods? I have a Entities.ForEach.Schedule, and just under it I have three local methods declared. When using .Run() they work, but Schedule() gives me this: Assets\Scripts\GameBoard\GameBoardSystem.cs(121,13): error DC0004: Entities.ForEach Lambda expression captures a non-value type 'this'. This is only allowed with .WithoutBurst() and .Run()

I'm assuming that it has to do with my local methods. Is there a special thing I can do to make this work or best just to convert them to static and pass in extra context (i.e. command buffer, etc)?

#

Oh shit, nvmd, I converted to static and I still get this error. What could be triggering this?

#

Where can I paste my code for review/input?

rustic rain
drowsy pagoda
#

I'm aware of that, but it seems I am using something somewhere that I'm unaware of. Was wondering if I can post my code somewhere to get a second look at it from someone else?

rustic rain
#

yeah, just paste it here

drowsy pagoda
#

You sure? Don't want to clutter chat.

safe lintel
rustic rain
drowsy pagoda
#

Shit. Nitro doesn't let me 😛

#

What websites can I paste it in and share link here?

rustic rain
#

pastebin

#

I think

#

usually

#

if text is too large

#

it'll just create txt file automatically

#

when you ctrl+v

drowsy pagoda
rustic rain
#

and which line is error referrring to?

drowsy pagoda
#

So not much help there lol

rustic rain
#

wait

#

they need to be static

#

methods

drowsy pagoda
#

The local methods? Yeah I tried that, gave me the same error

#

That was my first assumption

rustic rain
#

well, they need to be local anyway

#

static*

drowsy pagoda
#

Alright, I'll update that right now.

#

Done. Just tested works great with Run. Switching to Schedule gives me the exact same error.

#

Would you like to see the entire script file?

#

Oooff, I found two variables _camera and _physicsWorldSystem that were referenced unnoticeably. I just did var camera = _camera and var physicsWorld = _physicsWorldSystem just before Entities.ForEach.
And now I get this error:
Entities.ForEach Lambda expression captures a non-value type 'camera'. This is only allowed with .WithoutBurst() and .Run()

So I'm pretty sure now this is the exact issue. Although I don't understand how to get around this...

rustic rain
#

well

#

that's your answer

#

Managed types aren't allowed in scheduled/bursted jobs

#

get all data you need before the job

covert lagoon
#
ArgumentException: A component with type:Unity.Physics.PhysicsWorldIndex has not been added to the entity.

Why?

#

Archetype:

        var chunkArchetype = dstManager.CreateArchetype(
            typeof(LocalToWorld),
            typeof(Translation),
            typeof(Rotation),
            typeof(PhysicsWorldIndex),
            typeof(PhysicsCollider),
            typeof(TerrainChunkTag),
            typeof(TerrainChunkToGenerateTag),
            typeof(TerrainBlock)
        );
#

Setting the PhysicsWorldIndex shared component (this appears in the stack trace of the exception posted above):

                    dstManager.SetSharedComponentData(entity, new PhysicsWorldIndex());
drowsy pagoda
# rustic rain get all data you need before the job

OMG, what a noob mistake! Yeah I collected the data beforehand now the error went away. But now I'm facing: : The previously scheduled job Broadphase:PrepareStaticBodyDataJob reads from the Unity.Collections.NativeArray1[Unity.Physics.RigidBody] PrepareStaticBodyDataJob.RigidBodies. You are trying to schedule a new job GameBoardSystem:GameBoardSystem_LambdaJob_2_Job, which writes to the same Unity.Collections.NativeArray1[Unity.Physics.RigidBody] (via GameBoardSystem_LambdaJob_2_Job.JobData.physicsWorld.CollisionWorld.m_Bodies). To guarantee safety, you must include Broadphase:PrepareStaticBodyDataJob as a dependency of the newly scheduled job.

Now I remember back in the 0.15 days that there was a way to inject Dependency into the PhysicsWorldSystem, how does that work now in v1?

misty wedge
#

If I use type punning for structs in C#, do I need to specify the struct layout, or can I rely on it being at the "beginning" of the struct as long as it is the first field in the struct?

covert lagoon
#

Whole code:

using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Rendering;
using Unity.Transforms;
using UnityEngine;

public class TerrainAuthoring : MonoBehaviour, IConvertGameObjectToEntity
{
    private const int SizeX = 128;
    private const int SizeY = 16;
    private const int SizeZ = 128;

    public UnityEngine.Material material;

    public void Convert(
        Entity entity,
        EntityManager dstManager,
        GameObjectConversionSystem conversionSystem
    )
    {
        var chunkArchetype = dstManager.CreateArchetype(
            typeof(LocalToWorld),
            typeof(Translation),
            typeof(Rotation),
            typeof(PhysicsCollider),
            typeof(PhysicsWorldIndex),
            typeof(TerrainChunkTag),
            typeof(TerrainChunkToGenerateTag),
            typeof(TerrainBlock)
        );

        for (var x = -SizeX / 2; x < SizeX / 2; x += TerrainChunkTag.SizeX)
        {
            for (var z = -SizeZ / 2; z < SizeZ / 2; z += TerrainChunkTag.SizeZ)
            {
                for (var y = 0; y < SizeY; y += TerrainChunkTag.SizeY)
                {
                    var chunkEntity = dstManager.CreateEntity(chunkArchetype);

                    dstManager.SetComponentData(chunkEntity, new Translation
                    {
                        Value = new float3(x, y, z),
                    });
                    dstManager.SetComponentData(chunkEntity, new PhysicsCollider
                    {
                        Value = BlobAssetReference<Unity.Physics.Collider>.Null,
                    });
                    dstManager.SetSharedComponentData(entity, new PhysicsWorldIndex());

                    var renderMeshDesc = new RenderMeshDescription(new Mesh(), material);
                    RenderMeshUtility.AddComponents(chunkEntity, dstManager, renderMeshDesc);
                }
            }
        }
    }
}
drowsy pagoda
#

Oof. Thanks anyway.

misty wedge
rotund token
covert lagoon
#

I'm going to go sleep

#

I can't even properly come up with sentences anymore

#

Holy shit it works

#

Obviously I don't get that error anymore

#

But most importantly, the player no longer falls through the terrain

wraith urchin
#

I having this weird behiavor, i have a system JumpSystem thats use PhysicsVelocityExtension ApplyLinearImpulse to make my player Jump, thats works well, but i have another system MoveSystem that moves the player in Input.Axis direction using Translation += dir * speed * deltaTime.
So apparently modify Translation directly makes PhysicsVelocity Component go crazy , i mean , jump just work fine its update my physics.velocity.Linear.y axis , but when i move its also updating all of my physics.velocity.Linear axis , and the angular two . Are this behavior expected ? 😦 Maybe my move system need to update velocity.Linear axis and not to use translation at all ?

misty wedge
#

Is there a reason you aren't using the physics system for all movement?

#

What I'm getting at is that modifying translation directly circumvents the physics system, and can have weird behaviour.

#

If you really want physics based movement (and not a character controller), I would use the physics system for all movement. I've not written a movement system in DOTS yet though, so maybe others will have more insight.

wraith urchin
#

There is no reason , i'm trying to make my own ThirdPersonController from scratch

wraith urchin
rustic rain
#

Is there a way to change Group for Unity's system?

#

I want to drop it into my own group

misty wedge
#

You can write custom bootstrapping to set up your own update groups

rustic rain
#

I do have them

#

but I want to throw Unity system

#

into it

misty wedge
#

What do you mean by "Unity System"? Things like SimulationSystemGroup?

rustic rain
#

not group

drowsy pagoda
#

If anyone is savvy with ECS Physics. Please help me figure this out: InvalidOperationException: The previously scheduled job Broadphase:PrepareStaticBodyDataJob reads from the Unity.Collections.NativeArray1[Unity.Physics.RigidBody] PrepareStaticBodyDataJob.RigidBodies. You are trying to schedule a new job GameBoardSystem:GameBoardSystem_LambdaJob_2_Job, which writes to the same Unity.Collections.NativeArray1[Unity.Physics.RigidBody] (via GameBoardSystem_LambdaJob_2_Job.JobData.collisionWorld.m_Bodies). To guarantee safety, you must include Broadphase:PrepareStaticBodyDataJob as a dependency of the newly scheduled job.

I tried _buildPhysicsWorld.RegisterPhysicsRuntimeSystemReadWrite() in OnStartRunning()

And I also tried adding _buildPhysicsWorld.AddInputDependencyToComplete(Dependency); in OnUpdate(). Both have failed.

The only Physics related thing I am doing in OnUpdate() is collisionWorld.CalculateDistance(queryInput, out var hit)

How can I prevent this conflict?

rustic rain
#

CompanionGameObjectUpdateSystem
I want this to update inside my group (since, doing it every frame is useless)

rustic rain
drowsy pagoda
#

How do I get that JobHandle?

rustic rain
#

find that JobHandle and just combine with your dependency

#

it's probably a field

drowsy pagoda
#

Woah, I just passed _stepPhysicsWorld.FinalSimulationJobHandle into the Schedule and it worked!

misty wedge
rustic rain
#

hmm

misty wedge
#

Just make sure to remove it from the system it's currently in. Otherwise I think it's updated twice.

rustic rain
#

yeah, already testing

#

huh, seems like it worked

#

thanks

pliant pike
#

weird question but is it possible to create an OnEnable() method of a gameobject in a Systembase

drowsy pagoda
#

Is there a way to make this Burst Compatible? Or System.Func is just not allowed?

private static bool VerifyNeighbor(DynamicBuffer<NumTacElement> numTacElements, int index, 
            int targetIndex, Func<int, int> next)
misty wedge
misty wedge
rustic rain
#

you are litreally limited to primitives

#

kek

drowsy pagoda
#

Ah. No equivalents for that I pressume?

rustic rain
pliant pike
misty wedge
rustic rain
misty wedge
#

I would say that's quite a bit different than a function pointer 😅

pliant pike
drowsy pagoda
misty wedge
#

Make sure to read the caveats / limitations though.

drowsy pagoda
#

Shit, I only need it to increment an int in certain steps (depending on circumstance). So it's as simple as i => ++i or i => i-9.

#

Maybe I should just hard code it and call it a day? lol

rustic rain
#

xD

#

but actually

#

in terms of ECS

#

you are supposed to go away from OOP constraints

#

They are not supposed to work in ECS

misty wedge
#

Things like DRY still apply though, and is harder to achieve in DOTS compared to monobehaviors imo

#

That's why things like burstable function pointers can still be useful. Also the library you posted (polymorphism) is a huge hallmark of OOP. It can still be useful in data oriented design.

drowsy pagoda
#

lol

#

Oh but function pointers require you define the actual operation ahead of time instead of from within code. It would be easier for me to hard code them because of their simplicity. Seems I just have to accept that this is an ECS limitation.

misty wedge
#

The reason they need to be defined beforehand is because burst needs to synchronously compile when you create a build.

misty wedge
drowsy pagoda
#

Yeah

misty wedge
#

They basically function like non-capturing lambdas

drowsy pagoda
#

I understand.

#

Thanks for that, saved that in my favorites.

#

Well, that's it for me today. I was able to convert to Schedule and fix all the errors. Thank you guys for your help and guidance. Take care 😉

haughty rampart
#

that's exactly the opposite of how you should think for ecs

rustic rain
#

Do I understand correctly that it just creates struct type based of index and then just runs it's method?

misty wedge
haughty rampart
misty wedge
misty wedge
haughty rampart
#

wdym exactly?

misty wedge
#

For example, you have a component that contains some type of struct, but the components all need to be handled in some similar way, but their data differs

#

And the data is variably sized

#

(basically polymorphism)

haughty rampart
#

??? if they all contain the same 'some kind of struct' and need to be handled similarily, then where's the problem?

misty wedge
#

Say you have 3 different types of structs, and this component needs to store all 3 different types, but only one at a time

haughty rampart
#

yeah?

misty wedge
#

How would you put that in a component?

haughty rampart
#

discriminated union

misty wedge
#

That's pretty much what the asset posted does

#

Except it uses source generators

haughty rampart
#

it puts logic on components

misty wedge
#

His example does, the asset doesn't

#

You can just pass the "correct" type to a function in a system that then handles it

#

The actual use is the automatic generation of the correctly sized union

haughty rampart
#

that would be ok. but don't put LOGIC on components

misty wedge
#

That's literally the first thing I said

haughty rampart
#

that wasn't explicit enough for me tbh. 'i personally wouldn't' -> no! you should NEVER put logic on components. personally or not
XD

misty wedge
#

That's your opinion. People are free to do whatever they want 🤷

haughty rampart
#

and write bad code in the process

rotund token
#

hear me out. what if we put logic on components but make them classes and rename them monobehaviours?!
and instead of entities we call them gameobjects.

misty wedge
#

Blasphemy.

misty wedge
#

That's why I found it funny that enzi found it interesting how phil thought (putting logic in components). It's OOP with extra steps

rustic rain
#

I just think of it of a way to implement OOP inside ECS

#

kek

#

has it's niche case, but I just don't see it

haughty rampart
#

i've written an analyzer that bans any use of non-data-oriented-aspects in ecs

rustic rain
#

wha

haughty rampart
#

for example methods in components

misty wedge
#

How would you handle commonly required operations? e.g. many systems in a game need to equip / unequip items from entities or something. Store the function statically somewhere and call it in a system? Create entities and a reactive system? Use some other communication method like native streams?

misty wedge
# haughty rampart exactly

I think for a lot of people there isn't a huge difference between having the function live somewhere statically vs storing it in the component

haughty rampart
#

and if there's no difference, then why not just always make it static

misty wedge
#

I'm not super well versed in this. What makes it bad performance wise? Branch prediction / caching?

haughty rampart
#

you SEPERATE data and logic

misty wedge
#

So a design issue, not a "program" issue

haughty rampart
#

both

misty wedge
#

What makes it worse performance wise?

haughty rampart
#

it captures this, the address may be moved around and other little things.
but primarily it's just not how DDD is to be approached

covert lagoon
#

I forgot how to add angular axis constraints to physics bodies again

rotund token
misty wedge
#

I've never really thought about performance considerations, I just never do it because of

it's how data-oriented-design works

haughty rampart
#

@misty wedge also, many programming languages do not allow methods in structs, only in classes. c# is very lightweighton that

misty wedge
#

Does C disallow methods in structs? I've never tried

covert lagoon
#

C++ does not disallow methods in structs

#

As far as I know, the only difference between structs and classes in C++ is the default member visibility

#

Struct members are public by default whereas class members are private by default

haughty rampart
#

in c++ there really is not even a difference between struct and class, since any can be allocated on stack or heap regardless

covert lagoon
#

How do I disable angular velocity for a physics body, aaaaaaaaa

#

Right now I have this:

    public void Convert(
        Entity entity,
        EntityManager dstManager,
        GameObjectConversionSystem conversionSystem
    )
    {
        dstManager.AddComponents(entity, new ComponentTypes(
            typeof(PhysicsJoint),
            typeof(PlayerControllerTag),
            typeof(PlayerInput)
        ));
        dstManager.AddComponentObject(entity, camera);
        dstManager.SetComponentData(entity, PhysicsJoint.CreateLimitedDOF(
            RigidTransform.identity,
            new bool3(false),
            new bool3(true)
        ));
    }
#

The GameObject being converted already has the PhysicsBody and PhysicsShape authoring components

#

I can move the entity by changing its velocity just fine but it keeps rolling over

misty wedge
haughty rampart
covert lagoon
haughty rampart
#

so it does make sense

misty wedge
covert lagoon
#

The non-DOTS way would just be to tick a few boxes under the Rigidbody component in the inspector

haughty rampart
haughty rampart
#

then use that?

covert lagoon
#

But I forgot how to use it properly

#

The code I currently have doesn't work

haughty rampart
#

but that applies to joints?

coarse turtle
rustic rain
#

static methods are faster, but REAAALLY slightly

#

allthough it wasn't tested in ECS, so can't know for sure regarding our use case

haughty rampart
#

i am 99% certain it won't really change with ecs

coarse turtle
#

im too lazy to profile and find out how much overhead a method in an instance has compared to a static method 😅

haughty rampart
#

just don't do methods on components. the design aspect doesn't change either way

covert lagoon
#

Why don't we have more documentation

haughty rampart
#

for what?

covert lagoon
#

Everything DOTS

misty wedge
#

Why does it use the virtual method table though? The method isn't virtual

covert lagoon
#

I just want to contrain angular velocity axises

haughty rampart
haughty rampart
covert lagoon
#

How

#

I'm sure I've seen it a while ago

haughty rampart
#

what you linked is for JOINTS

covert lagoon
#

I am 99% sure I saw something doing this by creating a joint where entity A is the entity we want to constrain and entity B is the null entity

#

But now I'm reading the documentation for PhysicsJoint.CreateLimitedDOF which I also remember seeing a while ago, and it already creates a joint by itself

coarse turtle
# misty wedge Why does it use the virtual method table though? The method isn't virtual

Haven't looked too deeply into vtables & c# but i think it might be by design. For instance you could do something like this:

    public class A {

        public void Foo() {
        }
    }

    public class B : A {
        public new void Foo() {
        }
    }

It's not marked virtual, but because B is derivative of A, you will need a vtable in order to bind new void Foo() with B such that you can call bInstance.Foo().

misty wedge
#

That makes sense to me, but structs can't inherit from anything.

coarse turtle
#

true

#

i haven't looked into how the sealed keywords works on the il level to say anything else on this

covert lagoon
#

build
Unity crashes

misty wedge
#

Can you store a BlobAssetReference inside a struct that is referenced by a BlobAssetReference?

#

I guess it would only be an issue when trying to serialize the BlobAssetReference...

covert lagoon
misty wedge
covert lagoon
misty wedge
#

If I pass a struct to a function with in, is the struct copied if I call a method on it?

rustic rain
#

in means it will be passed by reference

misty wedge
#

I'm wondering because of this rider message

muted field
#

why does calling complete straight away make jobs run on main thread - why not still run on other threads but lock the main thread and wait until they are done, you lose the parallel work when needing it done straight away which is silly

misty wedge
#

Are you sure they're run on the main thread?

muted field
#

yeah mine is running on main at the moment

misty wedge
#

Do you have a profiler screenshot?

muted field
#

sure one sec

rustic rain
muted field
#

not sure what you mean by that

rustic rain
#

worker threads only steal jobs if there's enough of it

muted field
#

enough of what though?

rustic rain
#

of jobs

muted field
#

well im calling 4 jobs straight away in a forloop on the main thread so it should take some

misty wedge
#

What he means is that the batch amount needs to be large enough so that the work can actually be scheduled to multiple threads

#

So if you scheduleparallel with a batch size of 32, but only pass a list that is 10 long, it will run on a single thread

muted field
#

this is how i call them:

            while (segments.MoveNext())
            {
                NativeHashSet<Path2> closed = new NativeHashSet<Path2>(8, Allocator.TempJob);
                NativeList<Path2> currentPath = new NativeList<Path2>(8, Allocator.TempJob);

                GetCycles2 job = new(path, data, closed, currentPath);
                var jh = job.Schedule();
                jh.Complete();
                HandleData(currentPath);
                closed.Dispose();
                currentPath.Dispose();
            }
rustic rain
#

well

#

you literally schedule them one after another

muted field
#

in total im calling 6 jobs

misty wedge
#

Yes, but you are forcing a complete before you schedule the next one

rustic rain
#

calling them to complete before you schedule next

#

lol

misty wedge
#

You need to combine the handles, and then call complete on the combined handles

muted field
#

oh i see

#

that might be difficult

#

how would i get all the results back

#

since my native containers are made in the loop with them =/

misty wedge
#

I think you could just keep track of the job structs in a list or something? The reference to your containers should still be correct

rustic rain
#

what are you doing with HandleData?

muted field
#

converting the path to managed array

#

to send back to a mono

rustic rain
#

hm, is it possible to keep NativeContainer pointer in NativeContainer?

#

if it is

#

you can just make a list of lsits

#

and then unpack it once job is done

muted field
#

oh maybe

rustic rain
#

but actual list of lists is not possbile

#

in native containers

muted field
#

true and it would need parallel writing and that doesn't allow resize

rustic rain
#

gotta figure out a hacky way to achieve this behaviour

#

hm

#

Maybe

misty wedge
#

So maybe something along the lines of:

var list = new List<GetCyclesJob2>();
var handle = Dependency;
while (segments.MoveNext())
{
    NativeHashSet<Path2> closed = new NativeHashSet<Path2>(8, Allocator.TempJob);
    NativeList<Path2> currentPath = new NativeList<Path2>(8, Allocator.TempJob);

    GetCycles2 job = new GetCycles2(path, data, closed, currentPath);
  list.Add(job);
var jh = job.Schedule();
closed.Dispose(jh);
    handle = JobHandle.CombineDependencies(jh);
}
handle.Complete();
foreach (var job in list)
{
    HandleData(job.currentPath);
    job.currentPath.Dispose();
}
rustic rain
#

save them to HasHmap?

#

is it possible?

#

oh yeah

#

this also works

#

you can actually use

muted field
rustic rain
#

DeallocateOnComplete attribute as well

misty wedge
muted field
#

oh it doesnt immediately dispose?

misty wedge
#

Not if you pass a JobHandle

#

It's an overload

muted field
#

i see

rustic rain
#

ngl tho, unless your jobs are really huge

#

I'd suggest combining them all to 1

#

Scheduling is costly

#

while burst makes even large jobs really fast

muted field
#

if i combine there is still the issue of getting all the data back correctly

#

pardon the pun

#

😄

rustic rain
#

judging by unity forum

#

you can store NativeArray as value through pointer in HashMap

muted field
#

what does that mean

rustic rain
#

that means you will create list of lists in a job

muted field
#

so NativeHashSet<NativeList<Node>> ?

rustic rain
#

NativeHashMap

#

allthough

#

maybe Set is fine

#

I'm not really familiar with them all

#

kek

#

I guess it is fine

#

but it'll be a pointer

#

doubt it'll allow you storing List itself

misty wedge
#

You'd need to store an IntPtr, as you can't directly store type pointers in collections. At that point you might as well just use UnsafeList though...

muted field
#

so NativeList<UnsafeList<Node>> ?

#

though i still have the issue of parallel writing

#

it doesn't allow list resizing

misty wedge
#

It probably needs to be UnsafeList<UnsafeList<Node>>

#

And if you want to write to the same list in parallel, you would need to grab an UnsafeList.ParallelWriter

#

(and like you said, this will not auto resize)

covert lagoon
#

Unused
0 B
Is the archetype chunk utilization of my terrain chunk entities perfect?

muted field
viral sonnet
#

other than SCD can I save a class (MB comp) in an IComp without making a mess with archetypes?

rotund token
#

use a class IComp?

#

or just save the class directly on the entity

viral sonnet
#

I don't want to affect my main entity archetype. class sounds like a good solution, never tried this or ever written one 😄

rotund token
#

class icomp and storing it on the entity directly basically do the same thing

#

just adding an extra step unless your class icomp has something else on it

viral sonnet
#

i should look at the source code how unity adds MBs to entities. maybe I find out how to get the ptr then

#

it's for a mapping system and I want to use NativeHashMap instead of Dictionary so I can call add/remove methods from burst

covert lagoon
#

Aren't you supposed to use EntityManager.AddComponentObject?

viral sonnet
#

so saving it on an entity is more or less a last resort

muted field
#

i just realisd parallel jobs using indices makes the use of iterating a multi hash map impossible -_- how annoying

haughty rampart
# covert lagoon 👍

You cannot use the build settings to build your project. How long will people keep doing this???

viral sonnet
#

Does somebody have experience what's faster for setting transform position/rotation: iterating transform on an entity or TransformAccessArray. Currently I have a TAA solution but that has its downsides

#

Uhm, has anyone checked this? Child is not part of the archetype in the archetype window? How's that?

viral sonnet
#

well, I dunno. the archetype window seems buggy. it doesn' show some buffers. IComps seem okay.

#

and WTH, I never realized that an endless combination of archetypes is built in the conversion stage which can be viewed with "show empty archetypes"

covert lagoon
#

It worked the second time

haughty rampart
#

It's still wrong

covert lagoon
#

Do you want me to use Build Settings assets?

haughty rampart
#

You need to use the build configuration asset

covert lagoon
#

I think I'll need to use that when adding the NetCode for Entities package

haughty rampart
#

You always need it

covert lagoon
#

Why?

haughty rampart
#

Because it says so

covert lagoon
#

Who's "it"

haughty rampart
#

Unity

#

/ documentation

viral sonnet
#

normal build won't serialize subscenes. that's one of the major things why to use build conf, because there you can explicitly reference the subscenes

haughty rampart
#

Also the asset is just .much much nicer

covert lagoon
#

So subscenes won't be loaded?

viral sonnet
#

not even exported. files are missing if you want to load them

covert lagoon
#

Yeah

viral sonnet
#

so, right now my conclusion is: archetype window doesn't show more than 31 components

viral sonnet
#

any idea to handle entity references like target gracefully when the target entity is destroyed. having to check for entity exists kind of suck :/

rotund token
#

my current idea is simply to only have 1 target component (or a buffer if i need multiple targets)

#

and then just validate it once start of every frame

#

alternatively, don't destroy your entities just disable them and clean them up later

#

and clean up the target in the AI with an is dead check or something which is pretty common in some path anyway

#

but yeah my design i'm going to try to go with is avoid HasComponent

#

and just code in a way to ensure state is valid

#

we have so many hascomponent checks in project at work and i feel there must be a better way

viral sonnet
#

Tough decisions, I wanted to avoid a structural change but my health comp has a HealthState.Dead enum anyway which I could use to avoid that but that's no good for entity query. Just destroying the entity is a bit forceful. Best thing I guess is to have a dedicated job at the beginning that checks for valid targets instead of having multiple checks all over jobs.

rotund token
#

something in your code needs to detect when target is dead/destroyed

#

because you have to react to that

#

may as well just do it once and ensure state

viral sonnet
#

very true, I only have 1 target comp so at least I don't have to iterate over several entity queries

#

thing is target is not my only reference. I create a small archetype for path finding requests that has an Icomp and a buffer which another job iterates to walk the path from the buffer. I thought about adding this as LinkedEntityGroup to the main entity but then another buffer on the main entity ... ugh

#

until entities dying I had no HasComponent ... haha

#

i think i'll build a NMHM for this. I hate data like childs, parents, linkedentitygroup and other useless shit to be in a chunk

#

and have a seperate method that basically overrides commandBuffer.DestroyEntity

#

I also hope Unity redesigns this. It's just lazy of them to put everything in as buffer and IComps for something so essential

#

like what do they expect? simd code for linkedEntityGroup? lol

#

With jobs like these I'm also struggling to handle the chunk version. Just getting the write handle increases the version number but if everything runs smooth there's no actual write

rotund token
#

well yeah, if you're using change filtering you can only use ComponentDataFromEntity and CommandBuffers to set the value

viral sonnet
#

Yeah, that would not be worth it I believe.

#

Then I rather abuse the pointer system and get a sneaky RO ... hehe - not that I would ever doing something this dirty

drowsy pagoda
#

What are some best practices when I have situations with cross-scene referencing? Like on ECS sub-scene I have authoring GO and I want to associate a non-ECS side UI GO.

drowsy pagoda
#

Well I have a game board type of deal. And a UI button that when pressed will set a flag (via BlobAssetReference) that the game board on ECS side will pick up and perform the specific action and reset the flag. But the Game UI canvas sits outside the ECS subscene.

#

All I need is for the game board authoring to be aware of the UI and just copy the BAR to its data component during conversion.

rustic rain
drowsy pagoda
#

That’s alright, don’t worry about it. I guess I just can’t explain it right.

rustic rain
#

oh

#

are you trying to create a Unity Component reference as a component?

muted field
#

is it possible to add an interface to a job besides the Ijob ones so i can put jobs into a regular list with polymorphism. sadly ijob and ijobfor etc dont share a base interface -_-

solemn hollow
#

hmm you could maybe work with wrappers around the job that share the same interface.

solemn hollow
#

Btw Blobassets are not supposed to be used for changing data.

muted field
#

would this be a reliable way to know when all jobs are complete:

            int jobCount = 0;
            void OnCyclesComplete(GetCycles2 job)
            {
                Debug.Log("Path Found");
                for (int i = 0; i < job.Path.Length; i++)
                    Debug.Log(job.Path[i].NodeA);

                job.Dispose();
                jobCount--;
                if (jobCount == 0) // is this a safe bet?
                    _callBack?.Invoke();
            }

            var segments = data.GetValuesForKey(n);

            while (segments.MoveNext())
            {
                var s = segments.Current;
                var closed = new NativeHashSet<Path2>(8, Allocator.TempJob);
                var cycle = new NativeList<Path2>(8, Allocator.TempJob);
                var job = new GetCycles2(new Path2(s), data, closed, cycle);
                JobController.Instance.Add(ref job, OnCyclesComplete);
                jobCount++;
            }
#

god damn it , it wont let me parallel read from a multi hash map wtf

#

why is reading from these containers restricted so much if its read only

rotund token
#

you can parallel read from hash map

#

if you mark it readonly

muted field
#

i did

#

still does it tho

rotund token
#

are you reading it while it's being used on main thread?

#

because it definitely is fine to read in multiple threads

muted field
#

oh i think i know what it is. im disposing it when the first job's callback occurs

#

but other jobs are still running

#

ok my counter system did the trick to solve that problem

muted field
#

does profiler have a search box

#

i can never find the jobs 😄

#

it happens so fast im probably not even near the frame it occured in

#

ah i found them at last

solemn hollow
#

guys is the entity inspector actually bumping the changeversion of components??? I have a system that usually only runs after a certain playerinput once. if i open the entity inspector it triggers every frame

rotund token
#

possible since you can change entity data in inspector

#

seems wrong though

solemn hollow
#

So maybe this is only in live edit mode then?

#

ill try what happens with closed subscene. but even in live edit i would consider that a bug

solemn hollow
#

I am still trying to figure out sensible pattern to use changefilter...

viral sonnet
#

nothing changes the version when you read

solemn hollow
#

hm yes i worded that badly sry. i meant if i declare write access on a CDFE and then not actually access an entity nothing happens?

viral sonnet
#

what tertle meant was that CDFE does only bump the version for chunks you are writing to while a write handle changes every version of a chunk

solemn hollow
#

yes thats what i was asking basically. so if i want to use changefilter and have a low amount of writes anyway CDFE seems good

viral sonnet
#

a pain I'm dealing with 🙂 but CDFE is not a good option for my case

#

yes, more or less your only option. command buffer is another, although I'd just write to the CDFE, especially when it's not involved in a race condition anyway

#

CDFE is much faster than one would expect. at least I'm always underestimating it

#

mostly because it has good caching. a write is still a write and no matter what, always somewhat expensive

#

so if you are using change filtering/DidChange it's a good solution to circumvent the global write handle problem

solemn hollow
#

What is actually the problem with only bumping the changeversion on a chunk where an actual write occured? is it that much more expensive to check?

#

Thinking about it myself i guess it would be alot more expensive. but so much more convienient too 😦

viral sonnet
#

the problem is with write handles like var targetInfos = chunk.GetNativeArray(TargetInfo_WriteHandle); it doesn't matter if you actually write something back. just acquiring the handle will bump up the chunk version so a DidChange will occur even when there was none

#

so other systems that also rely on DidChange will have true because the whole chunk got bumped

#

basically, if you have one write handle DidChange will always be true

solemn hollow
#

yep. my question was why the bumping of the changeversion needed to be at that step and not later when i actually write. but that would need some form of indirect access to the data then

viral sonnet
#

yeah, some form of code-gened lazy loading would be great. maybe that will come at some point

solemn hollow
#

id like to have manual control over it if needed.

viral sonnet
#

I do hope so because it's very difficult to get DidChange work correctly

solemn hollow
#

changefilters would be super powerful but atm it requires so many sacrifices

viral sonnet
#

preferably, yes. that's why DreamingImLatios is suggesting manual tracking of SystemVersion and utilizing ChunkComponents for it

#

I have not really understood the manual tracking though

solemn hollow
#

yes that works if the system runs anyway. but if i want the system to run once every X seconds because of some event then i dont want to manually poll the changeversion

#

Preferably id like to skip the whole systemupdate

#

In one of my cases its userinput that triggers a chain of events that only need to be processed exactly once. this will happen very rarely

rotund token
#

i use system groups for this

#

just put a collection of systems in a group that only needs to run on a condition then put the condition in that actual system group

#

to determine if it should update

#

i use this for things like, ghosts spawning on client to set them up

solemn hollow
rotund token
#

definitely a pain because it'd trigger a constant navmesh rebuild for me

solemn hollow
#

it ofc only happens if you inspect the entity with the component you are changefiltering for. so just dont inspect the wrong entities then xD

#

means i cant inspect my units anymore lol.

solemn hollow
rotund token
#

but it sounds like nothing should execute unless you have user input?

solemn hollow
#

some of the systems also execute when ai is deciding something

#

its a weird case. i see your point with the systemgroup. ill think about whether i can restructure the architecture a bit

rotund token
#

its a useful pattern for improving performance a bit

#

rather than a lot of systems having to constantly check their queries if they should run etc

#

just hide it behind 1 check

solemn hollow
#

thats really good for userinput stuff for sure. atm i am polling way too much

#

Ill write a Bug Post on Forum

rustic rain
#

Is there any reason to use byte over int?

#

if I know for sure, I'll never go above above 250

viral sonnet
#

sure it's 1 byte instead of 4

hot basin
#

is storing a method inside a field in the struct and then using it inside a job a good idea?

rustic rain
#

it's against ECS design

minor sapphire
#

If you need to calculate X based on Y and Z and they all make sense as members of the component, there is no problem that I'm aware of with X being a member of the component as a property. If you need a method because you need to pass something in from outside the component then it's worth reconsidering.

viral sonnet
rotund token
#

i would argue having logic on components probably goes against pure ecs ideas and generally should be avoided
however there are certainly case where properties/methods on components are useful and quite helpful especially if they are used to present the data that exists on the component .e.g CalculatePercentageHealth() => Health / MaxHealth;

If I had to simply this as a rule I'd say, avoid any method that requires external data. If the method can work with only the data on the component then it's probably 'fine'.

that said, blindly following rules and patterns is dumb and there are always exceptions. make up your own mind and use whatever solution fits your problem the best.

viral sonnet
#

unity even builds a dedicated feature with IAspect for it which is this idea on crack

#

as long as it's shaping a better code architecture that's easy to understand, maintain and extend everything is allowed. ecs has no real pattern or design to speak of.

minor sapphire
#

Enzi bro what are you working on

cerulean pulsar
#

How to make one entity the parent of another at runtime? When I add the Parent component to the child before adding LocalToParent, it says I need LocalToParent. When I add LocalToParent to the child before Parent, it says I need Parent

haughty rampart
haughty rampart
rustic rain
#

@rotund token sir, smth wrong with your algorithm of entity selection

#
                var colors = new UnsafeList<Color32>(batchInChunk.Count, Allocator.Persistent);
                var transforms = new UnsafeList<Matrix4x4>(batchInChunk.Count, Allocator.Persistent);

                var entities = batchInChunk.GetNativeArray(EntityType);
                var localToWorlds = batchInChunk.GetNativeArray(LocalToWorldType);
                var mesh = batchInChunk.GetSharedComponentIndex(RenderMeshType);

                for (var index = 0; index < entities.Length; index++)
                {
                    var ind = entities[index].Index;
                    colors.AddNoResize(IndexToColor(ind));
                }

                transforms.AddRange(localToWorlds.GetUnsafeReadOnlyPtr(), localToWorlds.Length);
                Map.AddBatchUnsafe((Color*) colors.Ptr, (Entity*) entities.GetUnsafeReadOnlyPtr(), entities.Length);

same code, I didn't change anything

#

yet Map seems really off

#

oh wait

#

I did change it from Vector4

rotund token
#

check the creation of the render texture

#

in my code vs your code

#

because of the previous mentioned issue of renderbatched vs rendermesh calls using different color space

#

it's setup very specifically

#

oh just looked at your screenshot

#

yeah that's just wrong it definitely creates the colours fine

rustic rain
#
        private void UpdateCamera()
        {
            _renderTexture = RenderTexture.GetTemporary(
                _camera.pixelWidth,
                _camera.pixelHeight,
                24,
                RenderTextureFormat.Default,
                RenderTextureReadWrite.Linear);
            _renderTexture.antiAliasing = 1;
            _renderTexture.filterMode = FilterMode.Point;
            _renderTexture.autoGenerateMips = false;
        }
#

it was always off for some reason

rotund token
#

the values in your hashmap are just garbage

rustic rain
#

I managed to fix it a bit by removing all bounds checks (no idea how it fixed anything), but then after bringing them back

#

I keep fighting this issue

rotund token
#

have you break pointed on your colors array before merging it to the hashmap
Map.AddBatchUnsafe((Color*) colors.Ptr, (Entity*) entities.GetUnsafeReadOnlyPtr(), entities.Length);

rustic rain
#

hm

#

conversion fault?

rotund token
#

well yes

#

you're storing it as Color32

#

that's not a float

#

thats 4x bytes

#

no where are you converting the bytes to floats

rustic rain
#

you were storing it as Color

#

xD

rotund token
#

and that's why

rustic rain
#

but I changed it

#

to Vector4

#

screenshots

#

are with Vector4

rotund token
#

you're not converting it though

#

your hashmap is Color, Entity

#

but no where are you converting Color32 to Color

#

you have remapped the byte memory into float memory

#

and it produces the above garbage

rustic rain
#
        private static Color IndexToColor(int index)
        {
            var r = (float) (index & 0xFF);
            var g = (float) ((index >> 8) & 0xFF);
            var b = (float) ((index >> 16) & 0xFF);
            var a = (float) (255 - (index >> 24));
            return new Color(r, g, b, a);
        }
#

will that do?

rotund token
#

no because that will be wrong color

#

that will be 255x higher

#

color is 0-1

#

you're passing in 0-255

rustic rain
#

I'm confused

#
        private static Color IndexToColor(int index)
        {
            var r = (byte) (index & 0xFF);
            var g = (byte) ((index >> 8) & 0xFF);
            var b = (byte) ((index >> 16) & 0xFF);
            var a = (byte) (255 - (index >> 24));
            return new Color32(r, g, b, a);
        }

Here's your original

rotund token
#

yes

#

new Color32(r, g, b, a);

#

thats in byte format

#

it hten implicit casts to Color

#

which is really just /255f

rustic rain
#

so I'm still confused

#

everything is like your code rn

rotund token
#

your IndexToColor is not the same as mine

rustic rain
#
        private static Color IndexToColor(int index)
        {
            var r = (byte)(index & 0xFF);
            var g = (byte)((index >> 8) & 0xFF);
            var b = (byte)((index >> 16) & 0xFF);
            var a = (byte)(255 - (index >> 24)); // flip the A just to make it easier to read since it'll likely never be used anyway
            return new Color32(r, g, b, a);
        }
#

it is from your file

#

I used it the whole time

rotund token
#

var colors = new UnsafeList<Color32>(batchInChunk.Count, Allocator.Persistent);

#

your colors list is Color32 though

rustic rain
#

I changed it to Vector4

#

before I made 2 sceenshots

rotund token
#

sorry wait, your new screenshots looks fine though?

#

(im not paying that much attention atm... new poe league ^_^")

rustic rain
#

So, this is player entity

#

from what I see, color is different

half jay
#

is it possible to set material to RenderMesh in Burstable system?

rustic rain
#

no

#

both are managed components

rustic rain
#
        private Color GetColorAtMousePos(Vector2 curPos)
        {
            RenderTexture.active = _renderTexture;

            Rect rect = new Rect(curPos.x, curPos.y, 1, 1);

            // Rect rect = new Rect(curPos.x, curPos.y, 1, 1);
            _pixelTexture.ReadPixels(rect, 0, 0);
            _pixelTexture.Apply();
            RenderTexture.active = null;
            RenderTexture.ReleaseTemporary(_renderTexture);

            return _pixelTexture.GetPixel(0, 0);
        }

am I doing smth wrong?

#

why color is incorrect?

#

oh wait, maybe height is inverted

#

well, it works when there's just 2 entities

#

but when I added 8

#

it doesn't

#

now colour is wrong again

#

sooo, it feels like it draws only 1 mesh during instanced call

rotund token
#

not sure what's up sorry

#

i tested it with quite a few instances and it seemed to work fine

rustic rain
#

it is indeed only drawing 1st entity

#

instead 8

rotund token
#

hmm ok did some investigation

#

i can kind of repo something but it's late and i need to sleep so i haven't figured out what part is broken

#

but it's definitely not just drawing 1 (at least for me)

rustic rain
#

ok, this is extremely weird

#

after some game time

#

it started to draw them

#

wtf

#

and for some reason now

#

it draws same instanced

#

several time

#

wait

#

now it creates 9 chunks, lol

#

to draw 9 entities

#

Color is fine though

#

smth about chunks creation

rotund token
#

i can definitely repo the missing stuff

#

so yeah will look at it tomorrow

#

need to sleep

#

@rustic rain if you want to solve it sooner i think it's the shader

rustic rain
#

yeah, it was indeed shader

#

but chunks creation is still messed up

#

it creates chunk for every entity

#

meanwhile chunk itself has length of all actual chunks

#

so it makes a draw call for array of 9, meanwhile there's only 1 valid matrix

hot basin
#

can I get link to the repo? I think I missed that one

rustic rain
hot basin
#

thanks!

#

I wonder, should I allocate and dispose of a list per system update, or should I cache it inside the system and reuse?

rustic rain
#

It is faulty tho

#

sir

#

but idk what's up with chunk creation

hot basin
#

what's the best job type for lists? IJobParallelFor needs length and for that I need to Complete() job that populate the list. Is there a way to do it smart or have I to use IJob and manually iterate inside?

rustic rain
#

for lists?

#

it'd require more details then that

hot basin
#

I have NativeList and I want to make a job that do some calculations on every element of that list

#

but the problem is, I populate it from another job so I don't know the size of this list to use IJobParallelFor when I schedule it

rustic rain
#

well, why not just do it on single thread?

coarse turtle
#

Try NativeList.AsDeferredJobArray() - its use case is that a list is populate by a prior job and then treated as a native array in the following job

hot basin
coarse turtle
#

not sure - havent tried that yet 🤔

hot basin
#

strange

#

IndexOutOfRangeException: Index 0 is out of range of '0' Length.

#

but i'm sure i'm adding something in previous job

covert lagoon
#

How can I see how much time a system takes to update in the standalone game?

hot basin
#

you can connect a profiler to your app

covert lagoon
hot basin
#

@coarse turtle is it a good setup? because it's still showing that array has 0 length

jobHandle = new JobDeffer{ array = array.AsDeferredJobArray() }.Schedule(
                    array ,
                    5,
                    jobHandle
                );
hot basin
#

there is even a standalone profiler now

covert lagoon
#

But I was told to use Build Configuration assets instead of the Build Settings window to build my game

#

Hopefully setting "Configuration" to "Develop" here will make it work

coarse turtle
hot basin
# coarse turtle yea looks right just from that snippet 🤔

before that I just do:

jobHandle = new JPF { writer = list.AsParallelWriter() }.Schedule(1, 5,  jobHandle);

which do:

public struct JPF : IJobParallelFor
    {
        [WriteOnly] public NativeList<TestStruct>.ParallelWriter writer;

        public void Execute(int i)
        {
            writer.AddNoResize(
                new TestStruct
                {
                    input = 0,
                    scale = 1,
                    shape = 1,
                    horizontalShift = 0,
                    verticalShift = 0,
                    value = 0
                }
            );
        }
    }
#

for testing purposes

coarse turtle
#

let me try something out

coarse turtle
#

iirc - you also might not be populating the list to the maximum capacity either right?

hot basin
#
var list = new NativeList<TestStruct>(10, Allocator.TempJob);
#

so both are "yes"?

coarse turtle
#

yea so i just tried that example, i guess with AsDeferredJobArray you'll need to keep the size consistent when you write & read. So if you intend to process 10 elements as a parallel writer - when you read as an array in the next job, you'll likely want to process the array w/ 10 elements. You'll also want to do an early out check if in the event you don't write which kind of seems like a waste to do in a job 🤔

hot basin
#

like wtf, so it seems useless job type

#

I can do it with standard IJobParallelFor if i've got max capacity

solemn hollow
#

btw IJobParallelFor is the old API. Its now IJobFor.ScheduleParallel()

covert lagoon
#

I'm making a game with Minecraft-like terrain but finite. Still, there are many terrain chunks and I don't want to regenerate the mesh for every single one there is to regenerate the mesh for in a single frame.
How can I update only a certain number of them at most per frame, especially since IJobEntity*s only accept EntityQuerys?

viral sonnet
#

@hot basin do you also use a IJobParallelForDefer job?

solemn hollow
#

if i need burst to recompile is it enough to clear the burst cache?

#

Burst is complaining about a generic job not beeing initialized correctly. even after i removed all generic stuff inside the job.

viral sonnet
#

best to just restart unity

hot basin
rustic rain
#

Oh man, feels bad I can't change SharedComponent through buffer

#

or maybe can I?

solemn hollow
#
public partial class EffectHandlerSys<T> : SystemBase where T : struct, IComponentData
{
    private EntityQuery updateEffectQuery;

    protected override void OnCreate()
    {
        updateEffectQuery = GetEntityQuery(ComponentType.ReadWrite<ActiveEffect>(),
            ComponentType.ReadOnly<EffectSettings>(),
            typeof(AttributeModifier<T>),
            ComponentType.ReadOnly<EffectModifier>());
    }
    protected override void OnUpdate()
    {
        var time = Time.ElapsedTime;

        Dependency = new UpdateEffectJob
        {
            time = time,
            activeEffectHandle = GetBufferTypeHandle<ActiveEffect>(),
            effectSettingsHandle = GetComponentTypeHandle<EffectSettings>(true),
            //targetModifierFromEntity = GetComponentDataFromEntity<AttributeModifier<T>>(),
            effectModifierHandle = GetComponentTypeHandle<EffectModifier>(true)
        }.Schedule(updateEffectQuery, Dependency);
    }
}```
#

im out of ideas. Burst always complaining about unresolved generics

#

But Burst should be able to resolve with this:
public class UpdateSpeedEffectSys : EffectHandlerSys<Speed>{}

#

Note that i dont even use any generics inside the job anymore. it has something to do with scheduling the job

#

Error msg : " Reflection data was not set up by an Initialize() call "

solemn hollow
#

Well i couldnt figure out what i was doing wrong with IJobChunk. Switched to manual chunk iteration with IJobFor and it works.

solemn hollow
#

so what do i have to register in the assembly then?

#

with IJobFor burst has no problems :S

rotund token
#

I already showed you how I do it

hot basin
#

@rotund token hi maybe you would know how to run 2 jobs, one that populate a NativeList and second one that use that list to do some calculations? (more on that above)

but TL:DR: I don't know how many elements there will be so I tried IJobParallelForDefer but it don't see the content of populated list

rotund token
#

Can you show code if your defer job

#

Did you use AsDeferredArray on your list

hot basin
hot basin
#

as for code of deffered job it have nothing but:

[BurstCompile]
    public struct JobDeffer : IJobParallelForDefer
    {
        public NativeArray<TestStruct> array;

        public void Execute(int i)
        {
            var element = array[i];
            array[i] = element;
        }
    }
#

as I strip down it to bare minimum to get it running first

rotund token
#

i take it 'array' on your scheduling is not an array, but a nativelist

solemn hollow
hot basin
#

I get IndexOutOfRangeException: Index 0 is out of range of '0' Length. on var element = array[i]; line

rotund token
#

ok so first thing i'm seeing

#

is you're populating an as parallel native list

#

asparallel native list can't resize, so either you know the size beforehand or just the max capacity?

rustic rain
#

I assume SharedComponentFilters only allow for WithAll setting? no excluding?

rotund token
#

@hot basin you're not still on 0.17 are you?

hot basin
#

I am

#

why?

rotund token
#

i feel like i remember an issue with the nativelist and parallel writer not being copied properly

hot basin
#

I changed it to IJobFor and used the list directly but result is the same

rotund token
#

kind of implies your original job is not writing anything
your original list has capacity right

rotund token
hot basin
#
var list = new NativeList<TestStruct>(10, Allocator.TempJob);
#
public struct JPF : IJobFor
    {
        [WriteOnly] public NativeList<TestStruct> writer;

        public void Execute(int i)
        {
            writer.Add(
                new TestStruct
                {
                    input = 0,
                    scale = 1,
                    shape = 1,
                    horizontalShift = 0,
                    verticalShift = 0,
                    value = 0
                }
            );
        }
    }
#
jobHandle = new JPF { writer = list }.Schedule(1, jobHandle);
jobHandle = new JobDeffer{ array = list.AsDeferredJobArray() }.Schedule(
                    list,
                    5,
                    jobHandle
                );
#

this is all I do

rotund token
#

hmmmm

#

array ,

#

why is that array

#

not list

#

what is array

hot basin
#

it's array as list.AsDeferredJobArray() returns array

solemn hollow
# rotund token nah that whole line there is the magic

thanks! i googled a bit and came across this: https://nagachiang.github.io/unity-dots-creating-generic-systems-with-generic-jobs/#
Sure its old but i thought the rules for burst havent changed much since then. Guess you shouldnt look at 1,5 yr old posts.

rotund token
#
                    array , // THIS HERE SHOULD BE list
                    5,
                    jobHandle
                );```
hot basin
#

oh yeah it is, sorry I'm editing it as we speak

rustic rain
#

I have this problem bothering me:
I need some kind of system to enable/disable rendering on entities based on where player's view at (at which room).
And all new entities coming/leaving room also need to get according treatment.

Rooms are sharedcomponent with only field - integer ID
So in best case scenario I'd simply just do:
AddComp<DisableRendering> to query of all sharedcomponents that aren't current room
And RemoveComp<DisableRendering> to query of shared components that is current room.

But here's the problem: shared comp filter has no excluding option. So one solution: I add this tag to literally all, and then remove it from current room entities. Every update.

I don't like this solution at all. Any other ideas to solve this?

rotund token
#

why not just keep a record somewhere of current visible room?

rustic rain
#

I do have a record of current visible room

rotund token
#

so when current room becomes not visible, just add the disable rendering component then?

rustic rain
#

it's just that entering/leaving entities or player who switches room through non-direct player action make things dirty

rotund token
#

so what?

rustic rain
#

so in order to do clean query

#

without adding unnecessary tags, that will be removed right after adding

#

I need to do query for every room

rotund token
#

no you don't?

rustic rain
#

how?

#
        public void SetRendering(InSystemComponent system)
        {
            EntityManager.AddComponent<DisableRendering>(_toDisableQuery);

            _toEnableQuery.SetSharedComponentFilter(system);
            EntityManager.RemoveComponent<DisableRendering>(_toEnableQuery);
        }

Here how I do it right now

rotund token
#

Query.SetSharedFilter(new room {Value = oldVisibleRoom})
Query.SetSharedFilter(new room {Value = newVisibleRoom})

#

why doesn't that work?

rustic rain
#

but there are 70 rooms

rotund token
#

yes but they're all previously invisible

rustic rain
#

ooooh

rotund token
#

you only need to change what was previously visible

rustic rain
#

that is smart

#

I didn't think of it

#

xD

#

well

#

actually, that's also has it's problem

#

entities are supposed to get created constantly

#

so new NPCs

#

come up

#

in different rooms

#

literally every second

rotund token
#

and when you create them you should set their initial state depending on their room

rustic rain
#

so it won't be fail proof

#

but it will be efficient

#

what about doing it dirty way

#
        public void SetRendering(InSystemComponent system)
        {
            EntityManager.AddComponent<DisableRendering>(_toDisableQuery);

            _toEnableQuery.SetSharedComponentFilter(system);
            EntityManager.RemoveComponent<DisableRendering>(_toEnableQuery);
        }
#

like this, every update

#

is it really that bad?

rotund token
#

depends if you are hitting something in the query

#

if the query is empty this basically just early outs

rustic rain
#

EntityManager.AddComponent<DisableRendering>(_toDisableQuery);
this is supposed to affect thousands

#

oh wait

#

more like

#

dozens

#

from 20 to 100 on average I'd say

#

and then I'll remove that tag

#

right after adding

#

every update

rotund token
#

100s of structural changes a frame doesn't sound great

solemn hollow
#

its not hundreds though since the whole chunk is changed at once. no copies. but not sure what the consequences are. profiling would be interesting i think

rustic rain
#

really wish, Unity would just make excluding filter option

hot basin
#

@rotund token so no luck with that defer job?

hot basin
rustic rain
#

yeah, but for shared component filter

rotund token
hot basin
#

i think i can't move to latest collections

rotund token
#

not suggesting you do

#

just suggesting you test to see if that's the issue

viral sonnet
#

anyone has a suggestion for handling entities that get very big or any insight how you are handling this? I currently have an entity that now gets a second collider, one for collision one for triggers (aggro radius) and I feel like it's getting all a little too big and it should be split.

solemn hollow
#

dont look at my entites. im happy if 3 fit into 1 chunk

rotund token
#

curious why you need a second collider - that doesn't sound like the performance king enzi i know

solemn hollow
#

if you have some sets of components that are completely orthogonal to each other it might be worth it to split those sets into entities and only have the one result that matters for your "main" entity written back. e.g. I could split my AI into a different brain entitiy that only communicates its decision to the "body" entity. im pretty sure in my case it would give me performance but at the cost of more abstraction

solemn hollow
rotund token
#

is it because you need different sizes?

solemn hollow
#

me or enzi? for me yes its about size. i havent compared to colliders performance wise

viral sonnet
#

yeah, different size. no that sounds like performance madness, I know. Thinking a lot about how to tackle this 😄

rotund token
#

are you relying on physics events?

viral sonnet
#

yeah, best case I'd just use dots physics

solemn hollow
#

I also have a way of just querying the entities close to the player. They get the "SLOD0" tag. then i can do a quick distance check to all of them without actually using physics.

viral sonnet
#

if it doesn't work out I'll write some small spatial hashing system for this.

#

@solemn hollow this checks every entity against each other?

solemn hollow
#

every entity on screen basically. and ofc you can filter for specific entities too then

#

There was a forum post where performance was profiled between actually using physics queries or just distance checking

viral sonnet
#

I heard good things about unitys BVH tree so I thought why not

solemn hollow
#

and only after a really huge number physics actually won i think

viral sonnet
#

huh interesting

solemn hollow
rotund token
#

for threat overlap spheres make more sense to me than colliders

viral sonnet
#

yep tertle, I think I'll do that instead. Also looking into just distance checking.

rotund token
#

if you're goal is 250k i don't think distance checking them all will work that well 😄

viral sonnet
#

yeah, that will be a bit too many

rotund token
#

but yeah i found you can do alternatives for nearest neighbour stuff than unity physics

viral sonnet
#

can you elaborate?

rotund token
#

well i think i've discussed my hash map solution previously

#

for my nearest neighbour calcs for my orca system

viral sonnet
#

ah right, ok 🙂

rotund token
#

unity used hashmaps as well similarly for their original nordeus demo

#

just 1 thing to be careful of i reckon is that you might be able to create a faster simulation/lookup code for a specific case, and you might be able to do this for half a dozen cases

#

so individually they might be a lot faster but they could end up being a lot slower if you have a bunch of individual cases

#

compared to using a slightly slower alternative that only needs to be built once

#

like your physics world is probably being built every fixed update regardless, any new simulation you build per frame is in addition to that

viral sonnet
#

right, that's the thing why I was thinking about triggers in the first place. Have it all in one place and not several others in addition that are overall slower

#

physics collider for enemies and players are here to stay anyway. at least, I think they will. 😄

hot basin
rotund token
#

dont you need entities for this test

#

just make a tiny project with updated collections

#

your code wasn't using entities as far as i can tell

queen snow
#

God I feel so discouraged from working on my current project because its on unity 2021 and basically everything needs the ECS system to work.

rotund token
rustic rain
#

ngl tho

#

result shader is literally just

#

example shader for instancing from manual page

#

xD

rotund token
#

it's about the most basic shader you can have 😄

#

i still fucked it up

rustic rain
#

is it possible to make color out of index in shader?

#

so instead of Vector4 array

#

you assign just int array

hot basin
#

it's hashing

rotund token
#

even if you could, you still need to know the colour in c# to check the entity

rustic rain
#

well

#

you'd just follow same logic

#

when converting back to int

rotund token
#

what's the benefit though?

#

since currently you don't convert back to int

#

oh i guess you're only doing it once - that makes sense

rustic rain
#

less CPU->GPU bandwitdh, less data to store or compute

#

also will ease the pain of all that

#

color conversion nonsense

#

since you will be free to do conversion in normal (non-bursted) C#

#

I just can't really think of what are options in HLSL

hot basin
#

can't you use same hash function in HLSL and C#?

rustic rain
#

hash function?

#

it's about converting integer to 4 bytes/floats

#

key point is able to reproduce Color -> integer conversion

rotund token
#

your only options for arrays on property block are setfloatarray, setvectorarray, setmatrixarray

#

so im not sure how we'd get the integers in

#

you could union the int to a float to keep precision, i dont know enough about shaders to convert that back though

rustic rain
#

SetFloatArray works fine

#

I used to do it

#

you simply treat float as int

#

and then convert on gpu

rustic rain
#

so you simply just reverse whatever algorithm is used in shader

rotund token
#

hence i suggested union

rustic rain
#

you can't?

#

fairly sure you can

rotund token
#

not enough precision

rustic rain
#

wdym?

rotund token
#

if your int goes above 16million

#

the precision drops below 1

rustic rain
#

nothing stops from simply using float tho

#

you'll probably need float in the end for algorythm, allthough not sure about it

#

but tbh, I still don't get why what you mean by precision drop

#

can always use uint

#

32 bit

rotund token
#

ok (ignoring negatives) integers can represent every integer value accurately from 0 to 2.1billion
float can only do 0 to 16mill

#

you convert 200,000,000 to float and 200,000,001 to float

#

you get the exact same value

rustic rain
#

oh

rotund token
#

anything above 16mill will have multiple integers being represented by the same float value

#

maybe this is not an issue

#

you aren't expecting integer indexes to go that high

#

but i've seen indexes in the millions before

#

(you know, because i created 10mill+ entities =D)

viral sonnet
#

I have not much idea what you're talking about 🙂 just one info - gpus and shaders are not built for ints. internally they convert to float, so stay with float as much as possible in a shader

rotund token
#

he wants to pass an array of integers and covert them to color on the gpu

#

instead of doing it on the cpu beforehand and passing an array of vector4

#

the problem is the range of integer values, while in most cases would not happen, could realistically in some cases exceed the integer accuracy of floats

rustic rain
#

hmm

#

I'm not sure why you get that

#

16 mill max value

rotund token
rustic rain
#

from what I see around

rotund token
#

float accuracy table

#

see 8.3mill to 16.7mill range is an accuracy of 1

rustic rain
#

oooh

#

going above will result in lower number

rotund token
#

yes

rustic rain
#

accuracy*

#

now i get it

#

welp

#

can always send Vector4 xD

#

which will be some kind of sum

#

of id

rotund token
#

wait

#

what's the point

#

if you're sending vector4

#

why not just send the color

rustic rain
#

you avoid doing conversion on CPU

rotund token
#

it's really not that slow in a multi-threaded bursted job though

rustic rain
#

it's still slower than doing it on fully paralleled GPU

#

also

#

shipping vector

#

is niche case

rotund token
#

most modern games are gpu not cpu bound

#

especially when it comes to threads

#

most games have ample spare cpu cores to do calculations on

#

but are often maxing their gpu

#

so while it's faster on a gpu

#

why not use the free resources instead

rustic rain
#

well, depends on a case I guess

#

in my case

#

GPU is like

#

10%

#

kek

rotund token
#

do you have 100% cpu thread utilization though?

#

or are you main thread blocked

#

this is purely worker thread cost

rustic rain
#

well, rn I never really profiled anything I do

#

but it's just usually the kind of games I work with

#

RImworld is hugely bound to main thread perfomance

#

so when I did mods, I would always consider doing compute shader for large computations

#

meanwhile gpu can be intel hd graphics

#

xD

viral sonnet
#

rimworld is not using burst AFAIK 🙂

rotund token
#

the huge advantage of jobs is it's opening up other threads to developers safely

#

anyway just a random thought

#

i just randomly hear, why use jobs/burst when you can use the gpu

#

and it often annoys me ^_^

viral sonnet
#

haha same 😄

rustic rain
viral sonnet
#

why use CPU at all? GPU has 512+ cores!

#

anyway, I still don't know what this is about? the entity picker system?

rustic rain
#

just wanted to move id to color conversion to shader

viral sonnet
#
                {
                    Vector4 c = IndexToColor(entities[index].Index);
                    colors.AddNoResize(c);
                }``` this part?
rustic rain
#

Yeah

#

Instead of shipping color array

#

Ship just float array with indices

viral sonnet
#

I'm trying to think what difference it makes in the end. You would still iterate and write the same amount of data, would you not? the bit shift to color 32 is basically free, just some ticks, minus the write operation. in the end you'd have the same array because you need to upload it to the gpu anyway

rustic rain
#

I will not compute and store colors on cpu side

#

I will only convert read color to id

#

Way less code clutter

rotund token
#

yeah you'd only need to calculate 1 (reverse) color on cpu vs 1 color for every entity

viral sonnet
#

if you want to optimize: var colors = new UnsafeList<Vector4>(batchInChunk.Count, Allocator.Persistent); var transforms = new UnsafeList<Matrix4x4>(batchInChunk.Count, Allocator.Persistent); is a good start.

#

allocation could be moved outside the job

#

for a large amount of render meshes this will take the longest time in the job

rustic rain
#

That's why I'll just get rid of it altogether xD

viral sonnet
#

are you using that in game or is this just an editor thing?

rustic rain
#

In game

#

I kind of want to do it every frame

#

For sake of mouse over

rotund token
#

the cost and pain of figuring out and ensuring each chunks capacity on main thread is not worth it

viral sonnet
#

why not use entityIndex from IJobChunk ?

rotund token
#

what do you mean?

viral sonnet
#

i mean, I get why you've written it that way. it was not meant to run every frame

rotund token
#

even if it was run every frame i'd probably do it this way

#

lets say you have 1000 chunks
are you suggesting on main thread you iterate every chunk, get its entity count, and ensure an array exists in the hashmap of that size?

viral sonnet
#

get the count from the query, set the capacity, use firstEntityIndex + i to find the index in the array

#

wouldn't even need a list

#

maybe I'm missing something 🙂

rotund token
#

no i think what you're saying makes sense

#

you can store start index/length in the hashmap

#

and subarray it

#

to pass to the shader

viral sonnet
#

you have thought this further now than me, hehe.

#

the rest of the job will be super fast.

rotund token
#

well they reason they are split is they need to be passed per chunk to the renderer

#

you can't pass the whole thing

viral sonnet
#

ahhh, that's what I was missing