Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Netcode and Disabled GameObjects

Discussion in 'Netcode for GameObjects' started by GhostTownGames, Jan 12, 2023.

  1. GhostTownGames

    GhostTownGames

    Joined:
    Dec 15, 2015
    Posts:
    6
    This seems to have been a deliberate design choice but Netcode seems to interact with gameobjects that are disabled in the scene in weird ways that don't make sense to me.

    Firstly if an object is disabled in the scene, it doesn't get spawned when the scene is loaded and so has to be manually spawned later. ( this is due to NetworkSpawnManager using Object.FindObjectsOfType in ServerSpawnSceneObjectsOnStartSweep to find network objects ).

    But also if a disabled NetworkObject is a child of an enabled NetworkObject, then the enabled object will collect child's NetworkBehaviours, enabled or not, assign itself to that NetworkBehaviour NetworkObject propterty (due to a call to GetComponentInParent, which ignores diabled parent objects, in the NetworkObject property field accessor in NetworkBehaviour), and it will do so even though that behaviour will not have InternalOnNetworkSpawn called (and indeed that code throws a warning saying "Netcode for GameObjects does not support spawning disabled NetworkBehaviours!") so it will have an incorrect BehaviourID. This means if a disabled NetworkObject in the scene is ever enabled it will have Behaviours that aren't associated with it, and that if passed into a NetworkBehaviourReference will be incorrectly identified.

    So TLDR this amounts to Netcode just not really supporting GameObects that are disabled in scenes ever being enabled at runtime, which seems like a pretty common use case? Have I got this right? Is this a feature that will be added? Is this a bug?
     
  2. ACWestmountain

    ACWestmountain

    Joined:
    Nov 7, 2022
    Posts:
    7
    I just had issues with this. My workaround was to just disable every other component, mesh renderer so on. So that the object could still be Active yet not interact with the scene in any other way really. But it would be preferable if it just worked with the common use case of setting the object as inactive.
     
    GhostTownGames likes this.
  3. bosko0509

    bosko0509

    Joined:
    Apr 13, 2018
    Posts:
    4
    Still nothing till this day.. wondering if someone else already found another solution that does not include disabling all components and activating them
     
  4. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    252
    This sounds like a bug to me if I understand it correctly (and I think I know why that might have started happening recently due to a change in how we find the NetworkBehaviours associated with NetworkObjects). I will look into this.

    Regarding disabling an in-scene placed NetworkObject:
    It really depends upon the reason behind why you want to start with something disabled and then enable it at a later point as to what I would recommend.

    A few things about NetworkObjects and NetworkBehaviours:
    • You can spawn with or without observers
    • NetworkObjects can be viewed as the first part of a "network address" within your scene hierarchy. NetworkBehaviours then represent the "sub-address", and RPCs as well as NetworkVariables are the final destination.
      • If you disable the NetworkObject, then nothing is updated and for all intents and purposes it "does not exist".
    There are some common usage patterns in single player Unity (i.e. set something inactive until you need it) development that require some form of "network" synchronization. Showing and hiding a NetworkObjects (the original approach) was the intended replacement for this functionality...but that can be bandwidth and memory intensive.

    Alternately, you can use Object Pooling to pre-instantiate certain prefabs that you plan on "turning on and off". Primarily it was designed for frequently spawned/despawned objects (i.e. projectiles etc), but you can also use that same technique to "enable/disable" things without the memory allocation cost (but you still will incur the bandwidth cost of spawning).

    As bosko0509 pointed out, the final way you can handle this is by controlling what components are active or inactive on your GameObject. The complexity of this depends upon how you setup your prefab. You can have something relatively complex like the EnableDisableNetworkObject sample or you can incorporate the intention of enabling and disabling things within your prefab design and script. I whipped together a simple example (the SimpleEnableDisable project attached) of how to easily enable and disable various parts of a spawned object based on the "visual state" of the NetworkObject that is controlled by a "VisualFlags" NetworkVariable. I added some additional functionality to it that allows you to start with a specific visual state and then make adjustments during runtime. You could (theoretically) also incorporate a "visual state" that requires more than one flag to be set using this framework.

    upload_2023-12-19_13-58-7.png
     

    Attached Files:

  5. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    252
    Oh yeah, I made that an in-scene placed NetworkObject just due to the original post's context...but you could make that a network prefab and dynamically spawn it as well.
    The example project provides you with a way to more easily enable and disable an entire hierarchy of nested GameObjects if you wanted...or segments of each hierarchy. The general idea is that you can accomplish a nice divide between the more familiar single player approach with very little netcode script to support that functionality.
    The original over-all goal for NGO was to provide the building blocks that provided you with a myriad of potential approaches you could take. Some approaches are obvious (but opinionated) and others are perhaps not as obvious (but you dictate how opinionated the design will be).
     
    Last edited: Dec 19, 2023
  6. Pandazole

    Pandazole

    Joined:
    Sep 23, 2019
    Posts:
    26
    I believe this is a pretty common case in UI handling, especially if you have multiple UIs for different entities.

    Since they are disabled by default, I'm having an issue with spawning many different child NetwokBehaviors automatically under the main Canvas (which has the NetworkObject, at the root).

    My current approach is to disable the specific UI/GameObject after network Spawning.

    Code (CSharp):
    1.     public override void OnNetworkSpawn()
    2.     {
    3.         base.OnNetworkSpawn();
    4.         gameObject.SetActive(false);
    5.     }
    But I'm not sure about the side effects, since I do not know exactly how the order of execution here. Also, not sure how the NetworkBehavior children will be affected, although in my case everything is working just fine, which has been tested in a very small project.
     
  7. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    252
    That is sort of how I handle displaying GameObjects in pre-loaded scenes based on game state in this example project, which also contains some additional components you might find useful.
     
  8. Pandazole

    Pandazole

    Joined:
    Sep 23, 2019
    Posts:
    26
    Yes, your logic is way better approach to handle this issue, but needs extra little work if you want to disable a specific/handful of objects vs the whole scene.

    Personally, my UI menu is already handled like yours (Disabled when everything is set), but it's helpful to know the current limitation.

    Also, I loved your scene handling, I need to steal some of your techniques, if not all of them :)
     
  9. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    252
    Feel free to use any of that code (it is 100% MIT). If you have any suggestions or run into issues let me know and I can make adjustments to that code base as well. ;)
     
    firebird721 likes this.
  10. Pandazole

    Pandazole

    Joined:
    Sep 23, 2019
    Posts:
    26
    Great :D

    It seems there's an unnecessary event assignment here on the client side:

    upload_2024-1-8_7-57-53.png

    Since the online scene will be auto-synced with the host. (Prefab duplications oversight? )
     
  11. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    252
    Yeah... I haven't updated it for a few months and you are right... we did have a recent update where already loaded scenes are synchronized...

    Will need to do another update pass on that project.
    Thanks for bringing that to my attention! :)