#I do wish there were some better hybrid

1 messages ยท Page 1 of 1 (latest)

lament copper
#

what is the actual final goal of having the attached monobehaviour

static granite
#

Honestly, the main use case for me is things like GetSingleton<Camera>(), or GetSingleton<UIReferences>()

lament copper
#

why would you do that instead of Camera.main or similar

static granite
#

where UIReferences is some mono that stores references to my ui stuff

celest solar
lament copper
#

if it's really a singleton, and it's managed, a static variable works fine?

static granite
#

And getting my Animator on my main character

lament copper
#

static variable sounds like it would work for that too?

static granite
lament copper
#

whenever you please

#

it's all a main thread managed party

mystic depot
#

yup, and the standard use is defintly awake if you want it the earliest :3

wheat ruin
#

I just want my physics2d to work...

lament copper
#

that is entirely separate

static granite
#

Feels weird to use static variables here. Like right now my game is singleplayer. But what if I later decide to make it multiplayer? Ideally I would iterate each Animator in a system and set the animation variables based on some ECS components.

lament copper
#

how about a List<Animator>

#

or a dictionary, where the key is an entity or something

#

(or a networkid, whatever)

celest solar
#

sounds dirty

#

It felt better when it was done by Unity under the hood ๐Ÿ˜…

mystic depot
#

Suggestions aside, already merged into master I added SystemAPI.ManagedAPI, which will indeed help with accessing the ComponentObjects :3

lament copper
#

yeah and i'm trying to dispel the idea that using normal c# and normal monobehaviour stuff is dirty in some way when you actually are sure you will never have more than a handful of these things, and it's managed and single-threaded anyway so you can't burst or jobify it

wheat ruin
#

With the assembly ref hack allowing for expanded companion GOs, hybrid kinda feels okay. The transform sync systems keep throwing errors but ignoring them works fine.

mystic depot
#

Also SystemAPI.Query support for MonoBehavoiur and ScriptableObjects (which btw already works today in IJobEntity)

static granite
wheat ruin
lament copper
#

...if you know it's a singleton you could just set it on a static variable...

#

that would literally be faster

#

both to code and to run

wheat ruin
#

I've disabled domain reload. I don't want to deal with cleanup of static fields

lament copper
#

errr... what's your idea about how a static field would be stale when the singleton entity wasn't

wheat ruin
#

Yea, probably, but I use that for onstartrunning and store a local reference inside the systembase

#

I also use those queries in require system to run.

lament copper
#

you could just check the static variable at the top of onupdate...

#

(that's literally what the require does, except it's slower)

wheat ruin
#

Yea, a static class with the GO as a property is the C# way, and I have done that in my lighting system for the singleton compute buffers and material properties, but dots...

lament copper
#

but NOT "but dots"! that's the disease i want to cure here. things do not get magically faster because they're part of the entities api!

wheat ruin
#

Haha, true. But good luck.

static granite
#

Its not about the speed, its about the consistency

lament copper
#

consistency is wildly overrated.

static granite
#

Yeah perhaps. But I did like how it felt when everything was done in systems and all data was on entities.

#

I'm not opposed to the static idea, btw. I'll give it a try and see how it feels. Thanks for the suggestion

lament copper
#

๐Ÿ‘ spread the word ๐Ÿ™‚

static granite
#

I believe you already suggested solving this with a static dictionary, but it does start to feel weird when you want to combine ECS components with mono behaviours on corresponding game objects. I want to write code like this:

foreach (Animator animator, Speed speed) {
   // Set animation var based on speed, where speed is an ICD
}

This is doable if you can add the reference to the monos as mananged components to the entities. But setting this up in baking is difficult (basically recreating the companion link stuff). And it sounds like you are suggesting that we instead write code like this:

foreach (Entity entity, Speed speed) {
   Animator animator = AnimatorStaticDictionary[entity];
   // Set animation var based on speed, where speed is an ICD
}
#

I guess this isn't all that different than something like a ComponentLookup on another entity. And since the mono lives on a game object and not the entity, it is doing a similar thing.

