-
-
Notifications
You must be signed in to change notification settings - Fork 190
Description
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:
- Load the ReplicatingPropertyIssue scene in a Unity project with FishnetPro (this uses Yak to easily test that locally)
- Start playmode
- Check the console for the warning log with the different deserialized value : notice that
NonReplicatedPropertyistrueinstead offalse.
Steps to reproduce the behavior generally:
- 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
- Send an instance of this class with the property set to a different value than its default one via a FishNet RPC
- 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.
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
}
}