#archived-dots

1 messages Β· Page 122 of 1

opaque ledge
#

is there a way to add collision filter to collider casts ?

junior fjord
#

no I don't mean a sharedcomponent for the NativeContainer but just to sort them into the right chunk

zenith wyvern
#

Yeah that's what I mean, I'm using SCD as opposed to a NativeContainer

junior fjord
#

@warped trail thanks but they do it particle based, I want to do it grid based (so not each water thing is a entity, but each tile stores how much water there is right now, in which direction it flows etc)

#

@zenith wyvern can I pn you?

#

or I mean I can also write it down here but don't want to spam so much:

warped trail
#

there is code examples how can you use hashmap to acces your neighbors πŸ€”

junior fjord
#

what exactly are you using the scd for? I thought your voxels arent entites but you have their data in Dynamic Buffer of some other entities?

slim nebula
#

there's something about physics layers @opaque ledge but I haven't used them myself so I"m not sure how they work.

junior fjord
#

@warped trail I have a good idea on how I want to access my neighbors, I am just overthinking if my memory layout is good or not

opaque ledge
#

there is a collision filter on raycasts but not on collider casts 😦

junior fjord
#

I mean I would just do a nativearray and index with [y*width + x]

zenith wyvern
#

SCD is used for filtering. So if I want to access a block at world position 10,5,1 - I need to get the region at RegionIndex (worldpos/chunksize) - then access the proper chunk then the block

warped trail
#

@opaque ledge my guess that colliders have filters inside themπŸ€”

junior fjord
#

so what is your scd? just a nativearray that maps region->entity etc?

zenith wyvern
#

Without SCD filtering you would need to use a NativeContainer - very annoying to maintain with an "infinite" world - or just literally iterate all chunks until you find the proper one you're trying to access

junior fjord
#

I don't really understand what an scd has to do with this

#

ok I have it easier in that my world does not need to be infinite

warped trail
#

@opaque ledge cs PhysicsCollider collider; collider.ColliderPtr->Filter

junior fjord
#

I mean I would then just have chunk entities, they store the data in dynamic buffers and some kind of global 2d NativeArray to access the neighbor voxels of the border voxels of a chunk

opaque ledge
#

hooo thanks @warped trail ^^

zenith wyvern
#

SCD is basically equivalent to a global container, but it's attached to the entities so you don't need to worry about maintining it - it lives and dies with the entities.

junior fjord
#

would you be so kind to show me the scd you are using? I really don't quite understand what is inside of it

zenith wyvern
#

It's just an int2 of the region index.

#

So if I want to access all chunks at a world position I divide the world position by chunksize, then I have the region index. I apply that index to a SCDFilter and it gives me all the entities in that region.

junior fjord
#

region index == chunk index?

#

or is region a group of chunks?

zenith wyvern
#

Yes

#

Region is a group of chunks

#

In my case

junior fjord
#

but world/chunksize gives you the chunk index or not?

zenith wyvern
#

Sorry I know the naming is confusing considering region and chunk both kinda mean something different in minecraft. Plus theres...the ECS meaning of chunks. And yeah

#

My chunks are laid out vertically in a region. So a region is any number of stacked chunks.

junior fjord
#

ah ok so by chunksize you mean how many chunks fit in one region

#

(per dimension)

#

?

zenith wyvern
#

In my case a chunk is a 16*16*16 set of blocks

#

They are stacked vertically in a region, so there could be 0 or 50 depending on the region

warped trail
#

i think you are confusing him more and more SarkπŸ˜…

junior fjord
#

hmm the only thing I do not get is why worldsize/chunksize is region index πŸ˜„

zenith wyvern
#

Well I'll be releasing the source code before too long so you can see for yourself how it works

#

WorldPosition.xz / ChunkSize.xz = region index

junior fjord
#

yeah but in a 1d world, if my chunk has size 10 and my position is 23, then 23/10 = 2 is the index of the chunk

#

if a region would not fit 5 chunks or something and I want to know which region my position is in, I would divide by 5*10 not by 10, that is what confuses me

opaque ledge
#

Thanks Druid, it lowered my raycast system to 0.11 ms from 200 ms lol

junior fjord
#

and I am looking forward to that source code πŸ˜„

#

very nice of you to release it

zenith wyvern
#

A region can fit 0 chunks or 50000000 chunks, the number of chunks in a region has no factor on the region index.

junior fjord
#

ahh now I get it

#

also what you mean by stacking it

#

ok thanks

#

yeah thanks very much πŸ˜„

warped trail
#

you can have cs struct testSCD: ISharedComponentData { public int2 RegionIndex; } then all entities that have testSCD with value int2(1,1) in same chunk

#

not all entities, but entities of same archetype

zenith wyvern
#

All entities of the same archetype will be in the same ECS chunk, yeah

junior fjord
#

yeah I mean basically that is the idea I came to here with. I already have entities that have data (but I have it per tile, not per chunk now). I thought about using a sharedComponent as above, to sort tiles that are nearby into the same Archetype chunk

zenith wyvern
#

And it lets you filter based on that index, regardless of the archetype

warped trail
#

then you can do things like give mee all entities which have SCD with value int2(1,1)

junior fjord
#

THen I know, that if I am accessing the neighboring tiles (which are saved in a DynamicBuffer<Entity> on each tile), I won't have cache misses very often, since most of the time, it will go to the same archetypechunk

zenith wyvern
#

You will have cache misses from accessing the entity components though since you would have to use a ComponentDataFromEntity

#

That's why arrays of entities should be avoided if you can

warped trail
#

but how will you access neighboring tiles from different chunk?πŸ€”

junior fjord
#

this makes it easier, since now all tiles just store their neighors and I think about the memory layout only at the end. I don't have to write tons of code for the cases where a tile is on the border of a chunk all the time

#

@zenith wyvern yes, of course I need a lot of COmponentDataFromEntity, but why is that a cache miss?

#

if the neighboring tile is in the same archetype chunk

zenith wyvern
#

CDFE = random access

#

Your entities may be in an array, their attached component data is not in that array. It's in a chunk somewhere

junior fjord
#

yes but I have the archetype chunks s.t. most of the time CDFE will access the same chunk that the tile itself is from.
What I mean is, I have my tiles with a Neighbor DynamicBuffer. But they also have a SCD with regionID.
Then, if I access the neighbordynamic buffer, most of the time, the entity in there will have the same regionID and will be in the same archetypeChunk

vagrant surge
#

btw, CDFE is slow

junior fjord
#

so I will access the chunk I am working with anyways

vagrant surge
#

as second slowest thing the ecs can do

junior fjord
#

doesn't that make sense?

vagrant surge
#

dont think of it as a pointer, because its much more expensive than that

amber flicker
#

@vagrant surge is it really that bad if it's predictable? I need to do another benchmark

junior fjord
#

ah ok, I was thinking of it as a pointer...

vagrant surge
#

@junior fjord do not store tiles in entities. Make tilemap entities if you want ecs, at least with a bunch of tiles each

#

like 8x8 or similar

#

8x8 is 64, so you can even do some bitmask trickery with it

zenith wyvern
#

Yeah that's what we were just talking about

vagrant surge
#

@junior fjord the issue is that it has to search where in the chunk the component data is

#

so its basically hashmap nation

#

either hashmap or binary search

junior fjord
#

yeah that is pretty much what sark recommends, I also know of that way. I just want to understand what is wrong with my way πŸ˜„

#

for learning purposes

vagrant surge
#

just to give an example on my implementation of unity style ecs, and also Flecs

#

to get the component data for A comp on entity Et, you have to do this

junior fjord
#

ok, so if Entity would be like a pointer, my idea above would be valid, or are there more problems with it?

vagrant surge
#

1: go to the global entity data array, and use entity ID as index. This gives you pointer to the chunk. world.AllEntities[entityID].chunk cache miss near guaranteed
2: from the chunk, grab archetype chunk->archetype another cache miss. (the ecs might have pointer to archetype on the allentities array tho
3: from archetype, look at its component list, and search for the component A. lets say this has a hashmap archetype->componentdeltas[A]
4: now that you have component delta, you can finally access the data by doing chunk->data[delta + index * compsize]

junior fjord
#

Your entities may be in an array, their attached component data is not in that array. It's in a chunk somewhere
@zenith wyvern I understand that. What I am talking about is, that nevertheless, the entity I am accessing will have its components very nearby, since the archetypes are sorted by region

#

so even though it is "random access", it will (nearly) always be random access from the same memory region

#

which is already in the cache

vagrant surge
#

issue is the search too. THere are other ways to implement it with hashmaps everywhere, but anyway, at the absolute least, its a hashmap search + some pointer math

#

and btw, entities have big overhead

#

entity ID is 64 bits. Each entity has 32b (version) + 64b (chunk ptr) + 32b (chunk index) of overhead

junior fjord
#

and @vagrant surge to your points:
1.+2. the neighbors will most of the time be in the same chunk as the entity itself, so this is not a cache miss, the components data will be in the cache like

vagrant surge
#

still gotta hashmap search + overheads

#

at least try to minimize it by having multiple ties per entitity

#

leave the 1 tile = 1 entity for the complex tiles

#

like a door tile, or chest, or object

dull copper
vagrant surge
#

its a big mistake to try to put everything into the ECS itself. you dont have to do that

dull copper
#

there's a roadmap thing coming at Wednesday, March 25 – Core technology and workflows

junior fjord
#

ok, so I understand it right, that memory locality is not a problem, but only the fact that Entity is kind of expensive way of pointer?

vagrant surge
#

yes

dull copper
#

so that probably covers DOTS too

vagrant surge
#

its much, much more expensive

junior fjord
#

Not trying to be right or anything, just want to understand what is going on

vagrant surge
#

think of it

#

would you create new unity game objects per tile?

junior fjord
#

yeah no, of course not, but that is why I am using ecs haha πŸ˜„

vagrant surge
#

ecs is cheaper, but still has overheads. Do not use entities unless you need the features of the ecs

#

also ecs sucks for random access

#

good candidates for things to not put on the ECS are pathnodes, and tiles, or acceleration structures

slim nebula
#

if I have two entities that are interacting with eachother and I need to modify component data on both entities, what's the best way to do that? Right now I have a query in my onupdate which returns the components for the one entity, then I use entity manager to get, then set the other entity's component data. Is there a better way?

vagrant surge
#

@slim nebula not really, thats the common thing everyone does

slim nebula
#

is there a way to get a reference to the component data so I don't have to set it explicitly after?

warped trail
#

what is not common and more efficient thing to do?πŸ€”

slim nebula
#

?

bright sentinel
#

@slim nebula Do you mean storing the data of the component in a system or something?

slim nebula
#

no, like updating a field on an IComponent

#

(or is it IComponentData I forget)

warped trail
#

ComponentDataFromEntity

vagrant surge
#

there are some crazy evil shanenigans you can do through unsafe pointers

#

dont do that

#

(but you could)

worldly pulsar
#

@slim nebula yes, but it won't save you any typing πŸ™‚ Look at what the generated code does to go from chunk to component ref

warped trail
#

can you show some examples of this shanenigans ?πŸ˜…

vagrant surge
#

store a pointer to the specific field on your target entity

#

not a ref

slim nebula
#

it's not that I want to save typing. I guess I just want to save performance. rather than copying to my code then copying back I guess I just want a ref so I can update directly

vagrant surge
#

a real pointer

warped trail
slim nebula
#

oh ok

#

that's a good idea

vagrant surge
#

and then, before accessing, check that the entity wasnt moved

slim nebula
#

"moved"?

opaque ledge
#

@slim nebula i do it with tags, when my player want to interact with something i put interact tag on that entity then check interaction condition (distance in my case) after that is true you can do your processing and remove the tag

slim nebula
#

like that the index is the same?

vagrant surge
#

chunk and index is same

opaque ledge
#

but perhaps there is a better way, idk, thats what i do πŸ˜„

slim nebula
#

ah ok

#

all good ideas

vagrant surge
#

with that, you might be able to lower the overhead of random access/set, but it IS crazy evil

#

and uses extra space

#

so i dont recomend it

junior fjord
#

@vagrant surge thanks

slim nebula
#

GetComponentDataFromEntity looks good too

#

yeah I'm not sure how much performance I'm going to need but. I want to make sure I don't design myself into a box

#

the way I'm handling the ghosts for NetCode is to separate the synchronized shit from the calculated shit so that I don't have this massive garbo list of crazy in the ghost authoring script

opaque ledge
#

nah dont worry about the performance of GCDE

slim nebula
#

but that requires transferring data from the ghost to the real components

#

and vice versa for the server

#

GCDE?

opaque ledge
#

GetComponentDataFromEntity

slim nebula
#

yeah. seems better than GetComponentData -> modify -> SetComponentData

#

is there a document or tutorial on where [BurstCompile] is valid? when I should use it? best practices, etc?

safe lintel
#

cant use burst on non blittable types

#

@dull copper did you get this error when trying out the new hybrid renderer Library\PackageCache\com.unity.rendering.hybrid@0.4.0-preview.8\Unity.Rendering.Hybrid\CopySkinnedEntityDataToRenderEntity.cs(16,26): error CS0246: The type or namespace name 'RenderMeshSystemV2' could not be found (are you missing a using directive or an assembly reference?)
!wait sorry nevermind i forgot latest srp is needed

slim nebula
#

is that the only restriction? I can put it on any class and the whole class/struct will faster?

amber flicker
#

ok, did pretty much the most simple test case I could come up with - incrementing a float every frame across 10mil entities - burst on, safety checks off - linear access: 44ms. cdfe: 280ms. I think it's useful to have the numbers in mind at any rate. In theory this is best-case scenario for cdfe I think as it's entirely predictable. ||```cs
using System.Collections;
using System.Collections.Generic;
using System.Timers;
using Unity.Collections;
using Unity.Entities;
using UnityEngine;

public class TestGroup1 : ComponentSystemGroup { };
[UpdateAfter(typeof(TestGroup1))]
public class TestGroup2 : ComponentSystemGroup { };

public struct SomeTag : IComponentData { };
public struct Test : IComponentData
{
public float Value;
}

[UpdateInGroup(typeof(TestGroup1))]
public class TestSystem : SystemBase
{
public NativeArray<Entity> AllEntities;
protected override void OnCreate()
{
AllEntities = new NativeArray<Entity>(10000000, Allocator.Persistent);
var arch = EntityManager.CreateArchetype(typeof(SomeTag), typeof(Test));
EntityManager.CreateEntity(arch, AllEntities);
}

protected override void OnUpdate()
{
    Entities.ForEach((ref Entity e, ref Test t) =>
    {
        t.Value += 0.1f;
    }).ScheduleParallel();
}

}

[UpdateInGroup(typeof(TestGroup2))]
public class TestSystem2 : SystemBase
{
protected override void OnUpdate()
{
ComponentDataFromEntity<Test> tests = GetComponentDataFromEntity<Test>(false);
Entities
.WithAll<SomeTag>()
.WithNativeDisableParallelForRestriction(tests)
.ForEach((ref Entity e) =>
{
tests[e] = new Test() { Value = tests[e].Value + 0.1f };
}).ScheduleParallel();
}
}

warped trail
#

@safe lintel you have to download source from github

amber flicker
#

sorry - thought I put spoiler tags round that

safe lintel
#

thanks, forgot about that πŸ™‚

#

@slim nebula burst package docs can probably give you more info on restrictions

slim nebula
#

I'm lookin at that but it's confusing. is burst only for jobs?

#

does it not work on systems?

warped trail
#

it is for jobs and function pointersπŸ˜…

worldly pulsar
#

The idea is that systems do light work to prepare data and build a job graph, where all the heavy lifting happens

slim nebula
#

function pointers ok

worldly pulsar
#

so in theory you shouldn't need Burst in systems πŸ™‚

slim nebula
#

hmm ok

#

I guess I need to learn what a job is XD

#

I will read up on that soonish

dull copper
#

@safe lintel did you get it running on beta 2?

safe lintel
#

i forgot it needed the srp from github and am too lazy to clone it/import it all for my project right now πŸ™‚

dull copper
#

I asked if we still need b3 on the forums but no reply yet

#

it does seem functional at first glance when using b2

safe lintel
#

i saw b2 and got all excited

dull copper
#

well, it doesn't break in all directions on b2 for me like it did on b1

coarse turtle
#

The issue has been reported multiple times - iirc it was an issue in the editor side and it was marked benign πŸ€”

slim nebula
#

orly

#

good to know. phew

coarse turtle
#

Well the last time I saw a thread post on it was in 2019 πŸ€”

warped trail
#

Leak Detection Full Stack Traces?

slim nebula
#

I saw some similar ones with ppl talking about that error in regards to specific code of theirs, but it didn't seem similar to what I was doing

#

I mean

#

I tried that but it doesn't change the stack trace output

#

log is still the same

coarse turtle
#

Yea - I forget which part was causing the warning - at some point I stopped seeing it consistently

slim nebula
#

when I add large amounts of logging it goes away rofl. seems to be some timing issue I guess?

coarse turtle
#

possibly

slim nebula
#

once your game actually does something then it's maybe not a problem?

#

rofl

#

ok

#

well I'll stop worrying about it I guess

#

just annoying cause I have to turn warnings off

#

then I dont see other warnings that I want

#

is there a way to filter the log?

#

either runtime or in the editor?

warped trail
#

i got those errors from Physics debugdraw

coarse turtle
#

Not that I know of, probably some other console editor asset might have that capability

warped trail
#

i updated SimulationsSystemGroup in fixed timesteps and there was more than 5 frames between updates of SSG πŸ˜…

slim nebula
#

SSG?

#

(i'm trying really hard to learn all these acronyms lol)

warped trail
#

SimulationsSystemGroup

slim nebula
#

ah

warped trail
#

all this names are so long

slim nebula
#

yeah

warped trail
#

80 characters is not enough πŸ˜•

coarse turtle
#
  at Unity.Entities.EntityRemapUtility.PatchEntityInBoxedType (System.Object container, Unity.Entities.EntityRemapUtility+EntityRemapInfo* remapInfo)```
Guess you can't add component objects in subscene entities via conversion system πŸ˜…
safe lintel
#

hmm An asset is marked with HideFlags.DontSave but is included in the build: Asset: 'Assets/Resources/Settings/Build/Hybrid.buildpipeline'

#

ok note to self - build pipeline file doesnt like being inside the resources folder πŸ™‚

mint iron
#

@digital scarab is there a way to load in a SubScene from Addressable yet?

#

ok, thank you.

dull copper
#

addressables being dead on arrival

dull copper
#

I kept asking about ECS support on addressables while it was on early preview

#

the answer used to be it's going to be supported once addressables release

#

now it's out and not much changed πŸ˜„

#

this was all long before Unity used DOTS term btw

safe lintel
#

new physics package, doesnt appear to be on pacman yet

opaque ledge
#

I have this code

    private EntityQuery defenderThreatTablesQuery;
    private EntityQuery attackerThreatTablesQuery;

    protected override void OnCreate()
    {
        RequireSingletonForUpdate<GameState_Encounter>();

        defenderThreatTablesQuery = GetEntityQuery(typeof(DefenderThreatMasterTableTag), typeof(ThreatMasterTable));
        attackerThreatTablesQuery = GetEntityQuery(typeof(AttackerThreatMasterTableTag), typeof(ThreatMasterTable));
    }

    protected override void OnUpdate()
    {
        var defenderThreatEntity = defenderThreatTablesQuery.GetSingletonEntity();
        var attackerThreatEntity = attackerThreatTablesQuery.GetSingletonEntity();

        var attackerThreatTable = EntityManager.GetBuffer<ThreatMasterTable>(attackerThreatEntity);

        var defenderThreatTable = EntityManager.GetBuffer<ThreatMasterTable>(defenderThreatEntity);
}
#

after that my job comes but it gives an error

#

"nvalidOperationException: The writable NativeArray <>c__DisplayClass_EncounterShipThreatUpdate.JobData.defenderThreatTable is the same NativeArray as <>c__DisplayClass_EncounterShipThreatUpdate.JobData.attackerThreatTable, two NativeArrays may not be the same (aliasing)."

#

well i will just change it to normal approach instead of Sark's 🀷

worn stag
#

is there a way to use subscene more than once in scene?

#

without duplication of referenced by subscene unity scene

bright sentinel
#

Just uh, create a new sub scene

opaque ledge
#

@dull copper physics new update πŸ‘€

dull copper
#

new havok package too

#
## [Unity Physics 0.3.1-preview] - 2020-03-19

### Upgrade guide
 * User implemented query collectors (`ICollector<T>`) may no longer work. The reason is that `ICollector<T>.TransformNewHits()` was removed. To get the collectors working again, move all logic from
 `ICollector<T>.TransformNewHits()` to `ICollector<T>.AddHit()`. All the information is now available in `ICollector<T>.AddHit()`. Also, `IQueryResult.Transform()` was removed, and user implementations of it will not get called anywhere in the engine.

### Changes

* Dependencies
    * Updated Burst from `1.3.0-preview.3` to `1.3.0-preview.7`

* Run-Time API
    * The following properties are added to `IQueryResult` interface:
        * `RigidBodyIndex`
        * `ColliderKey`
        * `Entity`
    * `ICollector.AddHit()` now has all the information ready to perform custom logic, instead of waiting for TransformNewHits().
    * Removed `Transform()` from `IQueryResult` interface and from all its implementations.
    * Removed both `TransformNewHits()` methods from `ICollector` interface and from all its implementations. All the information is now ready in `ICollector.AddHit()`.

* Authoring/Conversion API

* Run-Time Behavior

* Authoring/Conversion Behavior
#
### Fixes

* Setting `Collider.Filter` now increments the header version so that the simulation backends can recognise the change.
* Asking for collision/trigger events in scenes with no dynamic bodies no longer throws errors.
* Updated to new version of Burst, which fixes a regression that caused `ConvexCollider.Create()` to produce hulls with a very small bevel radius.
* DOTS Run-time failures due to multiple inheritance of jobs have now been fixed.
* Changed `Math.IsNormalized` to use a larger tolerance when comparing float3 length.```
#
## [Havok Physics 0.2.1-preview] - 2020-03-19

### Fixed
- Changing motion type of many bodies in a single frame no longer results in a crash.
- Trigger events are now consistently raised for penetrating bodies.
- Asking for collision/trigger events in scenes with no dynamic bodies no longer throws errors.
- Android ARM64 and ARMv7 can now be built together without any special actions. Android-specific instructions are removed from [Supported platforms](Documentation~/platforms.md).
slim nebula
#

where can I find changelog for new unity physics

dull copper
#

besides here? πŸ€”

slim nebula
#

where here?

dull copper
#

two messages up

slim nebula
#

I'm dum sorry please hold my hand

#

oh I thought that was havok because I didn't read

#

ignore me

dull copper
#

changelogs are always part of the package

#

they'll update the online changelogs shortly after the release

south falcon
#

Do you guys know why translation is NaN? After Instantiate the gameObject to a scene, which is attached ConvertToEntity and should be convert to entity after Instantiate .

opaque ledge
#

are you using multiple physics shape or colliders ?

south falcon
#

are you using multiple physics shape or colliders ?
@opaque ledge No, Only using one physics shape and one physics body per entity. And no unity collider on it.

opaque ledge
#

can you check what PhysicMass Transform field shows when its converted?

south falcon
#

are you using multiple physics shape or colliders ?
@opaque ledge Oh, it does the problem with physics body or collider. I turn them off and the translation is ok

#

maybe it is the problem that I spawn two entities in a same position

opaque ledge
#

yeah most likely

#

i had an issue a few hours ago, was wondering if you had the same

#

but your suggestion sounds more logical

dull copper
#

An updated version of the Physics Samples is also out. We have removed LWRP package dependency to reduce the complexity of the package.

warped trail
#

why they are not using SystemBase in samplesπŸ€”

dull copper
#

why the advanced physics samples are still using the first quick setup they made that's a) totally hacky b) bad example for people trying to learn these things

#

that vehicle scene bugs me especially

#

afaik, these physics samples were quite quickly done initially and they haven't really revisited them for making them more like proper samples

#

I talked a bit about this with the Havok guy at last Unite, but it doesn't seem to be a priority atm

#

people who make more complex physics setups would benefit from better dots physics examples

#

instead of making each user experiment and figure things on their own

quiet sand
#

Has anyone successfully despawned entities inside a ICollisionEventsJob?

wary anchor
#

hi everyone, I find myself needing to access IComponentData from the player Entity all over my code, and I end up with things like the code below, which seems really bad practice. What can I do to stop creating all these sync points and reduce the code clutter?

NativeArray<Entity> playerArray = playerEntityQuery.ToEntityArray(Allocator.TempJob, out inputDeps);
inputDeps.Complete();
if (playerArray.Length != 1)
{
  playerArray.Dispose();
  UnityEngine.Debug.LogWarning("Could not find player");
  return inputDeps;
}
Translation playerTranslation = EntityManager.GetComponentData<Translation>(playerArray[0]);

float3 playerPosition = playerTranslation.Value;

AIHomingJob job = new AIHomingJob
{
  PlayerPosition = playerPosition,
  HomingRangeSq = settingsStorageSystem.AISettings.AIHomingRangeSq
};
playerArray.Dispose();
return job.Schedule(this, inputDeps);

^^^ YUK! All help for me to escape from this bad bad bad code would be most welcome! πŸ™‚

worldly pulsar
#

RequireSingletonForUpdate<Player>() in OnCreate gets rid of the whole playerArray.Length != 1 section

wary anchor
#

that would mean making the player a singleton entity I assume

worldly pulsar
#

GetSingletonEntity<Player>() lets you get the entity without scheduling a job (or allocating)

#

well, since you are checking that playerArray.Length is 1 I assume you only have 1 player πŸ™‚

wary anchor
#

yeah I'm kinda having to do that because it's the only way I could prototype it. I won't be doing MP for this project but the next one based on it has a good chance of multiple player entities

#

Thanks @worldly pulsar I'll see about how it would affect my implementation as it stands to change over to a singleton entity

warped trail
#

and you can do something like cs var arr = playerArray.ToComponentDataArrayAsync<Translation>(Allocator.TempJob, out var jh);

#

and than pass this native array to your job

wary anchor
#

if I have to get the playerArray like now it's basically meaning a sync point in every system where I need that reference isn't it - is this avoided with the GetSingletonEntity route?

warped trail
#

i guess noπŸ€”

wary anchor
#

this must be a very common scenario - systems for a variety of things around the game requiring data (eg position or other state) from a different entity, how do you deal with this?

worldly pulsar
#

This is not a structural change, so it will only sync the jobs that write to Translation

#

assuming you use the full dependency automagic, and not the USE_SIMPLE_SYSTEM_DEPENDENCIES (don't remember the actual name of that symbol)

bright sentinel
#

Do all your enemies need the players position? if so, you should probably use a SharedComponent instead, and then have the player's system set that shared component instead

wary anchor
#

I'm not using any such preprocessor symbol!

bright sentinel
#

Another approach is to save the entity in a component and use the GetComponent<T>(Entity) method

#

Generally you want to save the data you need in components

wary anchor
#

all the data are in components on the player entity, do you mean store a reference to the player entity?

bright sentinel
#

Yes

worldly pulsar
#

you should probably use a SharedComponent instead
I really don't think this is a good idea

bright sentinel
#

Either that, or have the player's system set the value of some components

#

For example, have a system that first gets the player position, and then sets some component on your enemies with that players position (if you need the position) on the components that needs it

wary anchor
#

full on cheese method would be for one of the player systems to write out the various bits of data I need to publicly exposed properties on the system, but that violates so many core principles of common decency it's not even funny

bright sentinel
#

Pseudo code

NativeArray<float3> playerPos = new...;
Entities.Foreach((int index, in Player player, in Translation trans) =>
{
  playerPos[index] = trans.Value;
}
Entities.ForEach((ref ComponentThatNeedsPlayerPos comp) => 
{
  comp.playerPos = playerPos[0];
}
#

Or whatever

warped trail
#

why not use ToComponentDataArrayAsync then?

#

or what is the difference?

wary anchor
#

I can't find any API docs for that @warped trail ?

bright sentinel
#

Isn't that essentially the same as Entities.ForEach though?

#

Haven't used it before

#

Ohh, I see

warped trail
#

i think this is exactly the tool for that

#

you are creating IJobChunk with 3 iterators

wary anchor
#

got a link to the docs for that? google isn't bringing anything up with that name

bright sentinel
#
EntityQuery playerQuery = // Some query that gets the player
NativeArray<Translation> playerPos = playerQuery.ToComponentDataArray<Translation>(...);

Entities.ForEach((ref ComponentThatNeedsPlayerPos comp) => 
{
  comp.playerPos = playerPos[0];
}
#

There's some stuff here

#

You can also use it directly in the systems of course

warped trail
#

ToComponentDataArray is the same as ToComponentDataArrayAsync

wary anchor
#

okay the async part was throwing me off

warped trail
#

ToComponentDataArray creates a job and completes it

wary anchor
#

πŸ‘

warped trail
#

ToComponentDataArrayAsync creates a job and gives you a handle

bright sentinel
#

Man this gametorrahod knows so much, but the English in there is so bad 😦

#

I wonder who this person is πŸ€”

wary anchor
#

mmm maybe async is in a newer version, I don't have that extension method

warped trail
#

they just created explicit methods for ToEntityArray(Allocator, out jobHandle);

#

this ToEntityArray(Allocator, out jobHandle) became ToEntityArrayAsync(Allocator, out jobHandle)

#

you can read 0.6.0 changelogs

wary anchor
#

mmh type must be a reference type to use it...

warped trail
#

?πŸ€”

wary anchor
#

I'll leave that until I next upgrade Unity.Entities! It doesn't seem to like having any struct that implements IComponentData as the type for entityQuery.ToComponentDataArray<T>(); for some reason!

warped trail
#

ahm but T has to be IComponentDataπŸ€”

wary anchor
#

oh, it returns a list of all components of all component types from the entity query?!

warped trail
#

it returns a copy of all components of type T from query. If you have 100 entities in your query .ToComponentDataArray<Translataion>() will return NativeArray<Translation> with length 100

wary anchor
#

when I type ToComponentDataArray<Translation>() I get an error saying that the type needs to derive from class and implement IComponentData... maybe they updated it in the newer version to work with structs

#

but thank you for the links and advice! Very helpful (I need to upgrade soon, but have a mini deadline tomorrow so not now!)

#

yeah that looks awesome, it clearly says struct there but at least in the version I have it requires class, which clearly none of my IComponentData structs are because I'm not a monster!

warped trail
#

ToComponentDataArray<Translation>(Allocator.TempJob);

#

yes?πŸ˜…

wary anchor
#

Oh christ it's overloaded with the struct version... thank you I am so dumb

warped trail
#

but you need this one cs var array = query.ToComponentDataArrayAsync<Translation>(Allocator.TempJob, out var jobHandle);

wary anchor
#

that's not in 0.5.1

warped trail
#

oh

wary anchor
#

so yeah I'll wait until after the crunch to update

warped trail
#
ToComponentDataArray<Translation>(Allocator.TempJob, out var jobHandle);```
#

this one then πŸ˜…

wary anchor
#

but it's bookmarked, thank you (yeah I'll try that with the jobhandle that way)

