Skip to content

feat: add NetworkObject and NetworkBehaviour reference types #1173

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

Merged
merged 9 commits into from
Sep 16, 2021

Conversation

LukeStampfli
Copy link
Contributor

Implements helper structs for using NetworkObjects and NetworkBehaviours in RPCs and NetworkVariables.

One thing to note about this implementation is that the resolving is stateless. This can be a problem because netcode recycles the networkids so in theory the reference can end up pointing to a different object if the original one gets despawned. The fix for this would be to cache the NetworkObject inside the reference after resolving it for the first time but this does not work with NetworkVariable as the struct would no longer be unmanaged.

/// A helper struct for serializing <see cref="NetworkBehaviour"/>s over the network. Can be used in RPCs and <see cref="NetworkVariable{T}"/>.
/// Note: network ids get recycled by the NetworkManager after a while. So a reference pointing to
/// </summary>
public struct NetworkBehaviourReference : INetworkSerializable, IEquatable<NetworkBehaviourReference>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrt:

The fix for this would be to cache the NetworkObject inside the reference after resolving it for the first time but this does not work with NetworkVariable as the struct would no longer be unmanaged.

I think this being a struct, value type and let's say documented with its proper usage etc would be good enough IMHO.
Maybe exposing internal m_NetworkBehaviourId over a public get-only ulong property would give more clues about this thing is actually working inside (+ maybe another TryGet API that accepts that ID too?).
To be fair, I'd like people to use this like: MyServerRpc(new NetworkBehaviourReference(MyNetworkBehaviour)); etc (you get the idea).

long story short, I wouldn't worry about it too much :P

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also what about super-generic GameObject one where we try to get NetworkObject or NetworkBehaviour component from it to serialize over the network? 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can actually do MyServerRpc(MyNetworkBehaviour) and the implicit operator will make it work automagically as long as the parameter on the RPC function itself uses the reference.

Regarding the GameObject one. I think taking a NetworkBehaviour from it would be a bit too far fetched so I'm afraid people might get confused as to why they can send some GameObjectReferences and not others. NetworkObjectReference also has implicit operators from/to GameObject so you can pass an GameObject into an RPC with a NetworkObjectReference parameter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh this implicit operator, just saw this :)

public static implicit operator NetworkObjectReference(GameObject gameObject) => new NetworkObjectReference(gameObject);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with your second point too!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, what about adding a few other RPCs for these implicit operators into tests you implemented in this PR?
that way, they'll be tested + will be good sample code as well — what do you think?

using UnityEngine.TestTools;
using Object = UnityEngine.Object;

namespace Unity.Netcode.RuntimeTests.Serialization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not put tests under specific/separate namespaces and keep using the common top-level one?

Suggested change
namespace Unity.Netcode.RuntimeTests.Serialization
namespace Unity.Netcode.RuntimeTests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then they are not nicely sorted into a single place in the test window. E.g. right now I can simply run all serialization tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ugh, we're going to play "find where my tests are" game with foldout menus instead of a flat hierarchy :P
it's fine though, it's kind of a personal preference — I just wanted to follow the same "per-asmdef namespaces" here too but can live without it.

@0xFA11 0xFA11 changed the title feat: NetworkObject and Behaviour reference feat: add NetworkObject and NetworkBehaviour reference types Sep 13, 2021
Copy link
Contributor

@0xFA11 0xFA11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ship-it-parrot)

…ect-ref

# Conflicts:
#	com.unity.netcode.gameobjects/Tests/Editor/Serialization.meta
@0xFA11 0xFA11 enabled auto-merge (squash) September 16, 2021 15:02
@ShadauxCat
Copy link
Collaborator

Is this just to get around the problems that prevent us from being able to pass NetworkObject and NetworkBehaviour directly in RPCs? If so, those problems are corrected in INetworkMessage - INetworkMessage allows implementing extension methods for the serializers that allow doing exactly this without needing to create wrapper classes.

@0xFA11
Copy link
Contributor

0xFA11 commented Sep 16, 2021

@ShadauxCat

Is this just to get around the problems that prevent us from being able to pass NetworkObject and NetworkBehaviour directly in RPCs? If so, those problems are corrected in INetworkMessage - INetworkMessage allows implementing extension methods for the serializers that allow doing exactly this without needing to create wrapper classes.

No, we intentionally wanted to have these reference types so that things won't look like they are serializing NetworkObject/NetworkBehaviour/GameObject magically. We also kill SpawnManager deps in other places too.

@0xFA11 0xFA11 merged commit 0654eaf into develop Sep 16, 2021
@0xFA11 0xFA11 deleted the feature/networkobject-ref branch September 16, 2021 16:10
SamuelBellomo added a commit that referenced this pull request Sep 16, 2021
* develop:
  feat: interpolation for network transform (#1060)
  feat: add `NetworkObject` and `NetworkBehaviour` reference types (#1173)

# Conflicts:
#	com.unity.netcode.gameobjects/Components/Interpolator.meta
#	com.unity.netcode.gameobjects/Components/Interpolator/BufferedLinearInterpolator.cs
#	com.unity.netcode.gameobjects/Components/NetworkTransform.cs
#	com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformStateTests.cs
#	testproject/Assets/Prefabs/PlayerCube.prefab
#	testproject/Assets/Scenes/ZooSam.unity
#	testproject/Assets/Scripts/MoveInCircle.cs
mollstam pushed a commit to Keepsake-Games/com.unity.netcode.gameobjects that referenced this pull request Feb 13, 2023
…ty-Technologies#1173)

* feat: make networkobjectref not stateful

* fix docs

* standards.py “¯\_(ツ)_/¯“

* standards.py

* refactor: standards.py now applied correctly

* Tests for implict operators and NetworkVariable

Co-authored-by: M. Fatih MAR <mfatihmar@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants