-
Notifications
You must be signed in to change notification settings - Fork 562
feat: tool to enable monobehaviours only on server or client #477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: tool to enable monobehaviours only on server or client #477
Conversation
Inheriting from this abstract class insteead of a NetworkBehaviour allows a script to be disabled on Awake and only enabled in a client or a server specifically
This reverts commit 6080134.
using Unity.Netcode; | ||
using UnityEngine; | ||
|
||
namespace Unity.Multiplayer.Samples.Utilities |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file will be moved to the Utilities package when the PR will leave the draft status. I kept it here to make testing and iterating easier since ParrelSync doesn't sync the packages folder automatically
The issue this PR fixes could also be the cause of MTT-2475, but hard to verify since we don't have consistent reproduction steps for that bug yet |
|
||
namespace Unity.Multiplayer.Samples.Utilities | ||
{ | ||
public interface IClientOnlyMonoBehaviour |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if those interfaces are tightly coupled to monobehaviour and netcode, any reason we wouldn't just have an abstract class that inherits from NetworkBehaviour and has SetEnabled as abstract method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An earlier version of this used inheritance, with a single class inheriting NetworkBehavior with a protected field telling if it was meant for a server or a client. The disabling/enabling was handled by that abstract class in its Awake, OnSpawn and OnDespwn events.
The advantage was that we did not need a second script to enable/disable it, but it came with more restrictions that I wasn't really happy with. First, we would need to make sure to call the base methods inside those three methods if we wanted to override it in daughter classes. Also, it would mean that if a specific class needs that behaviour, all its parents would have to have it too, which might not make sense. i.e. class A is a client-only netbehaviour inheriting from class B that doesn't need to know if it is on a client or on a server. In this case, if we want to restrict A to only clients, we would have to have B inherit this abstract class, even though B doesn't require it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Yeah makes sense. I wonder if there could be a way to dynamically add the enabler without requiring us to remember to add it. It's too bad "RequireComponent" doesn't work on interfaces.
Or we could have some editor script magic with some reflection...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LukeStampfli @pdeschain @fernando-cortez what do you guys think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add "RequireComponent" to the classes implementing these interfaces themselves I suppose, but it's still not as plug-and-play as I hoped it could be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking back on it, would adding this recommendation as remarks in the interface descriptions be sufficient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using an interface here is better than using inheritance. With the updated xml docs on the interfaces I think it is easy enough to understand how to use this.
{ | ||
if (IsClient) | ||
{ | ||
foreach (var behaviour in gameObject.GetComponents<IClientOnlyMonoBehaviour>()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OnNetworkSpawn would be called with network pooling correct? This has the potential to be a very costly spawn, GetComponent isn't performant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
especially if there's multiple multiple spawns with pooling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh you're right, that would be super costly. Maybe I should cache all of this in its Awake method? Another solution could be to expose a list to the editor, but that would require us to manually enter all netbehaviours, and that would be even more work than what this tool is trying to simplify
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah caching would be good
on hold until we have true solution |
Adding this for all PRs that have been opened since this new flow has been added. Please add your changelog here project changelog file and/or package changelog file |
Description (*)
This PR adds a NetworkBehaviour that can be placed on a NetworkObject to make sure certain MonoBehaviours can only be enabled on active servers or active clients by using specific interfaces that those MonoBehaviours would inherit. This would remove that responsibility from those MonoBehaviours. It would also allow us to make some of them not be NetworkBehaviours anymore since it was mostly used for the OnNetworkSpawn to enable/disable themselves.
As an example, I have included in this draft PR an implementation of this feature with the interactive door.
Some pros of this solution:
Cons:
Related Pull Requests
Issue Number(s) (*)
Fixes issue(s): When implemented, should fix MTT-1683 & MTT-2433
Manual testing scenarios
Questions or comments
Contribution checklist