warped trail
#

they just renamed overloaded function

wary anchor
#

πŸ‘

warped trail
#

basically you can change this```cs
NativeArray<Entity> playerArray = playerEntityQuery.ToEntityArray(Allocator.TempJob, out inputDeps);
inputDeps.Complete();
if (playerArray.Length != 1)
{
playerArray.Dispose();
UnityEngine.Debug.LogWarning("Could not find player");
return inputDeps;
}
Translation playerTranslation = EntityManager.GetComponentData<Translation>(playerArray[0]);

float3 playerPosition = playerTranslation.Value; to thiscs
var playerPosArr = playerEntityQuery.ToComponentDataArray<Translation>(Allocator.TemJob, out var jh);

wary anchor
#

yup, already done and working, thanks man that's so much tidier!!

warped trail
#

and don't forget to combine dependencies πŸ˜…

wary anchor
#

so I need to dispose of the array, which means calling complete on the homingjob then disposing - this is what I have now have I been triple dumb? This seems to work fine but I'm all about learning from my mistakes :D

protected override JobHandle OnUpdate(JobHandle inputDeps)
{
    var translations = playerEntityQuery.ToComponentDataArray<Translation>(Allocator.TempJob, out inputDeps);

    AIHomingJob job = new AIHomingJob {
    PlayerPositions = translations,
    HomingRangeSq = settingsStorageSystem.AISettings.AIHomingRangeSq
    };

    inputDeps = job.Schedule(this, inputDeps);
    inputDeps.Complete();
    translations.Dispose();
    return inputDeps;
}
warped trail
#

you can .Dispose(JobHandle);

#

translations.Dispose(inputDeps);

wary anchor
#

ooo so yes to triple dumb this is golden

warped trail
#

at least you can do this in recent version of collections πŸ˜…

wary anchor
#

yup same here, so just

return array.Dispose(handle);
```?
warped trail
#

