#archived-dots
1 messages · Page 20 of 1
yeah, they can't
it would even be split into different chunks
so impossible really
Yeah, that's why I was wondering if this is something that can be done without turning off the system, but I guess it's a pretty niche use case
i have never used sharedcomps so i'm not even sure the safety system is too dumb to understand that. i trust tertle though 🙂
Yeah this is the single shared component I use, I think for this use case it's all right, but I really don't like them
It should make it very efficient to fetch all entities belonging to a "world" in my case though, so maybe it's fine the way it is
yep, me neither. have not found a single good use case for them
i don't even think worlds are a good use case
why not go the route of setting up entities worlds?
I used a lot of shared comps to geographically separate entities by location.
and for the sake of understanding i call your concept now layers 🙂
Too complicated with the networking system, I need to send networking information to players even if they are in a different world
Also these "worlds" can be used as a shortcut for pathfinding requests. E.g. you could walk somewhere, swap world, keep walking, swap again, and then arrive at your destination, using a shorter path than if you had walked normally
I think that'd be pretty complicated using completely separate ECS worlds
haha yeah what you do sounds really involved
probably why I'm making progress at a snails pace >_>
but that's the advantage of it only being a hobby, I can just never release it!
lol
Really liking netcode a lot more than monobehavior based networking solutions
the netcode devs know their stuff
that, but it's also just the paradigm. dots is great for just sending stuff over the network. you basically trade bandwidth for ease of use and server performance
can't access static methods from a struct that implements an interface QQ
at least not in our c# version
now i have to write dumb code AvatarStatsIndexer statsIndexer = default; var statIndex = statsIndexer.GetStatIndex(avatarStatType);
I somehow broke ECBs :[
=================================================================
Managed Stacktrace:
=================================================================
at <unknown> <0xffffffff>
at System.Object:wrapper_native_000001E116B11F00 <0x000a7>
at <Module>:invoke_void_intptr_int_intptr_int_int <0x000b9>
at Unity.Entities.ECBInterop:_forward_mono_ProcessChainChunk <0x0004c>
at Unity.Entities.ECBInterop:ProcessChainChunk <0x00062>
at EcbWalker`1:WalkChains <0x0076a>
at Unity.Entities.EntityCommandBuffer:PlaybackInternal <0x00322>
at Unity.Entities.EntityCommandBuffer:Playback <0x0003a>
at Unity.Entities.EntityCommandBufferSystem:FlushPendingBuffers <0x0042a>
at Unity.Entities.EntityCommandBufferSystem:OnUpdate <0x0002a>
at Unity.Entities.ComponentSystem:Update <0x00215>
at Unity.Entities.ComponentSystemGroup:UpdateAllSystems <0x00373>
at Unity.Entities.ComponentSystemGroup:OnUpdate <0x00042>
at Unity.NetCode.ServerSimulationSystemGroup:OnUpdate <0x0039a>
at Unity.Entities.ComponentSystem:Update <0x00215>
at DummyDelegateWrapper:TriggerUpdate <0x0002c>
at System.Object:runtime_invoke_void__this__ <0x00087>
probably some entity that doesn't exist or setComp on an entity that doesn't have the comp
That crashes unity?
iirc it only throws an exception
This is the last error message I get, I have no idea where it's coming from though
System.NullReferenceException: Object reference not set to an instance of an object
This Exception was thrown from a job compiled with Burst, which has limited exception support.
0x00007ff692a1b1d5 (Unity) aligned_free
0x00007ff68ff5e6bc (Unity) MemoryManager::Deallocate
0x00007ff68ff5e3a2 (Unity) MemoryManager::Deallocate
0x00007ff68ff6747a (Unity) free_alloc_internal
0x00007ff68f95a69b (Unity) UnsafeUtility::Free
0x00007ff68f847df3 (Unity) UnsafeUtility_CUSTOM_Free
0x00007ffab1022104 (095060945a0a00b25d2dd62b054f140) [UnsafeParallelHashMap.cs:208] Unity.Collections.LowLevel.Unsafe.UnsafeParallelHashMapData.DeallocateHashMap
0x00007ffab1022961 (095060945a0a00b25d2dd62b054f140) 59142aef52ef9b6ab273da58974494a1
0x00007ff6902735e0 (Unity) ExecuteJob
0x00007ff6902747ef (Unity) ForwardJobToManaged
0x00007ff69026fac0 (Unity) JobQueue::Exec
0x00007ff69026fd7a (Unity) JobQueue::ExecuteJobFromHighPriorityStack
0x00007ff690270309 (Unity) JobQueue::ProcessJobs
0x00007ff69027236f (Unity) JobQueue::WorkLoop
0x00007ff69046ad47 (Unity) Thread::RunThreadWrapper
0x00007ffb7cba7034 (KERNEL32) BaseThreadInitThunk
0x00007ffb7e982651 (ntdll) RtlUserThreadStart
looks like something outside of my code
ignore subsequent errors. most likely a cascading problem
first ones are the most important
do you have safety off
I'm curious what people think about the best way to design an ECS tween library. I've seen a few different approaches but they all seem to be some flavor of the following:
A) Tween components that can be added to an entity. There are different components for each type of tween (position, rotation, scale, etc.)
B) A polymorphic tween that is added to an entity. The same component can be used for different types of tweens.
C) Separate tween entities with a reference to the entity being tween
The main advantage of A and B over approach C is there is no need for random memory access to tween an entity. I'm currently using approach A simply because I didn't want to deal with the complexity of a polymorphic component. However, there are some advantages of approach C. Entities don't need to store a bunch of empty components when they aren't actively being tweened. This is especially nice for entities that don't need to be tweened often. It also seems much easier to write a nice API to handle things like chaining multiple tweens and interrupting tweens. It even allows a single tween entity to be responsible for tweening multiple target entities.
Are there other things I should consider? Any other approaches I should think about?
how can i register this job?
the TStatBuffer_Final is defined in the SystemBase class. do i need to explicitly make this job generic too?
What do you mean by register?
i need a RegisterGenericJobType attribute for a generic system
i get no compiler errors but on run i get: Reflection data was not set up by a call to Initialize()
Huh, I didn't even know that was a thing
Did you define the attribute?
(I'm guessing yes)
I'm confused though, what part of your job is using generics?
This line is throwing a nullreference exception, very odd
It's inside UnsafeParallelHashMap
The call triggering it is UnsafeParallelHashMap.GetKeyArray
means you've corrupted your hashmap
It's empty 😬
unsafe
imo it's unassigned
I check UnsafeParallelHashMap.Capacity in the line above GetKeyArray, and it tells me 100, which is what I set it to
you've broken it somehow
as I say, use unsafe containers suffer the painful consequences
oops
that was the previously not-in-a-component local hashmap
so you were spot on
what a rewrite ... finally got everything working again. what a relief 😄
i think @rustic rain might have worked on porting a tween library, not sure what his progress was
Thanks! I think I saw some posts from them and I believe they were going with the polymorphic approach
Regards the difference between A and B, i think tertle had suggested recently that it can be faster to combine for example separate jobs into one more complicated job, so i wouldn't necessarily be afraid to just put it all into one component and go from there
I know it doesn't really answer your question, but personally i'd consider building something that works first, and then optimize from there
Whether it's separate tween entities, or not
Yeah, I have something working with option A right now. But I now have a use case where I need to chain multiple tweens. To do so, I was going to switch over to storing tweens in DynamicBuffers. But then I started wondering if I should totally rework it to use separate tween entities instead.
if you want maximum performance I wouldn't use dynamicbuffers to be honest
Why's that?
I guess if the internal capacity is exceeded, its going to be doing random memory access anyways to access the buffer elements
they are slow to get, if you've got a bunch of them on entities
I've made faster code by just prechaching dynamicbuffers into a single nativearray
Interesting. So without buffers, how would you support multiple tweens on the same object?
I guess it depends how much performance you're trying to squeeze out.. How many entitie's you'll actually have etc.. Is is 100's of thousands or a few hundred.. I've been hesitant to use Db's for that reason but used them anyway just to get the job done and it's fine
yeah it does depend on how performant you want it
I'm not sure how you would do it without buffers though to be honest 🤔
NativeParallelMultiHashMap is one option
Probably tweening somewhere in the ballpark of a few thousand entities at most I'd guess.
Hmm yeah, could use a native collection on a system or class component
but you'd have to permanently store them in a system
it would be limiting to get them
or in a class IComponentData on a singleton, but yeah
Why not put it in a component
there's nothing wrong with storing native containers in a system
I currently do it in a few places but I find that it is easy to run into dependency issues.
I've been considering migrating those uses cases to storing in a class component for that reason
well it's best only the system that has it uses the container
getting the class comp has a lot of overhead
Wouldn't something like a tween library need multiple writers?
just use World.GetExistingSystem to get your SystemBase class that has the nativecontainer
That's why you use an unsafe collection and break everything 
Does accessing class components have more overhead than accessing a class SystemBase?
depends on implementation. the tween can be split into static data and dynamic data
yes
getting a class comp needs to go through a query
unless you cache it somewhere
Yeah, I'm talking about storing the native collection on a singleton entity. And that query would be cached on any system that accesses it
that the query is cached is a given. i mean going through GetSingleton<T>
using a class comp also means not being able to burstcompile and that's a big loss
unless it's just a wrapper and you feed the value to a job
I would be doing this on the main thread before scheduling jobs. i.e.
var myTweens = GetSingleton<MyTweens>();
// Alternatively
// var myTweens = World.GetExistingSystem<MyTweenSystem>().MyTweens;
Entities.ForEach((Entity entity) => { myTweens.AddTween(entity, blah); }).Schedule();
This should work with burst, right?
MyTweens would be some class ICD storing a native container for all tweens in the game
Is it possible to schedule an IJobParallelForDefer using a dynamic buffer on an entity as a dependency somehow?
the class won't work with burst. (no class will work with burst) only structs and the native container itself
yeah you're right. Should be var myTweens = GetSingleton<MyTweens>().MyNativeCollection;
why would you need a defer job for a dynamic buffer?
dependency should be enough as scheduling a DB doesn't need information on the length or capacity
I actually never considered storing a native collection in a singleton class component until recently. There was some post by @storm ravine on the forums mentioning something like that. Seemed like a great way to solve the dependency issues where multiple systems need to access the same native collection.
how recent is that post? must be pretty old i guess.
hmm thought it was recent but I'll try to find it
My first dots project i had a task system for units which did rely on db's and worked like this:
So there was a separate buffer for each task type
And a buffer to stack up / chain together a bunch of tasks
No, I want to schedule an IJobParallelForDefer and use a dynamic buffers length on an entity as the array length property. I'm guessing this isn't possible though
From a week ago: https://forum.unity.com/threads/how-to-organize-the-data-for-flowfield-pathfinding-what-datastructures-to-use.1331418/#post-8416185
oh hm, yeah that's a tough one. the NativeList has a method for it but if you look at it, the code is really weird, casts to a NativeArray and patches the length. i have no idea how to trigger that for a DB
Eh, it's probably an issue with my design anyways
I'm guessing the easiest way to do it is to schedule a job that writes the buffer's length and that is then used to schedule the deferred job
thanks for posting. i mean, it's okay. it works. i just don't think it's a great way to do that. there are a lot of dependencies anyway on the class then. you could make a singleton class and just not store it in entities at all. the differences really do not matter though when talking about performance. just choose what you like more
hm, that would only work with a .Complete in between.
Why? I can pass the handle to the next job
i thought you want to schedule the length of the buffer?
Yeah, you can pass an int* to deferred job
so something like (int*)NativeReference<int>.GetUnsafePtr() might work?
oh nice. ok, with that you can just get the ptr to the length itself.
UnsafeUtility.AddressOf<int>(ref buffer.Length)
What's buffer? That's a recipe for an asynchronous stack overwrite if it's a value type
I burnt out xD
Hi guys! I was researching: how to convert a GameObject to Dots. Is it really as easy as installing the three packages and checking the 'ConvertToEntity' check-box or am I missing things?
wrote a full tween library like 3 years ago for entities, never used it
was the cool thing to do at the time
rather than a useful thing for me =\
yeah haven't touched it in 3 years
haha yeah....
it's way way more complex
I was so close to writing tween library using your approach (with dynamic buffer)
but polymorphic components didn't support blobs
🕯️
Sorry I forgot to mention I'm using Dots 0.51.1 out 8/2/2022. I ran a test where it does seem to convert my GameObjects to Entities and is quite a bit faster. Is this maybe just the beginner's approach. I would imagine creating your own entities would result in much more optimal results...
yeah, but it's not nearly as simple as just converting game objects
all logic will have to be reimplemented in ECS
Got it. Using the Jobs system I presume.
Is there a good overview of 0.51.1 that you know of?
Thanks!
There is a huge issue if container not read only and some jobs write some read to that container, “just singleton class” wouldn’t work if you want non-breaking schedule chain, without completing dependency chains here and there. With ICD singleton and our own dependency mechanism for them we avoid that and all the jobs working with that containers safely scheduled and properly chained against each other.
You just lazy
There's way to have read-only container stored in class and then accessed through pointer
I’m aware of what possible and what not 🙂 Again - it wouldn’t help if some jobs read and some >write<, read carefully 😉 And tbh there is no point to use FP for global read only container - just use simple singleton and pass to job
(this channel is populated by a group who don't believe in safety 😅)
This is why I rarely come here
only because someone mentioned me out loud
And don’t tell them about race conditions for the sake of god @rotund token
Thread safety was invented by government to control us
😅
I personally don't care about thread safetly so long as I can disable it during tests and release builds (which you can) 
also
Unity Physics is causing GC to deallocate almost 3MB of garbage every couple of seconds... causing on average ~140ms of lag
also SimulationSystemGroup seems to take 83ms ?? weird...
can you expand the group further to see exactly where the garbage is being created
yeah one second
wait hold on it's one of my systems... could of sworn it wasnt last time I checked
Wait, no it actually isn't one of my systems... my system only allocates 1kb every fixed frame, and this momentary lag happens every ~3-15 seconds
For whatever reason this seems to be the cause:
Well thats... editoronly
yes, but trying to find where tf it is coming from is annoying
Probably because you have jobs debugging on or something similar
well time to deep profile the editor 
Ok for whatever reason the editor is allocating a fat native array every couple of seconds and it makes zero sense
Hmm.. never recall turning it on.. but yes, for that particular source of lag it was the cause
yeah that creates huge garbage
what is the best way to get the fixed delta time? Time.DeltaTime seems to still be affected by lag
Time.fixedDeltaTime inside your system should do it
i guess the first question is why?
(SystemBase.)Time.DeltaTime will be fixed time
inside of your FixedStep group
because everytime there is a slight lagspike it send all my physics elements flying all over the place
ohh really, i didn't realise that
useful to know
yes welcome to unity.physics
since default unity is set to fix step of 50fps
while unity fixedstep group is 60fps
yeah i'd noticed that i think
i think the fixed rate manager is inited with 60 right
yes
i remember trying stuff like updating that per frame to account for lag etc trying to prevent the spiral, was messy and confusing times
doesn't make any sense for this to happen. It never does in physX
yeah i don't think i ever figured it out tbh, although i've not seen it in a while
for example you click away from the editor, then click back and everything explodes
yeah it really screws me over when preforming tests
is your rate manager the default or is it set to null?
trying to remember if that caused it
don't do this but it's here:
World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<FixedStepSimulationSystemGroup>().RateManager = new RateUtils.VariableRateManager();
by default RateManager is initialized with FixedRateManager
which really is the safest thing to keep it at
you can set it to null, which i found gave much better performance, but it comes at a cost of instability
so i was wondering, had you nulled that out and that's why you were getting explosions
I didn't even know it existed until now, so no I didnt
1.0 cant come fast enough 
next question would be, are you changing PhysicsVelocity components outside of FixedStep group
No it's all within this group: FixedStepSimulationSystemGroup
and it's before: BuildPhysicsWorld
Trying to remember the conditions under which everything explodes on lag spikes..
hmm
Is everything actively colliding at the moment it explodes
yes, but actually no
it's a custom vehicle that uses raycasts
so it's basically hovering
if you're raycasting you should be doing it after BuildPhysicsWorld
otherwise you're using previous frame data
have you tried
[UpdateAfter(typeof(BuildPhysicsWorld)]
[UpdateBefore(typeof(StepPhysicsWorld)]
yeah it's deliberately before
there's no concernable difference between before/after regarding the lagspike
strawman much?
YOO
I set the RateManager to FixedRateCatchUpManager and it stopped a lagspike lmao
you can't disagree that the most active people in this channel are also the people who constantly use unsafe code
i'm not saying this is a bad thing but it's far from your average dots developer
unsafe is fun, duh
that's why
unsafe code and pointers can still be railed in by the safety system with correct setup. that's why i think it's a strawman
the safety system is for development only
if you got memory leaks, that's on you for being stupid/careless/forgetful
that's why it exists in the first place. It's not called the "UnsafeSystem" that yells at you when you dont use unsafe code
interesting, what does catch up manager do
oh so thats why my powersupply keeps bursting into flames..
public bool ShouldGroupUpdate (ComponentSystemGroup group) {
float num = math.max(group.World.MaximumDeltaTime, m_FixedTimestep);
if (m_DidPushTime) {
group.World.PopTime();
} else {
m_MaxFinalElapsedTime = m_LastFixedUpdateTime + (double)num;
}
double num2 = math.min(m_MaxFinalElapsedTime, group.World.Time.ElapsedTime);
if (m_FixedUpdateCount != 0L) {
if (!(num2 - m_LastFixedUpdateTime >= (double)m_FixedTimestep)) {
m_DidPushTime = false;
return false;
}
m_LastFixedUpdateTime += m_FixedTimestep;
}
m_FixedUpdateCount++;
group.World.PushTime(new TimeData(m_LastFixedUpdateTime, m_FixedTimestep));
m_DidPushTime = true;
return true;
}
uhh so.. it's..
is it skipping world time when it falls behind?
oh it's changed
nah I think that's from all the memory leaks 😛
this is about dependency chaining read/write safety and it makes a lot of sense to use the safety system in the context what was talked about. the ICD thing solves annoying UpdateAfter/Before attributes. where I'm not sure is how it can deal with ordering.
yeah i'll leave it to someone else to figure out what that code is doing
I dont know what PopTIme or PushTime do and I dont really care right now because it's not a priority of mine. I believe the docs have info on it anyhow
You shouldn't rely on the before/after attribute for thread safety since some job operations are going to be multi-frame
Personally I dont believe the safety system is apart of atomic read/write
since that is something that deliberately controls what can read/write what
job operations from systems can't be multi frame (by default)
they are auto completed next time the system that starts them runs
to avoid infinite dependency chains
yeah that's why I sad some systems are going to be multi-frame
plus, under your own RateManager you can define how often a system is ran (I think. I haven't looked into it much)
that's totally fine, but you have to buffer your data - you can't use entity data directly in multi frame jobs
but yeah you can implement custom rate managers however you want
It's hard to say what we can or cannot do definitively until 1.0 releases. Some things won't change, but I bet they will add things to make multi-frame jobs easier and safer
i wouldn't hold your breath unfortunately
that said multi frame jobs work fine as is
yeah, im not, but I'm still hopeful 😛
i use plenty of them for terrain gen / navmeshes etc
yeah! those are exactly a use case I had in mind
I've also done multi-frame jobs in the past for proc gen stuff, but they were nested inside coroutines that were dreadful to work with. Being completely linear in ECS makes everything so much easier
how would i set the write dependency of a class ICD when i don't actually use it in a job? just setting up a query?
oh right, like the physics is doing it in their RegisterPhysicsRuntimeSystemRead(Write)
it's an odd way of setting up dependencies. wonder why there's no non-internal method to do just that with a query. am i missing it?
I just encountered this warning Object Cube is not a Prefab after putting a Unity default cube in a subscene. Not sure what Unity is trying to tell me here. It is correct that cube is not a prefab. But why is this a warning?
I don't think Unity wanted devs to even think about setting dependencies themselves
huh, but we do that all the time. some RegisterEntityQueryAsDependency would be nice
so the real downside of the class ICD approach I see is that it's not compatible with ISystem. but as I'm using just containers I can use a struct instead
also the order still has to be set. otherwise, how would the system know when to schedule the writes. afaik write has no priority over reads
what is ICD?
IComponentData
ah
Hey all. Ok, I've encountered a problem with combining some packages from asset store with dots. As I understand I can't use monobehaviours from the scenes that I've converted to dots, right? So, if I use SceneSystem.LoadSceneAsync, all the things that doesn't convert to entities wouldn't be available?
No, subscrne contains only entities
man, enums in authoring comps are a pain. especially when they are changing. gonna rewrite it to strings
just gonna need to serialize the actual string because an index would have the same problems
for the stats, when new stats are added, removed, etc...
i always explicitly define enum values
but yeah i don't use them if it's user generated data
only when they tie directly to code
it's really a cascading problem. i can create 2 stat sets, or more. all are accumulated in a StatType enum that is used in runtime. it's not a problem for the runtime that indices are changing but for authoring it is. and a stat set can contain a bunch of enabled PreDefinedStats and CustomStats. so when you add 1 stat in the first stat set every index is incremented by 1 in the 2nd stat set
i don't have a good solution for it. first i wanted to have 2 different enums for each stat set but that didn't work out in the code that was using the stats.
the comps save the StatType byte. Then i could have 2 different stats that have index 0. so i'd need another byte that defines the stat set. noped out 😄
i use my K system
string keys mapped to integers defined in a config file
directly readable in burst
that's what i'm writing now. not that involved or generic but at the end this is what i need.
this.gravityIndex = K<EffectStats>.NameToKey("gravity");
a non made up example
defined here
maps to
(technically maps to gravityX but gravity is index 0,1,2 but order in this list does not matter)
pretty nice 🙂
yeah my K system was kind of designed to be editable enums without code changes
but the original primary purpose was to allow LayerMask.NameToLayer
inside burst jobs
stupid question are you basically creating generic types?
(is this directed at me?)
yeah
oh right, I was just trying to understand what you were doing and how you were doing it
public struct EffectStat_Authoring
{
public double value;
public StatChangeType changeType;
public StatType statType; // obsolete
public AuthoringStatType statTypeAuthoring;
}``` ```public class AuthoringStatsInspector : Inspector<AuthoringStatType>
{
public override VisualElement Build()
{
var root = new VisualElement();
var ddl = new DropdownField(AuthoringStatTypes.AvailableStats, "None");
ddl.RegisterValueChangedCallback((e) =>
{
Target.serializedStatType = e.newValue;
});
root.Add(ddl);
return root;
}
}``` shouldn't this work?
basically does nothing 😄
cant even see the dropdown
what is AuthoringStatType
authoringstattype is just a wrapper around a string
you have a string on your component?
yes, in the authoring comp. string array that has all the stats and the selection gets serialized to the string
what the ahhhhh it's so nice
ok thanks
this /might/ change in 1.0
when in 2022 ui toolkit is used to draw the default inspector
but for now, default inspector is still drawn with imgui
unless you override it
that would be cool. hate the other way
it's really not that different?
public class HalfDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var field = new FloatField(property.displayName);
field.BindProperty(property);
return field;
}
}```
hmm there's a bit of a gotcha here from memory
i forgot i have an override to draw the inspector with UI elements
{
protected VisualElement Parent { get; private set; }
public override VisualElement CreateInspectorGUI()
{
this.Parent = new VisualElement();
foreach (var property in SerializedHelper.IterateAllChildren(this.serializedObject))
{
var element = this.CreateElement(property) ?? CreatePropertyField(property, this.serializedObject);
this.Parent.Add(element);
}
this.PostElementCreation(this.Parent);
return this.Parent;
}
protected virtual VisualElement CreateElement(SerializedProperty property)
{
return null;
}
protected virtual void PostElementCreation(VisualElement parent)
{
}
protected static PropertyField CreatePropertyField(SerializedProperty property, SerializedObject serializedObject)
{
var field = new PropertyField(property);
field.Bind(serializedObject);
return field;
}
}```
(technically you can apply that above script to Object as a fallback and i think it'd work on everything but might break some custom tooling. i just apply it to my base custom setting script)
with stuff like this, i get the image of someone dropping just before the finish line. like why is this not working already.
i'll just write an OnGUI property handler and hate myself for that
huh, there are similar examples for CreatePropertyGUI which should work(?) - why do you need the UIElementsEditor?
ah that forum post clears it up There is a bit of a catch here, indeed. You need to make sure the Inspector (Editor) for your object is also using UIElements for any UIElements-based custom PropertyDrawers to show up.
and he wrote that early 2019. unity taking their time
i'd go the UIElements route but the property is deeply nested so setting this up could be a pain
how to pass transform reference inside GameObjectConversionSystem ?
i need something that will update game object transform from inside the entities for each method
ok i figured it out :
using System.Collections.Generic;
using Unity.Entities;
using Unity.Transforms;
using UnityEngine;
public class TransformHook : MonoBehaviour {
public Transform target;
public static Dictionary<Entity, Transform> dict = new Dictionary<Entity, Transform>();
public struct TransformHookData : IComponentData { /* NO DATA */ }
public class ToECS : GameObjectConversionSystem {
protected override void OnUpdate() {
Entities.ForEach((TransformHook mono) => {
var entity = GetPrimaryEntity(mono); dict.Add( entity, mono.target );
DstEntityManager.AddComponentData(entity, new TransformHookData { /* NO DATA */ });
});
}
}
public class Controller : SystemBase
{
protected override void OnUpdate() {
Entities.WithAll<TransformHookData>().ForEach(( ref Entity self, ref LocalToWorld localToWorld ) =>
{
var target = dict[ self ];
target.rotation = localToWorld.Rotation;
target.position = localToWorld.Position;
}).WithoutBurst().Run();
}
}
}
hopefully the Dictionary approach won't be too heavy
seems to work , but the behaviour is a bit strange ...
nope did not know , hence why i asked lol
thanks tho
already solved it
script was attached to collider which is nested inside body , move it up to the body instead and it did the trick - i suspect under the hood the rotation value is converted from quaternions to euler angles and back into quaternions hence the 180 degree snap on the Y or ... X axis ?
how do i convert ecs quaternion to Unity quaternion ?
i see there is a cast
but it looks like it doesn't follow the axis order
looks like its something other then XYZ
they are interchangeable and both float4. quaternion and Quaternion can be implicitly cast
there is no axis difference. that would be quite weird
there seems to be some sort of offset
those are the attached components to the shape
tried a few combinations
with locaToWorld , with localToWorld times rot , with initial rot value , etc...
there's built in system for that
which the most perfomant you can get
TransformSystem ?
no
IJobParallelForTransform ?
GameObjectUpdateTransformSystem
it's literally built in system
into entities package
which updates companion link transforms
trying to avoid using Hybrid
_<
if you have game object - it's hybrid
well trying to do hybrid without the actual package
hybrid is part of entities
besides
hybrid is just the way you do things, not some package or API
any ideas how to use it ?
var ltw = localToWorld[entities[index]];
var mat = *(UnityEngine.Matrix4x4*) <w;
transform.localPosition = ltw.Position;
transform.localRotation = mat.rotation;
transform.localScale = mat.lossyScale;
odd method " *(UnityEngine.Matrix4x4*) <w " ... gon try that
seems like the rotation has the wrong pivot or smth
the pivot is actually correct
its in the middle of the yellow boxes
or maybe physics collider bakes the mesh* and changes the pivot?
what i'm seeing is that all 3 rotate in the middle of the collider
hm, don't know about that. don't think so
ye
ok wow
this : *(UnityEngine.Matrix4x4*) <w solved it
y do i need to use unsafe code ...
no idea why, the reason for unsafe code here is just to avoid struct copies
and they cast to a matrix which is really just needed for the lossyScale it seems
notice :
transform.localPosition = ltw.Position;
transform.localRotation = mat.rotation;
@rustic rain what's the current way to setup companion link? docs have removed all mention
when using localToWorld.Rotation im getting different results
hm, i can copy the ltw rotation to the transform rotation just fine
i have my own IJobParallelForTransform written a long time ago. didn't bother with the companion thingy
i got to investigate though why one works for you and the other doesn't
i got the occasional rotation glitch. maybe that actually stems from it. sadly the Matrix4x4 call is internal :/
one works because its attached to the Physics Body
other doesn't becasue its attached to the Collider
did also see the rotational glitch ( angle flip ? ) when not attached to body
var mat = ConvertUnsafe( localToWorld );
var r = mat.rotation;
if( data.rotStartApply ) r *= data.rotStart;
target.rotation = r;
that's what i got rn , seem to fit all cases
No idea tbh. I think KornFlaks did it
He somehow registered monob as hybrid
And game created companion link
I kind of want to figure it too
companion links are setup by default
have supported component on gameobject
companion link setup
Yeah but I am certain someone did it on unsupported component
It was saved on entity as clone
No sir
It was actual hybrid component
Which by itself created companion
Not simple managed component
i dont really get what you mean
if you want MyMonoBehaviour : MonoBehaviour to be converted and work, try add it to the companion object list
otherwise i'm not sure what you mean
(again this is not supported and likely to break)
CompanionComponentSupportedTypes.Types
or call
GameObjectConversionMappingSystem.AddTypeToCompanionWhiteList
Yes
That las thing
Is what I meant
This makes system create companion link
Whenever object is converted with chosen monob
Otherwise it works the way, so you add monob
And it becomes null as soon as you relaunch game
is the companionlink only triggered at authoring or runtime too?
it's conversion only basically
the only bottleneck in runtime - allocation of objects, but I'm not even sure how that works
i still have no idea how this works lol
wouldn't GO authoring need the ConvertToEntity comp?
for runtime conversion, yes
but I meant runtime as in
Instantiate
while prefab is preconverted in subscene
(I simply don't see it any other way at this point 😅 )
what are the steps then to get a companionLink in the simplest form?
none, companion link will only exist with hybrid component
as soon as you remove that component from entity
link is destroyed and removed
wdym? there is no hybrid component or AddHybridComponent anymore
you register it yourself
and then not sure...
found it
thanks. you add more comps here, that aside, all the CompanionLink really does then is updating the transform, right?
not mine
from here
kek
does the math library have a method for projecting vectors onto planes? I could only find a function for projecting vectors onto other vectors.
I think you simply want to project vector on 2 axises of your plane
I can make my own function if needed, I just wanted to know if it's already implemented
I tried to find something similar a while ago
dots physics has a plane but it has no raycast so you have to create your own
Any ideas why is there a jitter ?
All 3 systems show this artifact : PhysicsDebugDisplayAuthoring ( green lines ) , my system that updates the mesh position and the default GameObjectUpdateTransformSystem
tried with burst compilation off and on
also tried with job debugger on/off and safety checks on/off
btw about the rotation problem from yesterday. do you use a scale?
are the physics entities interpolated?
look like interpolation and then it's snapping back
magic, not sure why but its gone
no - the physics shape component will bake* scale in
looks like physics bug, kek
literally same issue for me
dang
tried all 3 , interpolation , extrapolation and none
take a look at the profiler timeline - maybe there are 2 physics steps occuring. no idea why this "bug" is not happening in builds. and make sure safety is turned off and physics integrity checks also
what are physics integrity checks ?
can be found in the tab DOTS -> Physics
i don't know exactly what it does. it tanks performance though, some kind of safety/debug thingy
bad performance in editor means multiple physics steps in 1 frame which could be the cause of it
so i noticed there's another sale on assets store happening - oh yay there was that $80 ECS character controller I wanted to get, lemme check it out... HOLY MOLY Unity Technologies bought it out and offering it free 😱 https://assetstore.unity.com/packages/tools/physics/rival-dots-character-controller-for-unity-225129
christmas came early 🤣
<unity oprah> you get a character controller! and you get a character controller!
I already own it!! QQ
@whole gyro totally missed that, thanks!!
how do i pass data from GameObjectConversionSystem to SystemBase ?
( not the add component data method )
been using a static variable so far , but on scene reloads seems like im getting index out of bounds
what are you trying to do because that just sounds wrong in practise 🙂
i have a static list of data
and each component data has an index to access it
the conversion system will create this static list and populate it
and will assign an index to each of the entity component data
then inside the system base i access it
its works great , but this seems to break when i load another scene
Tried to populate the static list OnCreate and logging out the data that has been written and it all looks just fine
can you not use a singleton entity and set a component with the static data and have those entities refer to that singleton? i think the problem is just having static data here
how do i access this data inside the SystemBase then ?
when creating an IJob i can pass this data , but looks like SystemBase is some sort of an abstraction
access singleton entity data?
just inside OnUpdate: var myData = GetSingleton<MySingletonComponentData>();
Singletons are just unique entities
If you create only 1 entity with MyComponent it's a singleton
Under the hood all its doing is a normal query and returning element 0
hmmm
looks like i don't need it
my problem is that the entities are not getting destroyed
from the previous scene
even tho i called SceneManager Unload Scene
so it seems like the entities from the previous scene are getting queried and their index is larger then the data amount in the next scene , hence why im getting index out of bounds error
any ideas why the entities are not getting destroyed ?
or rather how can i force clean the scene ?
static data in a GOCS? sounds like a recipe for disaster
its ok
all im worried about is why the entites are not getting destroyed
static data is mono data , nothing relevant to the ECS world
afaik the system isn't even in a build. is it runtime conversion?
SystemBase still queries my entities
after i populate the IComponent data inside GameObjectConversionSystem
well how are you destroying them? are you using SystemStateComponents? have you checked the DOTS hierarchy?
not sure
Physics ECS sort of does it
looks like it won't destroy prev scene data
found a way to manually stop all systems :
Unity.Entities.World.DisposeAllWorlds();
is there a way to start them over again after scene reload ?
ok nvm this did the trick instead :
var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
foreach (var e in entityManager.GetAllEntities())
entityManager.DestroyEntity(e);
just a heads up this breaks physics
and any other system that sets up entities in OnCreate
(also you can just do something like EntityManager.DestroyEntity(EntityManager.UniversalQuery)
(but again, this breaks physics)
what are you trying to achieve? you surely don't want to just destroy every single entity and just specific ones.
simply trying to load a scene lol
it will update
but your systems won't work
you will have deleted
PhysicsSystemRuntimeData
which is what
RegisterPhysicsRuntimeSystemReadOnly
RegisterPhysicsRuntimeSystemReadWrite
requires
basically you break dependency management between your systems and physics
hmmm
so looks like i need to manually clear all the physics entities that have been created inside the scene
i avoid changing scenes in entities because it's weird
i just open/close subscenes instead
slowly realizing dots should have been separate products , don't like how they mix the two
are they mixing it or are you?!
If you do have a game where each scene is completely unique and you want to wipe previous world, then imo it's probably easiest to just destroy world and start fresh
Then keep any persistent state in a seperate world
take a look at subscenes and how they work. it's essential to understand them when working with dots
.
that's what i was asking for lol
how can i create a world on scene load ?
look into DefaultWorldInitialization
damn my statsystem got out of hand. i hope that was the last big thing. now it support generic datatypes, can add an arbitrary amount of stats and now it even support different stat sets. lots of code generation to make that happen. best thing, no performance degradation
don't think so, should be all good. bunch of structs, enums, helper methods. not really related to entities. but the rewrite for the rest of it will be quite huge :/
it's not that bad. important part is to write the code at least once. then code gen the rest. just a bunch of StringBuilder.AppendLine. the more time consuming part is setting up analyzers but as i'm getting the data from scriptableObjects i don't need them
Well done!
thanks 😄
Interesting, thanks for the feedback 👍
is there a rigidbody sleep threshold for Unity Physics?
Also, does anyone know if double-precision will be added to Unity Physics?
i believe havok supports sleep
as for double precision, probably unlikely anytime soon but who knows
i remember seeing someone doing this a while ago but i don't think it's been updated to latest
0.51 was released less-than 17 months ago so you're right it is outdated
It would be nice to have since working with some touchy physics-related elements can be noisy with just floats
what is sleep in physics?
If havok has it, I imagine UP will have it as well in the future. Unless stateless doesn't allow for such a constraint.
if there's no state, there's no sleep state ^_^'
If a rigidbody is below a certain velocity magnitude threshold, it will not be updated
no that's not the same thing
putting a rb to sleep effectively frees up resources until an external force acts on it
ah, you mean entity specific
well the way I see it
you can quite literally create component
tag
or nah
component with velocity threshold
which will set velocity to 0
every step if it's below
you can, yes but I was hoping an internal feature existed already
problem is, setting the velocity to zero doesn't actually work
Unity Physics philosophy is simplicity over complexity
depends on what time of a step
you do it
it's a bit more complicated than that
this causes things to get stuck annoyingly
I get it, but you can do job that works exactly during physics step
natural forces like gravity need to be accounted for because velocity (unfortunately) does not reflect gravity being applied
quite literally on rigid bodies
it really requires a minimum time of velocity < threshold
then you have this whole issue of waking them up again
ah
saved state
welp xD
anyways, if that's for perfomance
then you might want to consider other optimisations
I mean, a state doesn't need to be saved to know when to apply force. For example if you had a box resting on a kinematic surface, velocity is effectively zero, so it can be ignored.
For me sleeping a RB is not for performance, but to remove noisy force values (micro sliding, specifically)
from my experience in unity physics
it takes a long time for things to actually hit 0 velocity
another reason for sleeping/ignoring I guess
I remember there's built in thingy for that
and I think it's inside step component
you mean contact solver?
if you find a good solution to detect bodies that should sleep
i could use it
currently i'm just manually sleeping when the velocity get close to 0 after 1 second or something
it's not a problem i really wanted to tackle so basic solution
but it's something i need to look at in the future at some point
Is that done in havok?
Always wanted to make an integrity system, just never had a reason to yet haha
no
that's unity physics
networked
i am considering looking at using havok at some point
because i don't think i need rollback from what i'm doing
(i'm considering completely ditching prediction)
you could do manual prediction. had issues with PhysX being unpredictable when working with only forces, so it might have the same effect in Havok
i mean netcode prediction
and prediction is something that should be apart of any networked game that is fast-paced or requires precision
but yeah i'm looking at using click to move
not wasd
and some of my requirements aren't possible atm with netcode if using owner predicted (e.g. changing ghost owners)
Unity Netcode handles it already? I thought that was 1.0
yes
netcode has great ghost prediction
it even supports ghosts in physics prediction now with 0.50
I haven't done anything with unity netcode yet
idk how hard it is to even work with compared to something like mirror haha
i really like netcode
it has a lot of potential
i'm hoping 1.0 brings a lot of polish
we all are, and Im sure it will happen
especially since ECS will unlock tons of potential for another market that unity struggles with
(RTS, large worlds, PVE/P MMOs etc)
Hello, it is possible to pass NativeMultiHashMap to IJobParallelFor and in Execute use function GetValuesForKey(TKey)(Returns an enumerator over the values of an individual key.)?
I have this testing code:
void Start()
{
NativeMultiHashMap<int, int> data = new NativeMultiHashMap<int, int>(5, Allocator.TempJob);
// adding data to hash map (only for testing)
for(int id = 0; id < 5; id++){
data.Add(id, 0);
data.Add(id, 1);
data.Add(id, 2);
}
// Initialize the job data
var job = new TestJob()
{
map = data
};
JobHandle jobHandle = job.Schedule(5, 64);
jobHandle.Complete();
data.Dispose();
}
[BurstCompile]
struct TestJob : IJobParallelFor
{
[ReadOnly] public NativeMultiHashMap<int, int> map;
// The code actually running on the job
public void Execute(int i)
{
}
}
But even with [ReadOnly] attribute I am getting this error:
InvalidOperationException: TestJob.test is not declared [ReadOnly] in a IJobParallelFor job. The container does not support parallel writing. Please use a more suitable container type. Unity.Jobs.LowLevel.Unsafe.JobsUtility.ScheduleParallelFor (Unity.Jobs.LowLevel.Unsafe.JobsUtility+JobScheduleParameters& parameters, System.Int32 arrayLength, System.Int32 innerloopBatchCount) (at <d8d38b92d94a4ff8a91e61d39c6d19cd>:0)
Unity.Jobs.IJobParallelForExtensions.Schedule[T] (T jobData, System.Int32 arrayLength, System.Int32 innerloopBatchCount, Unity.Jobs.JobHandle dependsOn) (at <d8d38b92d94a4ff8a91e61d39c6d19cd>:0)
Thank you 🙂
wtf?
test = test
wouldn't it be better to get key/value arrays instead?
I don't think enumerators are thread safe
anyone using Rival DOTS character controller? I'm getting compiler errors
The type or namespace name 'CharacterInterpolation' could not be found```
Unity version 2021.3.9f1.git.11352176
Entities / Hybrid / Physics Version 0.51.0-preview.32 - June 15, 2022
Or - any idea when @light badger might be around?
Unity should be at least 2021.3.30
Nope
I'm completely drunk xD Ignore my message
Did you check Rival package version compatibility ?
you folks know of a free bursted poly simplification repo somewhere? (I know it's much to ask of a freebie)
finally found the right instructions to follow https://philsa.github.io/rival-doc/Samples/samples-installation.html
bit of a documentation issue with this package... there are PDFs scattered all about the assets folder, there's the website https://philsa.github.io/rival-doc/, topics repeated in multiple sections therein, needs a bit of unifying / clarifying / normalizing into concise docs
so it was missing a package import ?
i guess so, it needs the whole Rival project not just the samples packages
now i think the FPS controller is starting to work, however my scene environment is not fully there yet. My trees/foliage are showing, but my terrain which are a bunch of objects with render meshes with Splatmap+shader from https://assetstore.unity.com/packages/tools/terrain/terrain-to-mesh-2021-195349 are not showing, although their physics are working and seem to have the correct mesh shape & physics
maybe some shaders or splatmap is not compatible with DOTS hybrid rendering or something?..
aha the console has something to say: "A Hybrid Renderer V2 batch is using a pass from the shader "Amazing Assets/Terrain To Mesh/Splatmap", which is not SRP batcher compatible. Only SRP batcher compatible passes are supported with the Hybrid Renderer."
and yet it somehow works?
was a case for me. No idea what's that, but... it's just works
the rest of the scene works, but my terrain meshes using that asset's Splatmap shader which seems incompatible with SRP batcher is not rendering/showing/visible
hmm
one way you can get around this - make hybrid renderer
I mean
use companion link with Mesh Renderer
attached
If this is the asset that I think it is
It only took me 15min up throw together a Shader graph to replace that Shader
I think it was quite a basic Shader
@rotund token can haz... copy? 🙏
I'll have a look when I get out of bed
k thx 🙌
I have a random basic question how would you guys define this structure in dots components
protected class KdNode
{
internal T component;
internal int level;
internal KdNode left;
internal KdNode right;
internal KdNode next;
internal KdNode _oldRef;
}```
Array of KdNodes and each 'ref' is just an indexer into it
struct Node{ Entity left; Entity right; ... }
interesting I was curious if it would be faster or not
{
internal Entity component;
internal int level;
internal int left;
internal int right;
internal int next;
internal int _oldRef;
}
public NativeArray<KdNode> nodes;```
I was going to test it straight against a brute force approach
oh so I just use the index of the entity's and that should work
the index is just the element i the array of all nodes
you could use a pointer
i don't know how it'd compare - probably faster
but could be a bit of a pain for memory (but probably not)
yeah it only needs to last for one frame really so yeah that should be fine
but really
just find a fast implementation in C on github
and copy that
https://github.com/begeekmyfriend/kdtree
something random like this (I have not looked at it, just first thing that popped up)
that's great, thanks
I haven't really used pointers with dots how would I go about doing that
well you malloc each KdNode
{
internal T component;
internal int level;
internal KdNode* left;
internal KdNode* right;
internal KdNode* next;
internal KdNode* _oldRef;
}```
and just point to the next
for the sake of performance if this is large, you should use something like a slab allocator so you aren't allocating each node individually
this is my graph but i was wrong, this matches mighty terrain
so 99% won't work for you (also before anyone uses it, it's probably wrong. i only threw it together friday just to have a quick test scene for something)
it will definitely be large so, yeah that's something to learn thanks tertle
this is my slab allocator if you needed
i have like pool allocators, parallel allocators, etc built on top of this
but the point of this is to reduce your allocation calls but also allow you to not worry about tracking individual allocations and just dispose them all at once
that's awesome, thanks a lot
ah shit this uses my UnsafeListPtr
this is basically just NativeList without safety
so unlike unsafelist it doesn't need to write back when you make changes
Do you hardcode the ID's or do you have a system that automatically assigns them? Would an enum be a horrible choice here?
if your designers need to edit code to add content then it's a bad idea
I can use unsafe mostly fine, that should not be to much of a problem, thanks
I like the readability it brings to the code side
It can be readable without being an enum
What would be a better choice?
think of Unity Physics Layers
these aren't enums
you can rename them in editor
but they're quite a readable list
i have a general purpose system for this called K
probably more advanced than you need
but really all you need is a list of
int, string
and then a property drawer for an attribute
[SerializeField]
[ActorID]
private int actor;
then a simple drawer that draws a drop down for ActorID mapping names to ints
from the list
do you only store the int in dots
my implementation?
yeah I figure the string would be on a scriptable object or something?
i can actually call this
K<UIStates>.NameToKey("build")
from a burst job
only the key is ever used but i can look it up via string from anywhere
oh 
that's cool
I just figured strings were bad in dots to be honest
but maybe that's from a while ago
you should avoid hard coding these because if someone renames it bad things happen
but its useful forthings like
gravity
or layer masks
What does NameToKey look like? Or is this some built in functionality?
/// K is an Enum or LayerMask alternative that allows your key value pairs to be defined in setting files.
/// It provides a way to convert human readable strings into values, even within burst jobs.
/// </summary>
/// <typeparam name="T"> The type of config. </typeparam>
public static class K<T>
{
private static readonly SharedStatic<KMap> Map = SharedStatic<KMap>.GetOrCreate<KMap, T>();
/// <summary> Given a name, returns the user defined value. </summary>
/// <param name="name"> The name. </param>
/// <returns> The value. </returns>
[BurstCompatible]
public static byte NameToKey(FixedString32Bytes name)
{
if (!Map.Data.TryGetValue(name, out var key))
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
Debug.LogError($"{name} does not exist");
#endif
}
return key;
}```
and KMap is just a hashmap pretty much
Ohh interesting, looks promising
so really all i'm doing is storing a hashmap tied to each generic using SharedStatic
I'll try to implement something like this, thank you!
would anyone know how to instantiate abunch of gameobjects with a for loop using IJobParrellfor?
what about entities?
totally
but even entities need to be instantiated on main thread however you can run your instantiation code in parallel
and use a buffer to do the actual instantiation on main thread later
(also don't use IJobParrellfor it's deprecated, use IJobFor)
i'm honestly amazed that i don't know any better way 😄
i should invest into some templating or smth. this is such a mess 😄
but no matter which code generation i've read, it was pretty much like this.
why does my game connect to steam inside of the editor but when I export the build it doesn't (im using fizzy steamworks and mirror)
probably should ask fizzy steamworks and mirror dev ^_^'
don't you just hate yourself though for having to write this?
somehow it feels even more dirty than the boilerplate it's removing
lol, no. i love automation even more than performance 😄
and my game has at least 3 stat sets, maybe even more in the future with new features. i'd hate myself for writing stupid boilerplate that's very easy to mess up
missing steaminfo.txt or what its called. id?
if job1 and job2 are both IForParallelFor, job1 merges a bunch of mesh chunks and job2 merges the vertices from job1 that have the same coordinates, since i don't know the total number of vertices until job1 is finished, is there a way to do handle dependencies in this situation?
Originally it didn't export with the steam_appid but even after fixing it, it still doesn't work
job2 can only be scheduled with either a defer job or AsDeferredJobArray array. chain the jobhandle from job1 into job2 and you should be fine
like, using IJobParallelForDefer instead of IJobParallelFor?
yes, but i don't know your implementation. does job2 run on the array that job1 outputs?
Yes
then try IJobParallelForDefer
it's made for exactly that use case
unknown array length
Thanks, I'll try that. Is there an example of such case?
a non ECS example
sure, always check the tests:
That might be why i cannot find it, I still use 1.2.4
i'm pretty sure there's also a test in 1.2.4. IJobParallelForDefer is pretty old - didn't you find one?
yeah pretty sure it's existed since like 0.1
I found it, I thought that project search could be scoped into packages but that's not the case, I just used listary to find the file name, thanks
jeez, i don't understand half of of this syntax and my head's about to explode.. do you think that's the right way to handle mesh merging followed by mesh index merging (same coordinate = reuse index) followed by mesh decimation?
before your head explodes. just .Complete the jobHandle of job1 and then schedule job2
never seen that before, what does that mean?
setup for the test. ignore that
ah i think it's setting up various values for length, that's why it's between []
string codeGen = $@"public class SomeClass {{
public float someFloat;
public SomeClass ({someArg}) {{ }}
public void SomeMethod () {{ }}
}}";
What you're doing is beyond absurd
thanks, i should've read more than microsoft docs 😄
This is basic string stuff, nothing relating to unity or ms docs explicitly
over several stringbuilders indentation is a pain. that's the reason i've written it like this. SourceText.From seems nice
i feel like anything much larger than this would just be easier to read from a .txt/.cs file
you could probably write it nearly normally in something like vscode
wonder if anyones written a 'template' analyzer
I'm writing a object interpreter that will convert C# sourcecode into a string/txt file for easy sourcegen
that'd be useful
It wont look as pretty, but it will be slightly less error-prone than writing a string out manually
lots of attributes for shit
$ and @ don't work together for me
ah, was missing the double braces
works fine for me
so for my small code files this is pretty nice. for my big one. i took me more time now to test formatting and fixing it than writing out those lines. formatting with breaks in between the stringbuilders is quite the pain
can you provide an example why you need a break in-between stringbuilders?
some loop or a condition
public string ForLoop(int start, int length, string body) {
return $@"for (int i = {start}; i < {length}; i++) {{
{body}
}}";
}
you dont even need to do a single break at all
its all strings, and you dont even need to use a string builder
well, i gave it a try with a part of the codegened file. doesn't file like an improvement. formatting is a pain and code starts to get scattered around making it even more unreadable to what's going on. i'll give it another try though when i got the time again. never put much thought into building such large code files so i'm clearly missing the experience here. my big one codegens a 1400 lines file. that's not just easily changed.
and i think when i redo this, i'll make some template for the overall skeleton of the code file.
at least i got the formatting down now. gonna retry in a few hours. now i got some more exciting things on my plate 😃
Of course it’s not hardcoded
we have an editor tool which generates SO config file for prefab from context menu in specific folder, which holds different stuff including unique id, and then you just use simple integer field whatever you want, with attribute [UniqueIdentifierReference] on it and in inspector you’ll see button which shows you name of selected prefab and ID (if you’ve selected anything) or you click and see small window with search box where you can add prefab. And you can use it in any place - GO or SO. Why this is better for us than making mechanism like Unity one (just prefab GO fields which will be processed on conversion, which is good for engine general case) is we strict our team to use only prefabs which been properly processed and converted with intention to be used like that, and saves us from designing more complex mechanism for converting prefab references on the fly (as in our mechanism you just: Right mouse click on prefab - Create Object Base Definition)
I mean does the ID get set and "hard coded" in the SO, is it just a counter that keeps going up, or does the designer decide the id based on some convention?
it's safe counter and designer doesn't do anything just what I described above (RMB->Create) and internal mechanism do the rest and ensures that next ID is unique. Every Object ID is not just int it's another hidden SO which holds actual ID
quick question @storm ravine how do you handle merges where 2 different branches have assigned the same ID?
Expected that question 
Well nothing elegant, there is just couple of people who responsible for creating new object ID's and usually they're just warn everyone that new definition created and immediately push only object definition with empty prefab and another people pull only that and continue, we decided not overthinking that and not reinvent safety mechanism for that or any smart merge tool, and we never had the issues with that since the beginning (4 years ago) and it was one of the first thing we made for pre-DOTS entities 
I mean NEVER
Was hoping for some magic solution but that makes sense
Oh that's clever. Seems like a good system overall with nice benefits. All these nice editors and systems ppl have and my head is spinning what's the best way to go about it :D Also I've taken some shortcuts previously which in hindsight I shouldn't have taken 😅
Really for a 4 years - no aliasing at all ))))
Sticking to well thought out rules usually trump complicated implementations.
At the end of the day the project you're working on will dramatically change your implementation. If you're a solo dev the level of tooling you require is significantly less than if you're in a team. Nice tooling is really important the more your team grows though.
Well I thought about that and eventually resolving that would not justify the time effort comparing to just what we doing with that. And than furfure our game comes - less new prefabs, these days it happens less than once in a month and usually it's just bunch of new prefabs and one person whi pulls new models - just creates prefab and object definition for them (just select all of them at once and RMB->Create, it supports multi creation of course).
True, I just don't like to build on systems I know smell bad, and tooling is nice even solo, never really needed it before so I haven't dove in to it. When prototyping I just want to get something on the screen, fast, a year later you're left with this
Hmm I now have a system to load prefabs to a NativeParallelHashMap<FixedString32Bytes, Entity> which is a bit cleaner, but seems that it didn't solve the reason I'm refactoring in the first place.
So I'm making a level generator and would like to to load & instantiate entities from prefabs in the editor world, I thought the cleanest solution would be to separate the prefab loading to a separate scene I can load in both environments. But it looks like you can't do EditorSceneManager.LoadSceneAsync("PrefabMap"); in the editor? How are you supposed to convert prefabs to the editor world?
Hello, it is possible to create IjobFor/IJobParallelFor to which will be entering for every index his own NativeArray? Inside job should be function which will found from corresponding NativeArray desired record. Thank you! 🙂
Use IJobFor instead of Parallel, it's new version of it
https://docs.unity3d.com/ScriptReference/Unity.Jobs.IJobFor.html
and for this job you only get index
which you use to manually iterate array or other container
Turns out even if you get the GO's loaded, the conversion system isn't running in the editor even with live conversion enabled. Am I just looking at this wrong, or is the only solution editing the entity package? Or is there some way to get the conversion world up in the editor, the systems are defined with [WorldSystemFilter(WorldSystemFilterFlags.GameObjectConversion)]
Maybe I'm making this harder than it needs to be by running it in the editor world, a new level editor scene might do the trick just as well
conversion is only done during Runtime OR
if you close subscene
otherwise no conversion in Editor
Ok so a runtime level editor it is then ^^
Hope the scene creation works there as well, at least in the editor, doesn't have to work in build
ahem?
It's not really clear what is it you want
but it feels like you are confusing smth
or maybe I am
I want to use ECS to build my level editor, and since the levels are going to be large, it should automatically slice them in to smaller scenes
no automatically so far
but if you want to use ECS entities to build levels
you should use SubScenes
they are perfect for this
perfect for large worlds and very efficient and fast at loading/unloading at runtime
Well I should be able to make it automatic if I can just write scene files from the level editor, essentially baking the generated level to a collection of subscenes
Yeah exactly, that's why I think generating subscenes is the way
recommend to read on this
to avoid a lot of further questions and bad practices in your game
That's the article that made me think it's possible, since they talk a lot about the editor conversion, which doesn't seem to happen in the editor world :P
Anyway I'll build this and see if it works, I've got most of the parts ready, was just having trouble loading prefabs in to the world
it does happen in Editor World though
but you need to close editing mode on subscene for that
once you did it
you can open hierarchy
and see fully converted subscene and all it's entities
Well yeah technically it does happen, but not in the way I was expecting
it's not technically
it's actual conversion
this is the kind of conversion that will be used in build
so practically what you see is the same thing (excluding conditional editor code) that will be in build
Left is editor, right is runtime. The difference is the "ConvertToEntitySystem" doesn't run when you initialize the editor world, so any objects you have inheriting IConvertGameObjectToEntity with Convert() in them doesn't run
ConvertToEntitySystem will be deprecated in future
it's rudimental component that is left for legacy
you are not supposed to use it
It's what does the conversion atm, I just inherit from IConvertGameObjectToEntity
the intended way is to drop your GOs into subscene
all GOs will be converted inside of it
and it's way faster than runtime conversion through that component
because conversion is done before you even press play
Yes, that's why I was going to generate the scenes which do the final conversion, just this level editor tool (which only runs in editor, not in build) would've needed the realtime conversion
First of all, thank you very much for your help. Could you please help me how to apply this IJobFor to my problem?
I have a variable number of NativeArray<float> and my goal is to for each one find float which meets same conditions. I thought that parallel job will be best for this, because computed results will be used in same function and searchings will be performed on different workers.
But I don´t know how to do it, because I need somehow link index inside IJobFor to specific NativeArray and nested NativeArrays are not allowed.
Is that even possible? Thank you 🙂
Anyway I'll stop polluting the channel, this is going in circles :P I'll try it and see if it works
wdym neested arrays are not allowed? you can store native array in a job
oh wait
you want native array of native arrays?
yep, I want to insert into job variable number of NativeArrays and on them perform searchings
I know that is wrong and not allowed, but for describe purpose I need something like this:
struct SearchingJob : IJobFor
{
[ReadOnly]
public NativeArray<NativeArray<float>> datas;
public NativeArray<float> results;
public void Execute(int i)
{
NativeArray<float> actualData = datas[i];
results[i] = searchFunction(actualData);
}
}
well
2 ways I see it
- use array of pointers
- use unsafe lists
you can store unsafe lists inside native arrays
or other native containers
and what do you thing will be better?
Another way can be to pack your data into one contiguous array. Then store some indirection/size array.
If your data allows that
thank you both I will look into it 🙂 ❤️
And that's a no, EditorSceneManager can't be used in play mode to create new scene files
Just do it intended way and you'll notice how good it is
I'v been trying to make my own solution too for a month...
Wasted month 😅
So there's no way to "save" entities as go's in a scene?
could you elaborate?
My map generation code runs in ECS, it generates arbitary data entities I would like to use as the basis to "bake" GameObjects to a subscene, in a system
sounds like your doing this backwards
How so?
well ok hmm i guess question is
purpose of map generator?
because if your map generator needs to create gameobjects from entities
why not just have your map generator create gameobjects
yeah, you should probably just do whatever you do during conversion
instead of doing weird GO -> entity -> GO -> entity conversion
The engine doesn't like having hundreds of thousands of GO's in the editor at the same time
But to do that I need to have them somewhere first
1:1 go-entity
you can have 1000 entities from 1 go
or none
sometimes I use game objects to define hierarchy parts in conversion
so instead of attaching hundreds of components to each GO, I simply add them as children to another
and it adds all required components during conversion
So I guess the problem stems from trying to visualise and interact with the map generation at the same time as "baking" the scenes from that visualisation, since one is done at editor time and one at run time
Would've made the level tool a lot easier to implement, it seems if I want to use runtime to author, there needs to be an intermediary data file which is then used at editortime to generate the scenes. That's probably why I tried to generate them at editortime in the first place. I then wanted to visualise the generated data in the editor view, which fell flat when I couldn't load the mesh prefabs as entities in to the editor world to see what it's going to save before committing to it, I assume it's going to be a slow process
why do you want to use runtime for conversion in the first place
Idk how else to explain it different from the above :D
Just an fyi subscenes are literally identical to normal scenes, but just for entities. Its all YMAL code for both scene types, and go prefabs
do you want modding in your game?
is that it?
Nope, the level generation just has many layers to it, procedural and authored which are all non-destructive, so I can make a change at one layer and press re-generate to apply the change to the result
exactly how subscenes work
How would you make them procedural?
So you'd just generate the GO's in to the open scene and save that?
I have this concept for my own game:
- make a go that accepts SO
- based on data from this SO generate as many required entities
- give them required data
viola
How do you make the entities in to subscenes after part 2?
during conversion you can register prefabs from fields
or
create additional entities
I think I'm missing a click somewhere, maybe it'll come after banging my head at the wall enough :P
have you touched subscenes yet?
@ocean portal you're making a procedural level generator, is that it?
A little bit, dividing common stuff to them and so on, no streaming yet
have you tried making simple stuff? for example super simple scene setup without any codegen?
I meant, not codegen, but procedural generation
Kind of, the procedural parts aren't runtime, just in the editor tool
Ok one sec
Manually yes, but haven't got anything instantiated in a subscene file with code yet
so, if you want tools smth like