I was reading through the Event system documentation and looked at how it’s used in the project. I think it’s a very interesting way to implement such system.
Have you used this system in other projects already and what types of issues did it cause?
I’m asking because once you start using asset bundles, you must be very careful that Unity does not duplicate assets. In terms of just assets (textures, meshes, sounds, etc) this is not a big deal, it just wastes memory.
However, since the event channel assets drive game-logic, I assume duplicated event channel assets can be problematic.
For example, if the same event channel asset is pulled into two asset bundles, each having a copy of that asset, one game system might listen to a completely different event channel in memory than another game system is broadcasting to.
This probably can be fixed by storing the event channel assets in an asset bundle that is a dependency of “everything” else, but I think it’s still quite error prone in this regard and getting asset dependencies in asset bundles right is a very tedious task and quite a black-box too imo. You can basically break the game-logic with a content change if suddenly event channel assets are duplicated across bundles.
Did you ever run into this issue? What’s your strategy to combat this issue?
It’s a very good point, @Peter77 . We haven’t run into the issue yet as we haven’t yet sectioned the game into bundles (except the Localisation files which do it on their own).
What I believe is that we could have the EventChannels all in one bundle, which would of course a local one (side note, in this game all bundle will be local) so included in the build and unique. This should make it so any other bundle referencing it will find it. But I’ll double check just in case.
Perhaps this limitation has been lifted in Unity 2020.x with the overhauled Generics serialization, but Open-Project-1 is using Unity 2019.4 at the moment.
Hey guys, I double checked with a person from Unity who deals with Addressables and AssetBundles a lot. Their reply confirmed what I was thinking:
The Addressables system tracks dependencies of objects. If you reference a ScriptableObject from a GameObject in a scene, and you reference the same SO from another GO in another Scene, the system knows it the same SO.
When we pack Scenes into Bundles, it’s important to mark the SOs as Addressables.
If they are, then the system will recognise the dependency and make it so that (for instance) SceneA, contained maybe in Level1Bundle, correctly references SO1 in a certain AssetBundle we’ll call SOBundle. SceneB (contained in Level2Bundle) also references SO1 in SOBundle. When requesting the load of either scene, SOBundle will be loaded too.
If the SOs are not explicitly marked as Addressables, they will be still pulled in these bundles because they are still a dependency. But this time they will be duplicated, giving the issue that you are describing.
So, we just need to mark things as Addressables correctly. Makes sense?
PS: for reference, it’s the same discussion going on in issue #331. I’m going to close that soon to avoid confusion.
Do you then need to replace all hard references to event SOs with an Addressables.AssetReference? Or is it irrelevant and it’s ok if some MonoBehaviours reference SOs hard and some through AssetReference?
I think it’s worth to point out that there are drawbacks to using event-based architectures:
It makes navigating the code harder, because you can no longer simply F12 your way into the callled function. Instead you have to search for all references to that event channel to find the methods that subscribed to it. This added friction can add up to the total work time and makes code discovery harder.
Dispatching an event is more expensive than calling a method due to the added layer of indirection, which can impact performance in “hot” code.
In this particular case, problem #1 is made much, much worse because the event channel is supposed to be assigned via the inspector. Since Unity doesn’t offer any way to find which objects/assets reference a specific asset, the only way to know who’s listening to a channel is to place a breakpoint in the calling site and step through the dispatching. This can quickly become unmanageable if used too often.
I worked on projects that abused Unity events and the problems were very similar, the difference being you have no idea of who is calling what.
Amen!! How do you structure your projects nowadays?
When a dependency visualizer is added to the editor it’ll be workable but for now a safety label is needed on that SO Kool-Aid bottle: “drink in moderation”.
That’ll be good for some and bad for others, you def should not have both on github like you do, it’s confusing.
It doesn’t let me link a specific time, but yeah, we did mention that it was noted by a contributor at 4:28 - though not by name.
But definitely thanks for bringing it up. More than an issue though it’s actually an important topic when talking AssetBundles that is worth to touch on, that’s why we included it in the video.
That’s cool @cirocontinisio . Anyway, what happens if you have pack a scene IN A DIFFERENT UNITY PROJECT. Loaded to a remote server and downloaded in a main different project. Is there anyway to get contact between scriptable objects with the same name? It would be great, isn’t?