yeah

wary anchor
#

grand, works a treat! Got a few of those cases to clear up, that's going to make some of my code a lot clearer now, thank you

warped trail
#

and i think you have to change this cs ToComponentDataArray<Translation>(Allocator.TempJob, out inputDeps) into this cs ToComponentDataArray<Translation>(Allocator.TempJob, out var jh); inputDeps = JobHandle.CombineDependencies(jh, inputDeps); πŸ€”

wary anchor
#

that seems to be equivalent - they're both working at least

warped trail
#

isn't this out inputDeps just replaces inputDeps?

wary anchor
#

yeah I don't know if it needs a new handle tbh...

#

I mean, it works fine πŸ˜„

#

even

inputDeps = JobHandle.CombineDependencies(job.Schedule(this, inputDeps), inputDeps);
``` works and that's just hilariously weird
warped trail
#

but you have all your previous dependencies in inputDeps

wary anchor
#

yeah that just makes it all linear doesn't it... good point I'll make a new jobhandle

warped trail
#

and out inputDeps just throws them away

wary anchor
#

so:

protected override JobHandle OnUpdate(JobHandle inputDeps)
{
    var translations = playerEntityQuery.ToComponentDataArray<Translation>(Allocator.TempJob, out JobHandle translationHandle);
    inputDeps = JobHandle.CombineDependencies(translationHandle, inputDeps);

    AIHomingJob job = new AIHomingJob {
        PlayerPositions = translations,
        HomingRangeSq = settingsStorageSystem.AISettings.AIHomingRangeSq
    };

    JobHandle homingJobHandle = job.Schedule(this, inputDeps);
    inputDeps = JobHandle.CombineDependencies(homingJobHandle, inputDeps);

    return translations.Dispose(inputDeps);
}
warped trail
#

this is unnecessary cs JobHandle homingJobHandle = job.Schedule(this, inputDeps); inputDeps = JobHandle.CombineDependencies(homingJobHandle, inputDeps);

#

justcs inputDeps = job.Schedule(this, inputDeps)

wary anchor
#

ahh yeah the scehdule combines doesn't it

#

DOH

#

it's a wonder I manage to get dressed most days

safe lintel
#

just a note, you should probably be transitioning to SystemBase over JobComponentSystem

hollow sorrel
#

i'm looking to have one collection (on a component) where sometimes i want to get each element per byte but sometimes less than a byte (e.g. when max needed is 16 go per half byte)
could do a DynamicBuffer<byte> and do bitwise ops on that, but maybe there is a better way?
i noticed there is a UnsafeBitArray in collections, would that be better suited?

opaque ledge
bright sentinel
#

Looking very nice! Great to see a more "real" project with DOTS

odd cipher
#

I'm not sure if I should use full DOTS if I only have around 10 gameobjects per scene (ignoring UI gameobjects)

low tangle
#

It's up to how you design things

#

Even in my Minecraft gamemode it only has currently 50 or so entities, but it was very easy to write in about two hours

#

The monobehavior equivalent would've took double and likely not networked like this one

#

Ignoring performance

odd cipher
#

huh, still some things that I am confused on about Entities, such as does DontDestroyOnLoad still work? and what about empty gameobjects with scripts on them?

low tangle
#

Yes it does, I use don't destroy on all gameobjects that are managed by entities

#

Empty gameobjects are fine, all my UI is basically that

bright sentinel
#

How do entities even interact with scenes?

low tangle
#

As much as you want

bright sentinel
#

So entities won't be unloaded if I unload the scene they were originally in?

odd cipher
#

Hm. I guess I could try and learn some of Entities by converting my Player into a Entity.

low tangle
#

You can use AddComponentObject to attach monobehavior and unity components directly to a entity and process then like a regular ecs component data

#

If you are creating a entities sub scene then yes, but all other created entities are not tied to one and are not deleted unless you say so @bright sentinel

odd cipher
#

Well, I do want to learn Entities so

low tangle
#

They are global/don't destroy by default which makes a lot of sense

odd cipher
#

Only thing I'm unsure of is, if its worth it

low tangle
#

That's hard to say as it's team, project, developer centric

#

Can only talk about personal experience

#

Yep

#

He's there one that convinced me to start on ecs after he started in early 2018

#

RTS are such a natural fit for ecs

odd cipher
#

I guess it is hard to say if its worth it but would you recommend using it?

low tangle
#

Yes 100%

dusty scarab
#

Are battle royale's a fit for fots?

#

dots*?

low tangle
#

Almost two years of using it and I thought it would be a waste of time, and a gamble to switch to on my young project

#

Instead it ended up being a solid sane framework, and one thing that's not mentioned too much is the fact you can do massive optimization way later on

vagrant surge
#

battle royales are a great fit, because you have 100s of basically everything

low tangle
#

That combined with the fact you can replace any system with better processes is so nice for updating core bits

vagrant surge
#

@low tangle yup. You can turn one system into a highly optimized one later

dusty scarab
#

Currently I'm in my 3rd year of CS undergrad, and I started learning DOTS but literally gave up after a couple of weeks because I simply couldn't understand the flow.

vagrant surge
#

its one of the main features of data-oriented design, it works very well with optimization potential

#

@dusty scarab read the data-oriented-design book

dusty scarab
#

There's a book?

low tangle
#

Like my download and asset streaming system has been patched for bugs over and over for the last year

vagrant surge
#

not about DOTS, but about the same "design ideas"

low tangle
#

Yeah read the book

vagrant surge
#

btw its a free book online

dull copper
#

my main interest on ECS isn't ECS itself (I'd just use burst + jobs) but I need the new physics quite badly with full source access

low tangle
#

It's great for getting your head around this kind of data is everything flow

dull copper
#

if Unitys physx integration sources were on my hands, I wouldn't even bother

low tangle
#

Things that are weird like, doing lod on logic

dull copper
#

(that being said, I've already used Bullet for physics in past)

dusty scarab
low tangle
#

Yep

dusty scarab
#

allright thanks!

vagrant surge
#

the paid book has a bit of extra content, but that web version is like 90%

low tangle
#

500 units in a group? Delete them, delete their meshes, delete their physics. Spawn single combined unit entity for the whole group

vagrant surge
#

the book talks about it on the whole "level of detail but for logic" stuff

#

one of the fun things on ECS, is that you can have a background "offline" world, and migrate things

low tangle
#

You can do stuff like that because you can cross cut and observe anything

vagrant surge
#

so when a NPC is far from you, you move him into this background shadow world

dusty scarab
#

like a subscene?

vagrant surge
#

and just spawn an entity that does distance check to recover

#

and when the player gets closer, you swap it with the entity in the shadow realm

low tangle
#

Yeah and if you were memory constrained, or just have a ton. You can even unload and compress the units data until he's needed again

dusty scarab
#

One question, in this shadow world concept, you only don't only render it right? Because if it moves to a viewable area you need the details on it. And then just render it again

low tangle
#

It's a just a chunk of data you want to save

#

It's not a object that you can render on

#

The world you store it in might not even have systems

#

When the npc becomes visible, you spawn all the peices that make up that unit then, which includes the meshes with transforms

odd cipher
#

I'm currently using Jobs and Burst, I guess it would be a good idea to add some of Entities in there too

dusty scarab
#

erm lemme ask with an example. Like on a multiplayer map A and B are really far away from each other. So, you just don't render A on B and vice versa. So, for any of them to render, you need a system to check whether the systems on A and B move them to a visible area. So, When swapping the visible entity with the one in the shadow world you keep the systems alive

#

so the only difference with normal way is you don't render it

low tangle
#

The systems are only running when there is units they care about to work on

#

Your render systems don't care that there's a unit that is disabled for rendering, instead, that unit doesn't even have rendering stuff at all and was never even looked at in the first place

dusty scarab
#

I see, because only the components required are seen, not the ones disabled

low tangle
#

When the unit becomes visible, is when the unit the rendering system cares about is spawned in the first place

vagrant surge
#

ok im back

#

got automuted by trying to send a link from the dod book

low tangle
#

Sorry phrased that last one wrong

#

Fixed it

#

Just woke up

vagrant surge
#

@dusty scarab first of all, turning entities "off" is super easy

#

just add some sort of Disabled tag to it

#

but then you need to make sure your systems dont iterate Disabled tag

#

i think unity already has something like that?

#

but not sure if its automatic

low tangle
#

Disabled exact name is

#

Excluded from all query's by default

vagrant surge
#

ah, perfect then

#

doing that should be safer than siwtching world

low tangle
#

Prefab is too and it has the added effect of getting stripped if you . instantiate it

dusty scarab
#

Switching the world would be the same right? Just add another tag

vagrant surge
#

not exactly

low tangle
#

Those are more implementation details than the logic I was trying to explain

#

The database he mentions in that book is exactly what the unity entity query system gives you. And when he mentions building look up tables for storting on creation or transformation, that can be achieved with a system state component

#

So far everything I've needed from that book has a easy parallel in dots

dusty scarab
#

okay, I get some of that. "When the unit becomes visible, is when the unit the rendering system cares about is spawned in the first place" This line actually makes a lot of sense now.

low tangle
#

I can write up a simple psudo code for it if that would help

#

Just need to get to the pc

dusty scarab
#

Don't bother, I'm just trying to understand the concept right now, will make a second attempt at dots programming soon, the first one didn't go so well. I got the CodeMonkey tutorials working and the Pong game by Unity but as soon as I needed to write something by my self the ship crashed :/

vagrant surge
#

look at the unity tiny samples

#

they are the best way to undesrtand how DOTS works

low tangle
#

yeah those are good

vagrant surge
#

they are super simple, and they are "modern" made

#

for example the tiny racer one is pretty good

low tangle
dull copper
#

@dusty scarab you need to figure out a lot on your own atm and unity's ecs is still at stage where you constantly need to relearn their systems as they keep changing the API

low tangle
#

highly suggest reading the DoD book though

dull copper
#

it's been like this for years now

vagrant surge
#

and very poor editor support

low tangle
#

well the base level api hasn't really changed much

#

its still just crud on entities when it comes down to it

dull copper
#

yeah, don't get me started on the conversion workflow

low tangle
#

the job api is the one that keeps getting changed

dull copper
#

it's my least favorite thing about this all

vagrant surge
#

tfw entitas still does it better

low tangle
#

yeah I dont do anything with the conversion workflow

dusty scarab
#

Erm, tbh, when I was doing it, I didn't run much into problems with API as VS usually showed me what was depreciated and I changed it accordingly

low tangle
#

built my own hybrid systems a long time ago when inject was added because I didnt like that either

dull copper
#

@dusty scarab what I mean, the api keeps evolving all the time

vagrant surge
#

honestly i learnt ECS by making an actual real project (commercial!!) on unity with entitas

dull copper
#

if you learned this like year ago, your code would look TOTALLY different

vagrant surge
#

and well, tons of random experiments outside of unity

low tangle
#

yeah let me pull up a system from early dots

dusty scarab
dull copper
#

current core ecs is super nice compared to the old setups

#

I'm not complaining about that at all

#

it's getting simpler every moment

#

it's just we desperately need better tooling and more robust workflows for getting things on ECS side if you do hybrid

vagrant surge
#

i still dont know why the fuck they didnt just do what entitas does

#

for hybrid

low tangle
#

they needed to just port the rest of rendering

#

thank god they are

#

its semi hybrid

#

like lights in megacity

vagrant surge
#

if it worked like entitas does, you would see a lot more people using unity ecs to optimize stuff on their normal games

low tangle
#

its always felt like a isolated team working on their own engine, trying not to rock the boat

vagrant surge
#

it also feels like me like they dont want hybrid to be a thing

low tangle
#

yep

vagrant surge
#

because adding entitas style stuff would be trivial

#

but they dont

#

so thats a specific decision where they decided they dont want to do that

low tangle
#

thank god they didn't take away what they gave us early on

#

AddComponentObject and TransformAccessArray

mint iron
#

current core ecs is super nice compared to the old setups agree 100%, i've been converting a bunch of my old systems to SystemBase/Entities.ForEach/Jobs.WithCode and its really quite nice, it just works.

dull copper
#

yeah, it also helps on code readability with all that boilerplate out of the way

low tangle
#

yeah I didn't like them at first for how buggy they were, but deleting 100s of lines of bolierplate off each system is great

#

sucks that jobforeach is going away

#

means I gotta port a bunch of old systems that are a year old

#

I really hope .WithRequireForUpdate(ref query) comes in soon

#

its the only thing I use OnCreate for now 99% of the time

#

that and caching World.GetExistingSystem

mint iron
#

Do you have complex queries? i just tested a system with just an Entities.ForEach and it properly doesn't execute the system unless an entity exists; so that was half of my OnCreate/RequireForUpdate code gone.

low tangle
#

talking about the systems that first hashmap or gather up some data from other entities, when you start splitting entities instead of fat archetypes you do this a lot

#

you only want them to run on the actual entites it processes, not the required extra data

#

if that other data exists, the system always runs unless you throw the require on the main query

mint iron
#

ahh yep, makes sense.

low tangle
#

SystemBase is the newest system type right?

dull copper
#

yes

low tangle
#

Added HasComponent/GetComponent/SetComponent methods that streamline access to components through entities when using the SystemBase class. These methods call through to EntityManager methods when in OnUpdate code and codegen access through ComponentDataFromEntity when inside of Entities.ForEach.

#

yeah that must be it

dull copper
#

you get rid of passing the dependencies manually on it

low tangle
#

damn thats nice

#

auto switching to ComponentDataFromEntity

#

does it do buffers too?

dull copper
#

I think it does

#

you get rid of that horrible EBBBCCC stuff

#

at least I converted one such system for the new thing and it worked

opaque ledge
#

no, there is no buffer version yet

dull copper
#

huh?

opaque ledge
#

there is no buffer version of Has/Get/SetComponent

low tangle
#

dang

#

is the EntityManager or GetBufferFromEntity still able to be accessed/created?

opaque ledge
#

Yeah, you use GetBufferFromEntity for buffers

amber flicker
#

Few slightly annoying limitations as well.. not sure if it's overall types but I couldn't do more than 3 types in .WithNone<> the other day

dull copper
#

I was referring to being able to do systembase with entities.foreach that has dynamic buffers in it

low tangle
#

you can chain the .WithNone's though

opaque ledge
#

i think you can still put multiple WithAll/None/Any

low tangle
#

fluent queries let you do that

opaque ledge
#

only filter is limited to 2

low tangle
#

Managed components are now stored in a way that will generate less GC allocations when entities change archetype.

#

thats nice

#

thanks for the help guys

#

time to get to work

mint iron
warped trail
#

wouldn't it be better to split this system to 3?πŸ€”

mint iron
#

maybe, but i already have about 50 systems, i think this makes sense because i have two different inputs that can create a score, and this system is the only place that handles claculating the score and producing score events.

warped trail
#

you have 3 different queries in system, and you are scheduling 3 jobs even if there is only 1 active queryπŸ€”

mint iron
#

two jobs, the third is a shared method they're calling. But thats true i hadn't considered that update would run if either job query matches.

opaque ledge
#

are you using Tertle's event system ?

mint iron
#

nah, i'm writing my own

opaque ledge
#

hooo, sounds nice

low tangle
#

hows the performance against normal event entities

mint iron
#

its pretty good, the bottlenecks are mostly EntityManager.DestroyEntities/CreateEntities. if i could find a fast way to get access to the lower level methods it would be nice.

vagrant surge
#

using batch operations can be much faster

#

tho i think you probably already do it

#

a better idea is to not use event entities unless you need the very complex features that can have, and just have normal boring old event queue

mint iron
#

the query overloads only seem to get faster after about 1000 entities, before that NativeArray<Entity> is much faster (for destroy). You'd think CreateChunk would be better for creation but its not running through a burst path and CreateEntities(archetype/count) is just bad compared to CreatEntities(archetype,/NativeArray)

vagrant surge
#

interesting

coarse turtle
#

hmm is that the perfomance testing api package? πŸ‘€

mint iron
#

yep!

odd cipher
#

How would I convert a float[][,] to something something Native?

#

or a float[,] in general?

coarse turtle
#

NativeArray<float>?

#

You'd be flat mapping the 2d array into a 1d array since [,] assumes that all rows are the same length - it just means you'd have an array of (# of rows) * row_length

warped trail
#
int i = x + y * max_x + z * max_x * max_y
int x = i % max_x ;
int y = ( i / max_x ) % max_y ;
int z = i / ( max_x * max_y );
low tangle
#
public static int GetIndex(int x, int y, int z, int3 size)
{
    if (x < 0 || x >= size.x) return -1;
    if (y < 0 || y >= size.y) return -1;
    if (z < 0 || z >= size.z) return -1;
    return (size.x * size.y * z) + (size.x * y) + x;
}
coarse turtle
#

whoops totally didn't read the whole float[][,] syntax

odd cipher
#

@low tangle So, I should just have a NativeArray<float> and use that?

#

like, flatten the float[][,] into NativeArray<float>

low tangle
#

this is just for a 3d array indexing into 1d

silver dragon
#

Using

collisionWorld.CalculateDistance(distanceInput, ref hits)

i get a lot of entries in hits, most of them belong to the same body. Do i have to calculate the unique bodies and their nearest point manually or is there a mechanism for that somewhere?

#

Basically i want to get all bodies within a certain range, but without creating a collider for a collidercast.

opaque ledge
#

are "hits" include body index ? if so you can do Bodies[entity].entity to get the entity that hit 'something' belongs to, you can then check if that hit belongs to self or not

#

Why you dont want to use collider cast ?

#

you can use sphere collider for it i think

warped trail
#

@silver dragon you have to manually filter out undesired collidersπŸ˜…

#

oh, they changed it a little bitπŸ˜…

limpid bough
#

Distance queries easily get prohibitively expensive. Design them out if at all possible

#

unless it's over very short ranges

#

even there it's generally you pay a big hit that you don't really need to if you used collider/ray casting

warped trail
#

so sphere cast will be cheaper than distance query?πŸ€”

limpid bough
#

Whatever is more restrictive/hits less things will be cheap. It's that using explicit shapes for the task at hand is more likely to produce fewer and more meaningful hits

silver dragon
#

I thought distance query is the same as a spherecast, just more flexible...

#

When using collidercast for a range query, especially if you have different ranges, do you create new colliders each cast? Can radius of sphere colliders be changed?

warped trail
#

yesπŸ˜…

#

but beware that you are using pointer to collider

#

changing radius in one place will change radius in all places that uses this colliderπŸ€”

silver dragon
#

Seems I have to cache colliders for each radius I have. Otherwise it can't be used in parallel...

#

Or use distance query and filter out the points I don't need.

warped trail
#

look at Collector.cs in Physics package, there is simple example for custom collectorsπŸ‘

silver dragon
#

Yep, there are some examples. Thx for the hint!

unique mantle
#

(theoretical) say there's some sort of runtime loading system for, I don't know, rocket parts in kerbal space program? The part configurations describe several modules (Thruster, FuelTank, etc), and the modules are made up of several Components. What's the best way to group sets of components for use in this manner, to add to an entity in blocks?

bright sentinel
#

@unique mantle Going off of my KSP knowledge, they do it by parenting parts. So you have the main cockpit (or whatever your first part is) which is the root. Then it has different slots where other parts can connect, which are attached as children to the parent object in a specific slot. Those parts can in turn have childs etc.

unique mantle
#

No, parts themselves are made up of abstract modules, like a fuel tank might have a FuelTank module and a PhysicalProperties module and a Model module or something

#

And a FuelTank module could be made up of a lot of components

bright sentinel
#

Oh I see, in ECS you'd just do that with components then.

unique mantle
#

well yeah, the question I asked was what's the best way to group multiple components into blocks

bright sentinel
#

Hmm, what sort of blocks do you mean?

unique mantle
#

groups, rather, that can be added to entiteis

bright sentinel
#

Oh, like prefabs?

unique mantle
#

sort of like a prefab but not a separate entity

#

just a thing added onto an existing entity

#

it's easy enough to do manually but I was just asking whether ECS has it's own system for this

#

since this might be a potential problem in the future

bright sentinel
#

I'm stil not quite sure I understand exactly what you want. If you want an entity to have multiple components you can just add those components to the entity

unique mantle
#

Also, since often times systems and jobs use multiple components it's like you add a "MoveSpeed" component or something then wonder why it isn't going anywhere but then realize you actually need "MoveThingamagic" component for it to do anything

#

good for organizational purposes, so you don't forget a Component and have to do a lot of messing about to figure out why on earth your entity isn't doing anything

bright sentinel
#

Well that seems like a solution could either be a prefab thing, or [RequireComponent]

unique mantle
#

components can require other components?

bright sentinel
#

Well, not exactly. MonoBehaviors can require other MonoBehaviors, but if they're converted with the conversion system, then it's essentially the same thing

unique mantle
#

so that would require your own authoring component

#

instead of the autogenerated one

bright sentinel
#

Yeah, but it's not that hard to do. Either look at some of the samples or the generated code that the autogenerated one generates

#

You can pretty much copy that and implement it yourself

unique mantle
#

Cool

#

It would be nice to sort of make Component groups that you can add to an entity as a single group, prefabs annoyingly describe a full entity which means you can't do that

bright sentinel
#

You can make prefab variants

unique mantle
#

prefab variants have nothing to do with what I'm asking

bright sentinel
#

And again, you can do your own custom conversion with it πŸ˜„

unique mantle
#

not talking about prefabs, at all, just the ability to group components and add them to an entity as a single group

#

instead of having to faff about with adding them manually and spending three weeks figuring out why your entity doesn't work

bright sentinel
#

You could also keep those groups in a list, and then have some system automatically add those through whatever group you make

unique mantle
#

it's probably easy enough to have your own group system, yeah

#

also authoring scripts, I could just make a script titled "Door" that actually adds multiple components on conversion'

bright sentinel
#

Yeah exactly

#

But I still think you can achieve this with prefab variants

opaque ledge
#

yep and convert them to entities, and there you go you have an entity for each 'modules', you can give them IDs to identify them

#

this ECS approach tought me the importance of unique IDs πŸ˜„

unique mantle
#

I suppose the part loading code could just add multiple components per module to the thing as well if I ran into that situation

#

I fail to see how multiple entities per part would help here

opaque ledge
#

if your modules doesnt change on runtime you can make scriptable objects and put them into authoring component and convert them to entities

unique mantle
#

you can convert scriptableobjects into entities?

#

huh, that might be useful

#

since I was already a bit annoyed that entities had to have transform components because every converted gameobject happens to have a transform

#

data-only "non-physical" entities might be useful

opaque ledge
#

you can also have static methods in your struct to create a the module with certain values, lets say i have a weapon and lets say pistol has 10 damage 1 fire rate, rifle has 5 damage 3 fire rate, then i could make something like, Weapon.Rifle() => return new Weapon{damage = 5, fireRate = 3} and Weapon.Pistol()=>return new Weapon{damage = 10, fireRate = 1}

#

but i think SO approach is better

frail seal
#

Can I store an entity reference?

#

I need to make a node tree.

warped trail
#

I don't think the ability to group components and add them to an entity as a single group exists right nowπŸ€”

opaque ledge
#

you can make an Entity field and store your entity

autumn pond
#

Hello, I have a question regarding Project Tiny. Is there a way to get Mouse Wheel status within Tiny.Input namespace? Somehow I cant find anything in the docs -.-

warped trail
#

i don't think there is scroll wheel supportπŸ€”

#

at least there is no such thing in InputSystem

hollow sorrel
#

i'm trying to use UnsafeBitArray to set bits in an underlying ulong but result is always 0 when setting the last few bits, doesn't matter what value is passed
for example where (pos, numBits):
(32, 32) stays 0
(48, 16) stays 0
(56, 8) stays 0
even non-pow2 such as (47, 17) stays 0
but everything around it
(33, 33) is fine
31, 33) is fine
(33, 31) is fine

#

i can't figure out why this would happen thonking

#

maybe missing something fundamental about how bitmasks work
i tried checking the underlying code and it's not long but it reads like arcane magic to me

bright sentinel
#

i tried checking the underlying code and it's not long but it reads like arcane magic to me
Happens to me everytime I read someone elses code lol

autumn pond
#

@warped trail Ah ... I was afraid that might be the case ... and there is probably no other way how to get some mouse wheel inputs right?

warped trail
#

@autumn pond πŸ€·β€β™‚οΈ

hollow sorrel
#

https://hatebin.com/luokldyltn
is the implementation in case anyone wants to have a look
not sure how the numbers work (they are literally just num1 num2 etc)

frail seal
#

Can I directly set variable inside of a dynamic buffer element?

#

Without insertion and removal of elements

autumn pond
#

is there a way to check if an entity already has dynamic buffer added? Something like null check?

warped trail
#

@autumn pond there is this thingcs var bfe = GetBufferFromEntity<TestBuffer>(); bool hasBuffer = bfe.Exists(entity);

autumn pond
#

ah, will check that right out, thanks!

#

@warped trail That seems to be working, thanks!

junior fjord
#

do I understand it right that an ecb already gives me back the entity and I can immeadiatly use it to save it somewher? (just the actual creation of the components etc takes time)

safe lintel
#

yeah the entity id gets remapped when the buffer system plays back

junior fjord
#

thats perfect

#

thanks

warped trail
#

but you can't do this? πŸ€” cs var instance = ecb.instantiate(index, spawnerFromEntity.Prefab); spawnerFromEntity.ChildEntity = intance

zenith wyvern
#

Yeah the entity you get back from ECB is not valid outside that scope

#

You need to get the updated entity reference after the command buffer plays back

warped trail
#

but if you store it somewhere through ecb it will be fixed? πŸ€”

zenith wyvern
#

No, if you try to store the entity you get from ecb.createentity or ecb.instantiate, it won't work

#

You can do all the ecb operations on it like add/set components, etc, but you can't store a reference to it

warped trail
#

hmπŸ€”

zenith wyvern
#

do I understand it right that an ecb already gives me back the entity and I can immeadiatly use it to save it somewher? (just the actual creation of the components etc takes time)
@junior fjord

You can't save it anywhere

warped trail
#

but this worksπŸ€”

zenith wyvern
#

I'm not sure if you do it on the main thread like that, but if you do it in a job then the reference is garbage

#

Try creating the reference in a job then examining the entity with the reference inside the entity debugger

mint iron
#

but you can't do this? - i think you can do that, last time i tested it (in 0.6 maybe), if you add the entity to components using the same ECB it will batch them all to the correct values as it plays back.

zenith wyvern
#

Maybe I was doing something wrong then, I just tried doing exactly this a few days ago in 0.8 and it didn't work. I'll have to re-check

mint iron
#

mmm, perhaps im wrong, in his case spawnerFromEntity already exists somewhere else outside the ECB, so it can't be updated automatically. ill test it real quick.

warped trail
#

it worksπŸ€”

#

if you set it through ecb it fixes entity referenceπŸ€”

#

if my test is right πŸ˜…

junior fjord
#

but this probably won't work right:

var e = ecb.CreateEntity
var buf = ecb.GetComponent<B>(e);
buf.ResizeUnitialized(6);
FillThisBuffer(buf);
#

since the buffer isn't yet created

#

the ecb doesn't have some kind of smart thing to give me a buffer reference to something intermediate and copy the values to the right stuff later?

warped trail
zenith wyvern
#

Hmm, maybe that was my problem then, trying to write a reference to a dynamic buffer created at the same time

warped trail
#

@junior fjord there is no methods like this ecb.GetComponent<B>(e);

junior fjord
#

yeah it was pseudocode

#

GetBuffer something

warped trail
#

@zenith wyvern i recall June said that ecb does not like buffersπŸ€”

junior fjord
#

yeah exactly because of that probably, the buffer reference is not valid

#

where should it point

zenith wyvern
#

That really sucks, I need to add a new entity to a LinkedEntityGroup and it wasn't working, I guess that's why

#

Good to know that it works with a non buffer though

junior fjord
#

I now circumvented using the ecb by doing all work I can in another parallel system that just creates "command" entities and then one system that only runs through the command entities and does the entity creation and buffer stuff on the main thread

#

I only needed it for the case where a new tile gets flooded with water, which won't happen to often so I hope that is fine

mint iron
#

yeah, similar to what im doing now with these event things, just need somewhere to store the buffer elements, then patch the buffer headers after creating the entity later.

warped trail
#

but conversion system manages to fix Entity references in buffersπŸ€”

mint iron
fallow mason
#

anyone know how I'd do the equivalent of transform.up in dots?

#

looking at the boid samples for heading and its not clicking

zenith wyvern
#

Localtoworld.up

fallow mason
#

ooo love an easy solution

#

thanks @zenith wyvern

#

I was trying to do through Translation

warped trail
#

you can do this if your entity does not have parent πŸ€” cs math.mul(Rotation.Value, new float3(0,1,0))

fallow mason
#

I was actually thinking of doing that. I still might because I'm already querying for Rotation.

#

I'm doing a top-down movement system. Player clicks somewhere on a map and the player object first completely rotates to that position and THEN moves to it

#

having lots of trouble figuring out the rotation math

low tangle
#

yeah ecb's handle the entity ref for you and patch it @junior fjord @warped trail

#

SetComponent and AddComponent that have entity refrences inside of them get patched, and yeah I think buffer adds now do as well

warped trail
#

@fallow mason there is math.slerp(quaternion,quaternion,t)πŸ€”

fallow mason
#

hmm I will try

fallow mason
#

ah now I remember why I wasn't doing a straight lerp. I want linear rotation (but cannot easily store the starting rotation state to do so) so I have to get the angular distance somehow to do deltaTime / distance

junior fjord
#

SetComponent and AddComponent that have entity refrences inside of them get patched, and yeah I think buffer adds now do as well
@low tangle so you think this

var e = ecb.CreateEntity
var buf = ecb.GetComponent<B>(e);
buf.ResizeUnitialized(6);
FillThisBuffer(buf);

should work?

safe lintel
#

buffer is the thing that you might run into issues with if you fill it with any entity reference that is going to be command buffered

junior fjord
#

yes that is what I also think

#

just junes comment sounded differently and I wanted to understand what he means

#

I mean since the buffer is technically a pointer, and the space has not been allocated yet, I can only think of very complicated workarounds on how to make buffer stuff work in ecb

safe lintel
#

well my solution was just to make another job for the dynamicbuffer adds once the ecb had run(basically skipping a frame), tbh i dont recall seeing anything about dynamicbuffers & ecb's that changed in the updates but id love to know if something was changed

low tangle
#

AddBuffer<BufferType>()

#

not get component

junior fjord
#

yeah add buffer works

#

but not setting the contents

low tangle
#

the space is allocated

junior fjord
#

@safe lintel yeah that is what I do too

low tangle
#

within the buffer the ecb uses

#

its a stretchy malloc within the thread local memory

#

you can memcpy to it

#

which I do quite often

#

when the ecb runs creating entitys, it patches the ecb entitys

junior fjord
#

so the ecb allocs, you can set it and then afterwards in the ecb system, it copies over what you did to the chunk?

low tangle
#

if you look at them they have a version of 0 and a index of 1,2,3,4,5 and so on

#

yes

#

not chunk

#

they are a stretchy memory buffer

junior fjord
#

what do you mean by "patching" entities?

low tangle
#

so the stitching system later on just takes the real index and looks for all entity structs within the ecbs operations

warped trail
#

it fixes entity references in buffer πŸ€”

low tangle
#

and then changes them from the fake index of {10,0} to the real of {324234,123}

#

yes

safe lintel
#

wait so does that test succeed?

mint iron
#

yes

safe lintel
#

do you know which update changed this?

mint iron
#

mmmm, good question, i am on 0.8

junior fjord
#

thanks, that is interesting

fallow mason
#

hmm I guess I could store starting rotations and positions in a nativelist

junior fjord
#

this is the code for the ecb add buffer

internal BufferHeader* AddEntityBufferCommand<T>(EntityCommandBufferChain* chain, int jobIndex, ECBCommand op,
            Entity e, out int internalCapacity) where T : struct, IBufferElementData
        {
            var typeIndex = TypeManager.GetTypeIndex<T>();
            var type = TypeManager.GetTypeInfo<T>();
            var sizeNeeded = Align(sizeof(EntityBufferCommand) + type.SizeInChunk, 8);

            ResetCommandBatching(chain);
            var cmd = (EntityBufferCommand*) Reserve(chain, jobIndex, sizeNeeded);

            cmd->Header.Header.CommandType = (int) op;
            cmd->Header.Header.TotalSize = sizeNeeded;
            cmd->Header.Header.SortIndex = chain->m_LastSortIndex;
            cmd->Header.Entity = e;
            cmd->ComponentTypeIndex = typeIndex;
            cmd->ComponentSize = type.SizeInChunk;

            BufferHeader* header = &cmd->BufferNode.TempBuffer;
            BufferHeader.Initialize(header, type.BufferCapacity);
            
            cmd->BufferNode.Prev = chain->m_BufferCleanupList;
            chain->m_BufferCleanupList = &(cmd->BufferNode);

            internalCapacity = type.BufferCapacity;

            if (TypeManager.HasEntityReferences(typeIndex))
            {
                if (op == ECBCommand.AddBuffer)
                {
                    Interlocked.Increment(ref m_BufferWithFixupsCount);
                    cmd->Header.Header.CommandType = (int) ECBCommand.AddBufferWithEntityFixUp;
                }
                else if (op == ECBCommand.SetBuffer)
                {
                    Interlocked.Increment(ref m_BufferWithFixupsCount);
                    cmd->Header.Header.CommandType = (int) ECBCommand.SetBufferWithEntityFixUp;
                }
            }

            return header;
        }

they really reserve spacec for the the buffer and then return a pointer to that intermediate location for now.

#

and in playback it is probably copied over

#

oh can I somehow make that code expandable?

#

so that it doesn't block everything

warped trail
#

@fallow mason why not just have some value like MaxRotationSpeed and then calculate if you need to rotate, rotate with MaxRotationSpeed ?

junior fjord
#

hmm but what did june mean with the fake indexes? the ecb immediatly returns the right entity index?
Did he mean that the cmd->Header.Entity here has some fake entity index for now?

warped trail
#

ecb does not return right index

fallow mason
#

Not sure I understand. Limiting to a max speed won't change that the rotation speed varies through the rotation.

junior fjord
#

wait so if I would do

var e = ecb.CreateEntity();
myEntityMap[x, y] = e;

I would have a problem
@warped trail ?

fallow mason
#

The only way to get the linear interpolation is if the start and end rotations do not vary.

#

or adjust deltaTime with the inverse of remaining distance

#

as far as I know πŸ€”

warped trail
#

maybe im wrong about CreateEntity, but instantiate returns negative indexπŸ€”

junior fjord
#

yeah no I think you are right thanks

#

and thanks for the vid

#

always hard to find where to get the valuable information from, it is so scattered πŸ˜„

#

it would be very weird if CreateEntity would return a valid id and Instantiate not

warped trail
#

CreateEntity is returning negative index too

#

just checked it πŸ˜…

junior fjord
#

I think it has something to do with it just not being possible. Funny, I would have thought that returning a valid entity id right away and then afterwards just copying the data to the right location would be easy, and making the buffers work right away would be hard

#

seems that it is the other way around πŸ˜„

#

ah ok yeah thanks πŸ™‚

warped trail
#

@fallow mason you need to rotate in constant time or speed?πŸ€”

fallow mason
#

speed. sorry I keep conflating linear interpolation and speed.

mint iron
#

the do return a negative index, its a placeholder. They need a placeholder because the entity doesn't actually exist until PlayBack() is called. Then they must go through and find all the Entity references you used, and replace them with the proper value.

fallow mason
#

I think I'm going to need to store starting rotations and positions. It will just make the lerp parts more straightforward.

warped trail
#

@fallow mason something like if my rotation is not equal to desired rotation, rotate me with constant speed towards desired rotation, no ?

fallow mason
#

exactly

#

so i need to compare relative angle and also take the shortest path there. no rotating 270 degrees. -90

zenith wyvern
#

This fails

warped trail
#

@zenith wyvern you have to set buffer via ecb

#
var newA = ecb.CreateEntity(entityInQueryIndex, arch);
var buffer = ecb.SetBuffer<LinkedEntityGroup>(entity);
buffer.Add(new LinkedEntityGroup{...})```
zenith wyvern
#

Ohh, so I can't use the buffer I pass into the lambda?

warped trail
#

i guess noπŸ€”

zenith wyvern
#

Huh, you were right, that works

#

That's going to save me a huge headache, thank you

#

Very strange that it doesn't work with the normal buffer, but I'll just take it as a necessary evil

warped trail
#

@fallow mason you can use cross product do determine +- of rotation

#

oh, not cross product, dotπŸ˜…

#

direction to your target with local right vector

junior fjord
#

@zenith wyvern you can check the youtube link that druid posted above, it does not work with the normal buffer because newA is not a valid Entity yet, it is just a placeholder

zenith wyvern
#

I will do that, thanks

#

The API naming for that is kinda weird though, they called it "SetBuffer" but you're getting back the buffer that you're operating on

#

Not sure what would be better but that doesn't feel right

warped trail
#

there is AddBuffer too πŸ˜…

#

but yeah it is confusing, i was expecting something like cs ecb.SetBuffer(entity, new BufferElement{...})

zenith wyvern
#

Exactly. I feel like at least they should let you change the existing buffer then pass it in, but even that is kinda confusing since you're already operating on it by reference and would expect it to just work

#

I'm going to make a thread about it

junior fjord
#

why is there actually so little show off in this channel? I would really like to see what other people are doing/did with dots already

warped trail
#

i don't think there is a lot of stuff πŸ˜…

zenith wyvern
#

I usually only post show off stuff to the forum

junior fjord
#

your account is sarkhan probably?

#

@warped trail I even mean small stuff

#

like just a gif of something cool that is working πŸ˜„

#

I really like to see that kind of stuff, somehow it always motivates me

#

especially if its something cool that can inspire you

opaque ledge
#

there is RTY project going on, i think its pinned on forums, you can check that out πŸ˜„

fallow mason
#

blue is "forward" vector, green is target direction

#

only 3 degrees difference lol

zenith wyvern
#

your account is sarkhan probably?
@junior fjord

Yes

#

Well, Sarkahn

warped trail
#

@fallow mason math operates with radiansπŸ€”

fallow mason
#

I know, I know. Still, not 3.2 radians there.

warped trail
#

how are you calculating angle?

fallow mason
#

this is just for my authoring monobehaviour so I can have some gizmos, so it's not what I've been trying recently for my system

#
private void OnDrawGizmos()
    {
        Debug.DrawLine(transform.position, new Vector3(Value.x, Value.y, transform.position.z), Color.green);
        Debug.DrawLine(transform.localPosition, transform.localPosition+transform.up * 2, Color.blue);
        Handles.Label(transform.position + (transform.up * .9f) + (transform.right * .5f), string.Format("{0}Β°", Quaternion.Angle(transform.rotation,Quaternion.Euler(transform.position-new Vector3(Value.x, Value.y, transform.position.z)))));
    }```
junior fjord
#

@opaque ledge rty?

opaque ledge
#

RTS

#

real time strategy

junior fjord
#

ah you mean this huge thing

#

yeah I have seen that, very impressive

warped trail
#

it is mobile game, no? πŸ€”

opaque ledge
#

Well, other than that i am working on a project as well, buts its on very early stages πŸ˜„

junior fjord
#

by eizenhorn or something? that is not a mobile I think

opaque ledge
#

i also know of someone that published a game using DOTS, but not sure if he like to have his name around

junior fjord
#

yeah but the kind of gifs where you just see that finally the 100 spaceships are following their leader or stuff can be cool too πŸ˜„ even if it is just to start off a discussion on how someone did that

warped trail
#

@fallow mason this is too complicated for me πŸ˜…

fallow mason
#

lol same

#

probably an easier solution

warped trail
#

isnt there Vector3.Angle method?

junior fjord
#

you can just take the inverse cosinus of the dot product @fallow mason

warped trail
#

or you can use acos(dot(A,B))

junior fjord
#

well you need to normalize it

warped trail
#

but normilize A,B

junior fjord
#

haha yeah πŸ˜„

warped trail
#

πŸ˜…

junior fjord
#

so arccos(dot(A, B)/(dot(A,A)*dot(B,B))^0.5)

opaque ledge
#

@junior fjord if you are talking about my gif, there is no following leader, every ships gets a target and they attack it, unfortunately i have trouble about how to do aggro management, so targeting is all over the place πŸ˜„

junior fjord
#

haha no I did not see your gif, is it in this chat?

#

Can I switch to only media somehow?

#

that was just a random example

fallow mason
#

sorry, wrangling my 21-mo-old who I guess does not want to watch disneynature chimpanzee

opaque ledge
#

oh lol, its a coincidence then πŸ˜„

fallow mason
#

thanks @junior fjord @warped trail I'll give that a try

junior fjord
#

@opaque ledge oh that is pretty cool

#

haha but yeah their strategy is optimizable πŸ˜„

#

are you using hybrid renderer or graphics.drawmesh?

opaque ledge
#

hybrid renderer

junior fjord
#

is the physics stuff tied to hybrid renderer in any way? I never used physics yet

opaque ledge
#

well they are all parts of DOTS, but i dont think its necessarly 'tied' to hybrid renderer

#

i mean they are all tied together anyway

safe lintel
#

you can use physics without the hybrid renderer

fallow mason
#

now to figure out the ecs way to do it

warped trail
#

acos(dot(a,b)) to find angle, and dot(toTarget, right) to find sign

fallow mason
#
            float3 dir = math.normalize(new float3(moveTarget.Value, 0f) - translation.Value);
            float angle = math.acos(math.dot(dir,ltw.Up));
            float sign = math.dot(dir,ltw.Up);
            Debug.Log(math.degrees(angle)+" : "+ math.degrees(sign)); //101.0919 : -11.02272
#

moveTarget is a float2. ltw.Up is my 2d "forward" direction

#

I'd expect math.degrees(angle) to equal the 137 I'm seeing in my gizmo :\

junior fjord
#

if you want the direction you need to take the dot product with your "right", not your forward as druid indicated

fallow mason
#

why would that matter? woudln't it just offset by 90?

junior fjord
#

if you take the dot product with your right, then it is positive if the direction is on the right side of you, else negative

fallow mason
#

ok, well I switch to right and now my debug is 100.0683 : -10.01659

junior fjord
#

about why the angle is wrong, I don't know. Why do you subtract translation.value in the first line and use ltw.Up in the second line

#

your angle now changed, did you move something in the editor?

fallow mason
#

I subtract the translation position from the target position to get the direction

#

no I didnt move anything, just changed the ltw from Up to Right

junior fjord
#

but the first number changed too

#

no only the ltw.Up in the third line needs to be changed

#

not in the second

#

and I just wondered since I guessed that the position and the upwards direction are saved in the same struct and you use translation.Value for your position and ltw.Up for your upwards direction

#

ah and you don't need to take math.degrees sign, you are only interested in the sign of sign for now

fallow mason
#

yeah that was the impression I got. which is fine. the target angle is indeed to the left of ltw.Up.

#

but the angle itself is not correct

#

just don't know enough trig to even guess what I'm doing wrong

pliant pike
#

I'm stuck leahYTHO I don't suppose anyone knows how incrementing a variable in a job by 0.001f can make the value jump in one frame from 0.04 to 0.121

fallow mason
#
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

public class MovementSystem : SystemBase
{

    protected override void OnUpdate()
    {
        float deltaTime = Time.DeltaTime;
        Entities
            .WithoutBurst()
            .WithNone<Cooldown>()
            .ForEach((ref Rotation rotation, ref Translation translation, in LocalToWorld ltw, in Move2DTarget moveTarget) =>
        {
            float3 dir = math.normalize(new float3(moveTarget.Value, 0f) - translation.Value);
            float angle = math.acos(math.dot(dir,ltw.Up));
            float sign = math.dot(dir,ltw.Right);
            Debug.Log(math.degrees(angle)+" : "+ math.degrees(sign)); //101.0919 : -11.02272
            //rotation.Value = math.slerp(rotation.Value, quaternion.Euler(new float3(moveTarget.Value.xy, 0f)-translation.Value),deltaTime);
        }).ScheduleParallel();
    }

} 
#

really simple system. MoveTarget only stores a float2.

warped trail
#

@pliant pike because you are changing your floatVal all over the place πŸ˜…

junior fjord
#

ah ok there someone else can help better I think, I don't know how unity stores stuff in ltw and translation

#

but if translation.Value is your current position and ltw.up your current forward it should be right. shouldn't there be some kind of position in ltw too? I don't know what translation is

fallow mason
#

really just using ltw to get the local forward

pliant pike
#

@warped trail I'm not I'm only changing it one place leahYTHO

warped trail
#

you change you code from last time? πŸ€”

pliant pike
#

I've reduced it to one entity with one variable I'll show you the output if I can

warped trail
#

@fallow mason wait, ltw.up is your forward?

junior fjord
#

@fallow mason hmm the code is right, I guess the problem is what is stored in translation.Value and in ltw

#

and I have no idea about that

fallow mason
#

I thought translation was == the position of the Transform component and ltw was the float4x4 of the TRS combo

#

@warped trail yes. it could just as easily be right though

#

not a horizontal platformer. top down. player can move in any direction on the xy plane.

#

but no particular need for it to be up. just how I drew the sprite really lol

pliant pike
#

I don't know if that helps to explain, timedelta is the value being increment outside the job and is correctly incremented

#

placeonspline is the value inside the job which I'm also incrementing in exactly the same way and getting the crazy values from

warped trail
#

why are you incrementing delta time?

pliant pike
#

I'm just doing it as a test so I have a consistent value and can see I still get inconsistent results

warped trail
#

can you show the code?

pliant pike
#

sure

opaque ledge
#

Wow, you are trying to work out this Spline moving for a long time now

pliant pike
#

yep, I had it working when it was only one entity that had to move

opaque ledge
#

so its the Time.DeltaTime gives you an issue ? iirc you said its working fine if its on main thread?

warped trail
#

have you tried to comment this line ?cs placeonSpline.floatVal = math.saturate(placeonSpline.floatVal);

pliant pike
#

yep, second one you mean?

warped trail
#

and this cs placeonSpline.floatVal = math.saturate(placeonSpline.floatVal) * Curvecount; i = (int)placeonSpline.floatVal; placeonSpline.floatVal -= i; i *= 3;

pliant pike
#

@opaque ledge yeah using placeonSpline.floatVal += timeaccumalator; inside the job doesnt work

warped trail
#

you are changine floatVal in 2 places πŸ€”

pliant pike
#

@warped trail if I remove that it just breaks it, makes it only go through one curve

warped trail
#

but what about values?

pliant pike
#

how so?

warped trail
#

if you comment everything, is it incrementing ok?

#

just comment everything elseπŸ˜…

junior fjord
#

lol components using floats are initialized as NaN, not as 0? πŸ˜„

pliant pike
#

I'm using the debuglog to check the floatval right after its changed

junior fjord
#

would have never expected that

pliant pike
#

placeonSpline.floatVal += timeaccumalator; thats where the problem is

warped trail
#

yeah, but after debuglog you are changine floatVal in 3 places πŸ˜…

pliant pike
#

yeah you have to because you have to calculate it across a whole spline

warped trail
#

is cs placeonSpline.floatVal += timeaccumalator;working correctly if you comment this lines ```cs
placeonSpline.floatVal = math.saturate(placeonSpline.floatVal) * Curvecount;
i = (int)placeonSpline.floatVal;
placeonSpline.floatVal -= i;
i *= 3;