#

Alright, I think I'm coming around to this

lament copper
#

it also makes it make more sense because baking has to exist in order to get the entity data in order for runtime. but the managed monobehaviour stuff is already in order, and doesn't need any baking; so shoehorning it into baking is quite unnatural

celest solar
#

I have another solution rather than storing on static field:
Create an object field in World using asm ref and then use it through casts

#

this way it'll be World singleton and not static

#

yet fast access

blissful cedar
#

Personally I disagree with statics because it limits ability of running multiple clients in isolation

#

I don't have 1 camera, I have 1 camera per world

static granite
lament copper
#

errr, you do? isn't only one of them rendering to the screen?

blissful cedar
#

No I have split screen

#

This is even auto managed

#

For testing multiplayer

lament copper
#

aha, that's interesting. however, should also be covered by a 2 element dictionary where the key is the world

#

it's true, the mapping thing is a bit interesting and i can see how you could argue baking or some step in that area should be related somehow.

blissful cedar
#

my game doesn't actually do splits creen, this is just for testing but it even auto splits each client world into mini windows

#

and i can focus each client separately to test multiplayer interactions

#

one of my biggest gripes at work has been how annoying testing multiplayer features are

lament copper
#

my trick is to have 2 copies of the project open in 2 editors

#

then you never have to make a build ๐Ÿ™‚

blissful cedar
#

thats great until your project reaches 200gb+ ๐Ÿ˜ข

lament copper
#

indeed sir

#

the iteration benefits are so huge that i might consider another ssd for it though...

blissful cedar
#

my recent issue has been more on the memory side of things

lament copper
#

(i'm not saying it's great, of course. just my personal hack)

blissful cedar
#

32gb just isn't cutting it anymore...

lament copper
#

yeah that's low for a big project like that with 2 editors

static granite
blissful cedar
#

anyway i actually have minimal complaints about hybrid, i just dislike the use of statics in general but if it works for people then good enough

#

however i don't really understand benefit of a static mapping for say animators when you could just bind the animator directly to the entity

lament copper
#

there's also the point that this specific thing will be solved one day by dots animation, but that won't be the end of needing to interop with monobehaviours

static granite
lament copper
#

so the instantiating at runtime thing i agree is not super amazing, but also we know for sure that whatever solution we come up with here won't scale anyway

blissful cedar
#

๐Ÿคทโ€โ™‚๏ธ that's what i do (prefab referenced stored i baking and initialized at runtime) but no one really seems to onboard with it, but it's been working amazing for me

#

in 0.51 i had my own entity picking scripts that would actually pick skinned mesh renders attached to entities but select the entity instead

celest solar
blissful cedar
#

i posted my full source here, to answer the question though yes just a managed comp

static granite
#

Sure, instantiating at runtime works fine, so long as you don't need that prefab to be referencing anything else in the scene.

blissful cedar
#

funny enough that isn't even that hard to solve

#

i have a full cinemachine wrapper that allows targets/follow to be setup

#

which are referencing other game objects

static granite
#

What you're describing sounds like a custom solution to hybrid

blissful cedar
#

(i did notice a sneaky cinemachine.dots package which i am looking forward to)

lament copper
#

what's the case where you need it to be referencing stuff? i followed the animator example, but i didn't see where that required scene references

blissful cedar
#

my only use case was cinemachine targets/follow. none of my regular hybrid stuff i have bound ever needed to reference other things

lament copper
#

i guess targets/follow for cinemachine makes sense

static granite
#

I don't have a great example for that. Maybe UI references, but static would work find there.

blissful cedar
#

all cinemachine, 4 different virtual cameras from memory, follow entities
it converts (this was 0.51) off the existing components

#

you can't even tell it's hybrid, nothing in hierarchy etc

#

you just write to unmanaged components and it's handled for you

#

i'm hoping if/when an actual native cinemachine support comes i can just swap my own components for that implementation (might be wishful thinking =D)

lament copper
#

