Skip to content

'NonSerialized' field-targeted attribute is not honored by generated serializer #935

@Elihpmap-Magic

Description

@Elihpmap-Magic

General
Unity version: 6.0 (6000.0.47f1)
Fish-Networking version: First found on 4.6.1, still replicated on 4.6.9
Discord link: I'm not on the community Discord, I kinda disagree on hiding the community ressources on private servers (even if I understand the utility of instant messages, I believe a publicly available forum would be better). I would rather discuss directly on this public issue report if needed. You can also contact me by mail if something requires a private discussion.

Description
When adding System.NonSerialized as a field-targeted attribute to a public property with a backing field. The value is still serialized and transmitted over the network.

Replication
Steps to reproduce the behaviour with the given example:

  1. Load the ReplicatingPropertyIssue scene in a Unity project with FishnetPro (this uses Yak to easily test that locally)
  2. Start playmode
  3. Check the console for the warning log with the different deserialized value : notice that NonReplicatedProperty is true instead of false.

Steps to reproduce the behavior generally:

  1. Create a classe with a backing-field property with the fild targeted attribute System.NonSerialized

like so for example: [field: System.NonSerialized] public bool TestBoolProperty {get; set;} = false

  1. Send an instance of this class with the property set to a different value than its default one via a FishNet RPC
  2. On the receiving end check the value of the property in the received class instance : the property is not to its default value but the one set on the rpc-calling side.

Expected behavior
Public field-backed properties with attribute [field: System.NonSerialized] should not be serialized (or at least not send over the network).

Example content
The example contains a simple scene and a unique script (retranscribed just below for easy access) to test this behaviour with a simple host configuration using Yak transport layer.

ReplicatingPropertyIssue.zip

single script content

TestHostBehaviour.cs :

using System;
using FishNet.Managing.Client;
using FishNet.Managing.Server;
using FishNet.Object;
using UnityEngine;

public class TestHostBehaviour : NetworkBehaviour
{
    public ServerManager server;
    public ClientManager client;
    void OnEnable()
    {
        server.StartConnection();
        client.StartConnection();
    }

    public override void OnStartClient()
    {
        ObserversRpc_ReplicateOnAllObserver(SemiReplicableClass.CreateAtOrigin());
    }

    [Serializable]
    public class SemiReplicableClass
    {
        public bool replicatedVariable = false;
        public bool ReplicatedProperty {get; set;} = false;
        [NonSerialized] public bool nonReplicatedVariable = false;
        [field: NonSerialized] public bool NonReplicatedProperty {get; set;} = false; //This is still replicated! (workaround : add 'private' accessor to the setter)

        public static SemiReplicableClass CreateAtOrigin()
        {
            return new() 
            {
                replicatedVariable = true, 
                ReplicatedProperty = true,
                nonReplicatedVariable = true,
                NonReplicatedProperty = true,
            };
        }
    }

    [ObserversRpc(RunLocally = false)] //Set RunLocally to true to test without semiReplicableClass replication (all values return true)
    public void ObserversRpc_ReplicateOnAllObserver(SemiReplicableClass semiReplicableClass)
    {
        Debug.LogWarning($"replicatedVariable = {semiReplicableClass.replicatedVariable}\n" +
            $"ReplicatedProperty = {semiReplicableClass.ReplicatedProperty}\n" +
            $"nonReplicatedVariable = {semiReplicableClass.nonReplicatedVariable}\n" +
            $"NonReplicatedProperty = {semiReplicableClass.NonReplicatedProperty}");

            //This prints:
            // replicatedVariable = True
            // ReplicatedProperty = True
            // nonReplicatedVariable = False
            // NonReplicatedProperty = True
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't workingResolved Pending ReleaseIssue is resolved and will be available on the noted version.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions