Skip to content

Add built-in serialization for UnityEngine.Pose #2675

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

Open
PitouGames opened this issue Aug 24, 2023 · 4 comments · May be fixed by #2677
Open

Add built-in serialization for UnityEngine.Pose #2675

PitouGames opened this issue Aug 24, 2023 · 4 comments · May be fixed by #2677
Labels
stat:reply-needed Awaiting reply from Unity account type:feature New feature, request or improvement

Comments

@PitouGames
Copy link
Contributor

PitouGames commented Aug 24, 2023

Is your feature request related to a problem? Please describe.

Unity provide a primitive struct called Pose, which is a composition of a Vector3 and a Quaternion. This type is not very known, but very usefull, for instance in a single list of waypoints that also need to store their rotation.

This type is not listed in the documentation: https://docs-multiplayer.unity3d.com/netcode/current/advanced-topics/serialization/unity-primitives/, and doesn't work if used in an Rpc or NetworkVariable.

[ServerRpc()]
private void TestServerRpc(Pose p)
{
    Debug.Log(p);
}
Assets\Scripts\Test.cs(32,13): error  - TestServerRpc - Don't know how to deserialize UnityEngine.Pose. RPC parameter types must either implement INetworkSerializeByMemcpy or INetworkSerializable. If this type is external and you are sure its memory layout makes it serializable by memcpy, you can replace UnityEngine.Pose with ForceNetworkSerializeByMemcpy`1<UnityEngine.Pose>, or you can create extension methods for FastBufferReader.ReadValueSafe(this FastBufferReader, out UnityEngine.Pose) and FastBufferWriter.WriteValueSafe(this FastBufferWriter, in UnityEngine.Pose) to define serialization for this type.
private NetworkList<Pose> poseList = new NetworkList<Pose>();

private void AddAnItem() {
    poseList.Add(new Pose(transform.position, transform.rotation));
}
ArgumentException: Type UnityEngine.Pose is not supported by NetworkVariable`1. If this is a type you can change, then either implement INetworkSerializable or mark it as serializable by memcpy by adding INetworkSerializeByMemcpy to its interface list. If not, assign serialization code to UserNetworkVariableSerialization.WriteValue, UserNetworkVariableSerialization.ReadValue, and UserNetworkVariableSerialization.DuplicateValue, or if it's serializable by memcpy (contains no pointers), wrap it in ForceNetworkSerializeByMemcpy`1.

Describe the solution you'd like
Add a default serializer for UnityEngine.Pose.

Describe alternatives you've considered
Today, users have to implement their own serializer or send Vector3 and Quaterion separately.

@PitouGames PitouGames added stat:awaiting-triage Status - Awaiting triage from the Netcode team. type:feature New feature, request or improvement labels Aug 24, 2023
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue Aug 25, 2023
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue Aug 31, 2023
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue Nov 13, 2023
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue May 1, 2024
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue May 1, 2024
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue May 6, 2024
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue Aug 18, 2024
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue Oct 21, 2024
@michalChrobot michalChrobot added stat:reply-needed Awaiting reply from Unity account and removed stat:awaiting-triage Status - Awaiting triage from the Netcode team. labels Apr 1, 2025
PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue Apr 19, 2025
@PitouGames
Copy link
Contributor Author

@michalChrobot
Hi, I have updated my PR. Please see #2677

PitouGames added a commit to PitouGames/com.unity.netcode.gameobjects that referenced this issue Apr 19, 2025
@michalChrobot
Copy link
Collaborator

Hi, thanks for pinging. We will try to find some time to check it out next week

@github-actions github-actions bot added stat:awaiting-response Awaiting response from author. This label should be added manually. and removed stat:reply-needed Awaiting reply from Unity account labels Apr 19, 2025
@michalChrobot michalChrobot added stat:reply-needed Awaiting reply from Unity account and removed stat:awaiting-response Awaiting response from author. This label should be added manually. labels Apr 19, 2025
@NoelStephensUnity
Copy link
Collaborator

NoelStephensUnity commented Apr 19, 2025

Hi @PitouGames ,

We will look into the possibility of making this a default type. However, you can always create your own Custom Serializers for various types that will work for RPCs, INetworkSerializable, and NetworkVariables.

As an example, adding Pose would look something like this:

/// <summary>
/// Custom Serialization Types
/// Includes <see cref="Pose"/> example.
/// </summary>
public static class SerializationExtensions
{
    public static void InitializePoseNetworkVariable()
    {
        UserNetworkVariableSerialization<Pose>.WriteValue = SerializationExtensions.WriteValueSafe;
        UserNetworkVariableSerialization<Pose>.ReadValue = SerializationExtensions.ReadValueSafe;
    }

    public static void ReadValueSafe(this FastBufferReader reader, out Pose pose)
    {
        reader.ReadValueSafe(out Vector3 position);
        reader.ReadValueSafe(out Quaternion rotation);
        pose = new Pose(position, rotation);
    }

    public static void WriteValueSafe(this FastBufferWriter writer, in Pose pose)
    {
        writer.WriteValueSafe(pose.position);
        writer.WriteValueSafe(pose.rotation);
    }

    public static void SerializeValue<TReaderWriter>(this BufferSerializer<TReaderWriter> serializer, ref Pose pose) where TReaderWriter : IReaderWriter
    {
        if (serializer.IsReader)
        {
            pose = new Pose();
        }
        serializer.SerializeValue(ref pose);
    }
}

You would just need to invoke SerializationExtensions.InitializePoseNetworkVariable when your application starts (i.e. before any NetworkVariable is serialized) in order to add the NetworkVariable support.

@github-actions github-actions bot added stat:awaiting-response Awaiting response from author. This label should be added manually. and removed stat:reply-needed Awaiting reply from Unity account labels Apr 19, 2025
@PitouGames
Copy link
Contributor Author

Thank you to both of you for the reply.

Yes Noel, that is what I meant when I wrote:

Describe alternatives you've considered
Today, users have to implement their own serializer or send Vector3 and Quaterion separately.

Thank you for the "official" sample code.

But it's developer work that can be avoided since Pose is an Engine type, just as Vector3 or Quaternion 😉

@github-actions github-actions bot added stat:reply-needed Awaiting reply from Unity account and removed stat:awaiting-response Awaiting response from author. This label should be added manually. labels Apr 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stat:reply-needed Awaiting reply from Unity account type:feature New feature, request or improvement
Projects
None yet
3 participants