continuing to ponder, some of this is an artifact of the fact that entities fundamentally is a complete hack, a hopefully reasonably successful attempt to staple an entirely unrelated engine model to the inside of an existing engine

blissful cedar
#

some people like to complain and wish it was completely standalone but personally i think that's unrealistic

#

can you imagine how long it would take to rewrite all the tooling alone

lament copper
#

i was working on that for a while, because tiny was basically that ๐Ÿ™‚ but indeed it did not get enough buy-in, maybe for good reasons

#

anyway, while i agree that this stuff is ugly, i'm not 100% sure if it would help if we made a thing to conceal its ugliness and slowness and unscalability

#

maybe if we put it in a class called UglySlowUnscalableHacksForHybridInterop ๐Ÿ˜‰

blissful cedar
#

the thing i'm really hanging out for is dots animation coming back and maybe a way to call vfx graph natively because as far as i can tell it really doesn't need to be tied to a gameobject, it's all native calls anyway except the use of transform.
whenever animation package returns it'll remove a high % of hybrid stuff for me

static granite
#

Well hopefully its less ugly haha

lament copper
#

yeah it's definitely coming. people actively typing on it as we speak

static granite
lament copper
#

dots animation. i'm not aware of people actively working on a dots-specific vfx graph

#

but i get the impression there are bigger fish to fry with graphics before that

static granite
#

Got it. Thought you were replying to me at first. My "hopefully less ugly" comment was about your "UglySlowUnscalableHacksForHybridInterop" name.

vernal abyss
#

i'm a bit confused about the usage of statics. with domain reload disabled they always make problems. sometimes they even make problems when initialized. i never found out the real cause and just didn't bother with them. well, not totally true because i used [ClearOnReload] from the unity-domain-reload-helper plugin.

#

on the topic of hybrid/companion objects. it should be possible to add any kind of component/monobehaviour on entities. the rest, if unity doesn't want to deal with it, which is understandable to some point, remove all stuff having to do with companion linking and leave it to the community

lament copper
#

i'd say it depends on your exact usage. if you set them anew on awake(), i would think you would get that called when you enter playmode irrespective of domain reload, and that would reset the state

static granite
#

I'm also guilty of avoiding statics because of not understanding what I could or couldn't do with domain reloads. I just never bothered to learn and it was easy to just not use statics.

#

Related to hybrid, it does feel weird how we can add monobehaviours to our subscene game objects and they will just silently do nothing if there is no baker defined. I know its wishful thinking, but it would be awesome if these monobehaviors were automagically added as component objects to the entity if there is no baker defined

#

Although, it would need some kind of big warning to prevent people from thinking they are converting to fast ECS components when they really aren't

vernal abyss
#

why the push then to move system data out of systems? unity could easily provide us the ISystem struct, yet it was moved to SystemHandles which prevents us from this. accessing system data instead of going through an entity singleton is quite a bit faster and more direct

celest solar
#

with UnmanagedWorld you can get ref struct

vernal abyss
#

ah, wasn't aware. let me see

lament copper
#

basically, the singleton pattern allows us to provide reasonable safety together with burstability, and it also opens the door, very theoretically, to swapping out a system in favor of another that writes the same data in a different way.

celest solar
lament copper
#

we intentionally didn't make it super straightforward, because we do think it's a better idea in general to go through entity data. but let's be clear, that is not a hybrid issue; that's for when you're pedal to the metal bursting all the way down

vernal abyss
# celest solar smth that has `Resolve` in it's name, don't quite remember exactly

ok, GetUnsafeSystemRef<T> /// This system reference is not guaranteed to be safe to use. If the system or world is destroyed then the reference /// becomes invalid and will likely lead to corrupted program state if used. /// /// Generally, instead of public member data, prefer using component data for system level data that needs to be /// shared between systems or externally to them. This defines a data protocol for the system which is separated /// from the system functionality. /// /// Private member data which is only used internally to the system is recommended.

#

thanks @celest solar at least that's still possible.

static granite
#

Maybe one day?

lament copper
#

well hmm, that's a cool idea right there you have sir.

celest solar
vernal abyss
#

yep, that looks nice

static granite
#

So checkbox would be off by default to prevent stuff accidentally working in a slow path

celest solar
static granite
lament copper
#

yeah, but in the meantime, and for components that don't have equivalent native dots functionality (like audiosources)

celest solar
#

FMOD does a job very well

#

it's also burst compatible

lament copper
#

ima forward that image! the defaulting checkbox to off is the real kicker

static granite
#

I think its unrealistic to think this hybrid problem will go away once animation and cinemachine, and audio have dots native solutions. Although those are the biggest pain points.

lament copper
#

yeah it'll be quite a while before we cover really everything

#

forwarded! we'll see what the baking people think when they wake up (i can't remember but i think they're either all or mostly in europe)

static granite
lament copper
#

indeed, that is the real trick. given various difficulties, i wouldn't be super surprised if it were pushed to after 1.0, but you never know

mystic depot
static granite
mystic depot
#

It's not that I don't think it's a nice idea, I purely just think there's a lot of potential issues. Another, what would the Animator animate? A skinned mesh? Where does that live? Surely can't be on the GO you put in your SubScene as that will be converted to the entity comp version and Animator doesn't know how to talk to that. - Like, Managed Components which are not IComponentData, so e.g. Animator, Transform, MonoBehavoiurs etc. all need a reference to an actual instance. Where IComponentData also just happens to be that instance, that is not the case for UnityEngine.Objects think

static granite
#

Yeah that's a fair point. In the case of Animator, if it depends on transform, it means a transform syncing solution as well.

static granite
#

IIUC, the old companion link stuff was implemented by cloning the game object before converting the main one to an entity, and then the main game object is deleted. Not sure why it was done this way initially, but I would do it the opposite. If there are any monos on the game object with no baker defined and this check box is toggled on, then I would simply keep the authoring game object alive in the runtime world. No need to clone and fix references.

celest solar
#

that's a such a cool concept, I don't see why it's not going into masses

static granite
#

But, I do concede the issue about a monobehavior using things like gameObject.transform and that possibly not working

#

I'll just add that even if that checkbox (or equivalent) doesn't make it, I hope we get a warning about no defined baker. Feels like a newbie trap right now

static granite
#

I think hybrid transform stuff will always be an unfortunately complicated thing to solve in a nice and automatic way. Maybe if any managed component checkbox is checked, a thing pops up near the transform asking how to sync the transform (either None, FollowEntity, or FollowGameObject)

#

Not sure I like it, but this is what I'm talking about (the new dropdown under the transform component)

#

It would only appear if you have a managed component being added

bright basalt
#

I dunno if I'm a tiny minority here but I use DOTS for these reasons:

  1. NetCode (that is somewhat capable, i.e. it has predicted physics)
  2. Easy queries & ECS code patterns (I don't need to follow references everywhere)
  3. Speed (when I need it, which I rarely do)

I use Unity because:

  1. I know it
  2. Asset Store
  3. Other people know it and can help me

So my use case for Unity DOTS really does not hinge on the performance aspect at all. I'm not making some massive game that requires DOTS scale speed as part of the core.
All I want from DOTS is a clean way to write well organized code that my sole indie brain can comprehend and easy interoperability with things I can get from the asset store like particle effects and animations. Consistency is not overrated when you are the only developer working on your project and you need to be able to remember how it all works.

The thing that really gets me about the DOTS development direction is that its balls to the wall looking for speed.
I do understand that there are a lot of people that want speed, but I'd argue that more people want a full game first.
And pretty much all games have animations, particle effects, audio, cameras and GUI, all of which doesn't mesh with DOTS well at all right now.
I'd love for there to be DOTS solutions to these things right now but even if there were, many would be using older stuff cos they depend on the asset store.
So I just don't see a world where good GameObject interop is absent from DOTS, well, for the next 5 years at least.

bright basalt
static granite
bright basalt
#

I think maybe checkbox or something next to each thing would be better?
Currently I use a single component for each, i.e. FollowRotation, FollowTranslation

#

But I definitely think its a good spot to put it

#

I dunno, its hell tricky cos of hierarchy

static granite
# bright basalt I dunno if I'm a tiny minority here but I use DOTS for these reasons: 1. NetCode...

I'm kind of in the same camp. I didn't start using ECS because I had a slow game. In fact, I'd argue that it is practically impossible to add ECS to a game in an effort to speed it up. In those cases I would use the other parts of DOTS (jobs, collections, burst etc.). I started using ECS near the start of my current game because I wanted "performance by default". In my case, I am making a game that that needs to simulate thousands of objects at the same time, so performance does matter. But my first priority is finishing the game, not making the game as fast as possible. Nice workflows and easy to maintain code is more important to me than burst-everywhere-all-the-time-no-matter-what. I realize that performance-by-default relies on that, but we, unfortunately, need some amount of hybrid to make a complete game right now.

static granite
#

For example, an entity might need to drive the position of the skinned mesh, but a bone on that skeleton might need to drive the position of an entity.

bright basalt
#

Hmm that's a good point, I don't currently have animations driving the position of entities.

static granite
#

Yeah actually in my example, things would be very complicated. In order for the animator to write positions out to bones, they need to be game objects. That means the entire hierarchy of game objects would be needed at runtime.

static granite
#

What about this instead. Every UnityEngine.Component on the game object (including Transform) would have a new check box. This would be used to tell the baking system to add that component as a managed component to the companion entity. By default, all of these checkboxes would be off by default. If any are toggled on, the companion game object will be created and managed for you, but only with the components that you specified with the checkboxes.

With this, a user can keep a Transform while still baking out transform-related ECS components. They could do this on the entire hierarchy of a skeletal mesh. Then they can add specific ECS components to entities like FollowGameObject or FollowEntity to add the transform syncing where they need it.

#

Btw, I solved this exact problem (entity moves game object with animator, animator moves bone that moves an entity) in my project already. But I'm using a tag system to find and link the game objects and entities I care about. What I'm proposing here is solving the latter.

lament copper
#

you can't have any monobehaviour without a transform, i would like to point out

static granite
bright basalt
#

That sounds pretty perfect to me.

lament copper
#

it's possible that this is actually very similar to iconvertgameobjecttoentity and it's impossible to get it to be fast and incremental and reliable and so this idea is bad for the same reason that that was bad

static granite
bright basalt
#

The alternative is that people are just rolling their own anyway

static granite
#

Or similar to the old ConvertAndInjectGameObject option

#

Somewhat related, but I think it would be cool to see the output of baking, broken down by component in the inspector. Previously, this didn't make sense because mono -> ICD wasn't one-to-many. You could have multiple monobehaviours all contributing to a single ICD. But the new Baker is always one-to-many. So I'm imagining that each game object Component has an area that shows the ICD types being added to the entity by baking. If there are none, you get a warning. This is also where the checkbox would be to add the mono as a managed component (which would then show in the list of types being added to the entity).
I'll make another mock up of this idea later today.

#

I'm essentially taking about making this Entity Baking Preview be broken down per game object Component. I feel like that would make it much more useful and would shed some light on the how the game object is being baked.

static granite
bright basalt
#

Great write up!

static granite
#

Thanks! I may have gone a bit overboard with the photoshop mockup haha

golden nimbus
# mystic depot It's not that I don't think it's a nice idea, I purely just think there's a lot ...

I think when official working on this feature, needs to make it to game production level by default. You can make it like companion solution but better that internally u still instantiate game object and auto get all the required managed component ticked by user at baker and it supports game object pooling by default. On top of tat, it needs to support content delivery i.e. addressables.

But this comes out another question that in future will have dots addressables for content delivery of entity and subscene that becomes maintenance issue that need to maintain both addressables and dots addressables setup. It seems like needs to have unify authoring experience for addressables and dots addressables that only need to setup once. If not I afraid it will become yet another URP/HDRP/Built-In RP disaster.