placeonSpline.floatVal = math.saturate(placeonSpline.floatVal);``` ?

pliant pike
#

def not that just breaks other variables

fallow mason
#

would it be possible to make placeOnSpline less responsible for resetting when it moves to a different curve? Like keep it always a 0-1 value but have your system figure ot which curve its on?

#

like a 4 curve spline .25 would mean 0 on the second curve?

pliant pike
#

that's what the above code does though

warped trail
#

@pliant pike you have to make your job not touch placeonSpline.floatVal if not necessary πŸ€”

#

increment placeonSpline.floatVal and make everything else use copy of that value

pliant pike
#

how leahWTF that's the whole point of placeonspline

warped trail
#

after this line cs placeonSpline.floatVal = 1f; everything should use copy

fallow mason
#

yes, exactly what I'm talking about ^

warped trail
#

and you will find out, that placeonSpline.floatVal is incrementing correctly πŸ˜…

fallow mason
#

right now placeOnSpline is operating as placeOnCurve

pliant pike
#

you mean like this ``` placeonSpline.floatVal += timeaccumalator;

        var tempval = placeonSpline.floatVal;```
warped trail
#

yes

pliant pike
#

when I check tempval its still coming up with the crazy results though

warped trail
#

what about placeonSpline.floatVal?

pliant pike
#

they have exactly the same values

warped trail
#

that means your code is the culprit πŸ˜•

pliant pike
#

who knows what's the culprit I'm lost leahWTF

#

anyways thanks for the help guys I may have to give this one up

warped trail
#

my bet it is this part cs placeonSpline.floatVal = math.saturate(placeonSpline.floatVal) * Curvecount; i = (int)placeonSpline.floatVal; placeonSpline.floatVal -= i; i *= 3;πŸ˜…

pliant pike
#

that's below where I'm taking the debug from though

#

in the above screenshot of debug.log it should be incrementing by 0.001 but its not

warped trail
#

whait you printet wrong values πŸ€”

#

you should debug.log timedeelta and placeonSpline.floatVal

pliant pike
#

no the job is

#

its supposed to be adding 0.001 each loop but its jumping to 0.306 to 0.92 in one frame and then down to 0.763

opaque ledge
#

so placeonSpline.floatVal += timeaccumalator; doesnt add 0.001 ?

pliant pike
#

nope 🀷

opaque ledge
#

wtf πŸ˜„

warped trail
#

ok i tested this cs placeonSpline.floatVal = math.saturate(placeonSpline.floatVal) * Curvecount; i = (int)placeonSpline.floatVal; placeonSpline.floatVal -= i; i *= 3;

#

and it is not working

opaque ledge
#

πŸ€”

pliant pike
#

how so πŸ€”

warped trail
#

what placeonSpline.floatVal should be after this code is executed?

pliant pike
#

like imagine placeonspline is 0.5 that means it should be the middle of the spline

opaque ledge
#

are you checking every single variable's value to see if they work correctly ?

warped trail
#

the code above is changing floatVal

#

you can just check it in MonoBehaviour

pliant pike
#

the code you posted above does change the floatval but then it changes it back

warped trail
#

no πŸ˜…

pliant pike
#

I'm pretty sure the above code does work correctly

#
            Bezpoint2 = booked.Bezzypoint[i + 1];
            Bezpoint3 = booked.Bezzypoint[i + 2];
            Bezpoint4 = booked.Bezzypoint[i + 3];```
#

it assigns those points so its calculating the correct curve

warped trail
#
floatVal += Time.deltaTime;
floatVal = math.saturate(floatVal) * Curvecount;
var i = (int)floatVal;
floatVal -= i;
i *= 3;
Debug.Log(floatVal);```
#

just check it in MB yourself

pliant pike
#

MB?

warped trail
#

MonoBehaviour

#
public class TestMB : MonoBehaviour
{  
    float floatVal = 0;
    int Curvecount = 24;
    // Update is called once per frame
    void Update()
    {
        floatVal += Time.deltaTime;
        floatVal = math.saturate(floatVal) * Curvecount;
        var i = (int)floatVal;
        floatVal -= i;
        i *= 3;
        Debug.Log(floatVal);
    }
}```
pliant pike
#

if I go through the value and assume floatval is 0.5 which should be in the middle of the spline then math.saturate(floatval) * curvecount = 12

#

var i = 12

#

0 -= i;

warped trail
#

wait a minute πŸ˜…

#

but floatVal is 12

#
floatVal = math.saturate(floatVal) * Curvecount; //0.5 * 24 = 12; floatVal = 12;
var i = (int)floatVal;// i = 12
floatVal -= i;// floatVal = 12 - 12 = 0
i *= 3;```
pliant pike
#

-= removes 12 from the floatval

warped trail
#

yes

#

and floatVal becomes 0

pliant pike
#

yep

#

which is correct

warped trail
#

but it was 0.5 in the begining

pliant pike
#

yeah but theres sets of curves all in a spline and its calculating which spline its on

#

so its at the beginning of curve 36

warped trail
#

so you just travelled from middle of your spline to the begining

pliant pike
#

which should be the middle

warped trail
#

your floatVal should go from 0 to 1

#

but you went from 0.5 to 0

#

backwards

pliant pike
#

yeah that's because its adding curves into a group that is called a spline

#

and its finding each curve in that group/spline by using the above code to find exactly where it is in that group

warped trail
#

so at floatVal = 0 you are at very begining of your spline that consists of many curves ?

#

at floatVal = 0.5 you are in the middle

pliant pike
#

yes

warped trail
#

and at floatVal = 1 is the end

pliant pike
#

yes it divides that value by the number of curves basically to get exact position of where it is

warped trail
#

but in one step you went from middle of your spline(0.5) to the very begining ( 0 )