Suggesting solutions for SerializeField warning

Summary of the problem

Back in 2018.4 a decision was made to remove the suppressor on the warning known as CS0649. This warning appears when a private or internal field is declared but never assigned a value.

When a MonoBehaviour contains a field that is private. One can add the attribute [SerializeField] to have the value shown in the inspector. This is because the inspector only shows serialized data and private fields are not serialized.

Since the removal of the suppressor, users have been seeing this message on their code:


“Assets\NewBehaviourScript.cs(8,12): warning CS0649: Field ‘NewBehaviourScript.myField’ is never assigned to, and will always have its default value null”

What we want from you
Please answer the following in a reply in this thread:

  • What’s your level of unity experience?
  • What’s the current project you are working on?
  • Which solution should we implement for 2018.4 LTS, 2019.4 LTS and 2020.2 based on the list below?
  • Which solution should we focus on for new releases of Unity 2021.1 and above, based on the list after the solutions for 2018.4, 2019.4, and 2020.2?

Solutions for 2018.4, 2019.4, and 2020.2
Project Setting, reorderable list
In the project settings window we add a list of default suppressed warnings. This gives you the ability to keep or remove the list of suppressed warnings. In addition, this allows you to add new compiler arguments that you want to pass to the compiler. The arguments will be passed to every assembly being compiled in your project. In addition to suppressing the warning for SerializeField, the warning will also be suppressed for any other valid cases.

Project setting, checkbox
In the project settings window we add a toggle button to enable and disable a built-in list of these suppressed warnings. Compared to the list approach, you cannot add or remove any of the suppressors individually. As with the previous solution this will not only suppress the warning for SerializeField, the warning will also be suppressed for any other valid cases of this warning.

Suppress the Warning by Default
In this case we would suppress the warning by default. There will be no UI to either enable or disable the behaviour. This was the old solution before the regression was introduced. This will work exactly as in 2017.4.

Nothing
None of the solutions will be applied. You can use one of the following workarounds to resolve the problem.
Today you can remove the error by adding the following pragma statements in your code:

#pragma warning disable 0649
[SerializeField]
private string m_MyField;
#pragma warning restore 0649

This will suppress the individual warning the pragma block is covering.

Another possibility today is to add a csc.rsp file the file content:

-nowarn:0649

By changing the field to public and not using SerializeField the warning will not be shown.
Assigning a default value to the field will do the same.

Solutions going forward
In order to make a more focused solution to this problem, we want to hear which solution we should be implementing going forward.

Assembly Definition Inspector
In the inspector of an .asmdef file we add a field where you can type in the additional compiler arguments you want to pass along. These arguments can be any of the ones supported by the Roslyn Compiler.
By suppressing the warning in this fashion this will not only suppress the warning for SerializeField, the warning will also be suppressed for any other valid cases of this warning.

This method will only work if your code is structured in this manner. If you do not have an asmdef for the project, it will not be possible to add these additional arguments.

This will function similar to the Project Setting approach. The main difference will be that this setting is per assembly. This will allow the assembly to add additional compiler arguments in addition to the ones that are hardcoded.

Roslyn Analyzer
With the newly added support for Roslyn Analyzers in 2020.2, we can add an analyzer to specifically suppress the warning for SerializeField. This will not add the ability to add additional compiler arguments.

We would ship these analyzers as a package that can be added to the project. They would work the same way as Visual Studio and JetBrains today is suppressing this warning in their code editors. These analyzers can be found here: GitHub - microsoft/Microsoft.Unity.Analyzers: Roslyn analyzers for Unity game developers and can be used in 2020.2 in the newest release of the code editor.

In addition, we can append a better message to the compiler warning to notify users about this possibility of adding the package to suppress the warning for SerializeField.

Changing Best Practices
We update our documentation to explain that a field should be public if you want it visible in the inspector. Rewrite the SerializeField documentation with a note that this pattern is not recommended and the issue that one can run into.

In addition we can append a better message to the compiler warning to notify users that this pattern is not recommended and to make the field public or assign a value to it in the code.

13 Likes
  • Mid-upper level, 4 years professional.

  • Location-based mobile game based on a large IP.

  • Project Setting, reorderable list with sane defaults is something that would provide the best balance of customizability and discoverability for both junior and senior devs.

  • Roslyn Analyzer sounds like a good approach, it would also act as a nice way to introduce developers into the existence of analyzers, and the world of static-code checking.

Please, for the sake of everyone working on larger projects/teams remove even the mention of:
We update our documentation to explain that a field should be public if you want it visible in the inspector. Rewrite the SerializeField documentation with a note that this pattern is not recommended and the issue that one can run into.
In addition we can append a better message to the compiler warning to notify users that this pattern is not recommended and to make the field public or assign a value to it in the code.
It is already hard enough to explain API design and data access control to new developers who only get Unity education without any engineering background without public fields being the only way of serializing things.

11 Likes
  1. Longtime Unity hobbyist - intermediate level. Professional software developer.
  2. Single player physics-based puzzle game.
  3. I like the first option - Project Setting, reorderable list. Adding defaults for new projects would be a good idea as well.
  4. Roslyn Analyzer solution looks the nicest to me. I especially think Changing Best Practices to encourage public fields would be a mistake. It encourages bad code. Specifically it encourages users to violate the Encapsulation principle of Object Oriented Programming by having public fields all over the place.
9 Likes

I agree with theOrioli and PraetorBlue that encouraging public fields is a mistake. Our default workflow is to keep our serialized fields private, since these often are intended for designers to tweak in the editor. Making those fields public opens up for all kinds of issues where developers unknowingly might change the values set by design.

11 Likes

Hello,

I’ve been waiting for this fix for so long now, I’m so glad that you’re finally addressing it. Thank you for that.

  1. Highly experienced, with 8+ years of development. I am lead game developer of a successful mobile game company since 2 years now, with hundred of thousands of DAU playing our games.

  2. Mobile hardcore strategy games.

  3. From what I understand, Project Setting, reorderable list is not a fixed at all and is not what we expect from this fix. Same thing for checkbox, this is not satisfying at all.

"Suppress the Warning by Default" => YES ! This is exactly what all developers are waiting for, just a fix for the regression. Not a workaround that hides the issue.

  1. Assembly Definition Inspector is not satisfying either, as it hides valid cases. Roslyn Analyzer could be a good solution, even if I lack of visibility right now to be sure about it.
    With all my respect, Changing Best Practices is one of the most absurd / chocking thing I ever read on this subject, and I had to read it 3 times to be sure that I was not misreading it. Please don’t do that.

In short: The warning should only be raised in valid cases, and not when [SerializableField] is used. The Unity fix should not hide the issue by suppressing valid cases for this warning.

Anyway, thank you for working on it, and I hope to finally see this fix asap!

11 Likes

I got here from a series of threads complaining about this issue, after finding this issue annoying.

  • What’s your level of unity experience?

  • I’ve been shipping Unity products for Microsoft for the past 7 years

  • What’s the current project you are working on?

  • Dynamic 365 Remote Assist for Hololens 1, 2, and Mobile

  • Which solution should we implement for 2018.4 LTS, 2019.4 LTS and 2020.2 based on the list below?

  • Surpress the warning by default. The field will not always have it’s default value null. The warning is simply false information.

  • Which solution should we focus on for new releases of Unity 2021.1 and above, based on the list after the solutions for 2018.4, 2019.4, and 2020.2?

  • Surpress the warning by default. The warning is simply false.

7 Likes
  • still a beginner, actively learning,
  • a 2D platformer,
  • the first solution “Project Setting, reorderable list”,
  • the solution where you “add a Roslyn analyzer to specifically suppress the warning for SerializeField”.

Please, do not modify the best practices, even if you are asked to! :slight_smile:

Thank you!

3 Likes
  • 10+ years with Unity, using it in a professional capacity

  • Games, Unity assets and learning resources

  • Nothing

  • Roslyn Analyzer

I’m extremely confused about this post.

This is very misleading, as there’s a way better way:

[SerializeField]
private Thing thing = default;

I am using this all over the place with no issue. Once roslyn allows Unity to just define that [SerializeField] should suppress this warning, that’s great, but until then, why would we disable this warning project-wide? Warnings exist for a reason and just disabling them because we don’t want to add a little = default is definitely a very bad idea.

Edit: Clarification because people seem to misunderstand: I’m not saying that the default keyword is the best and final solution. I’m saying it’s the best option until we get programmatic suppression - while just disabling the warning globally or using #pragma are not good ideas.

For the love of your personal favorite diety, please don’t do that. Unity docs are historically full of horrible best practices, please don’t add another one. Having a thing publicly accessible from other classes and having it serialized in the editor are two things that should continue to be kept seperate. Sometimes you want things public, sometimes you want things non-public, sometimes you want to have a deserialized value and sometimes you don’t. All four combinations exist and have useful application scenarios.

What I want you to do is

  • Wait until [SerializeField] can be set up to tell the compiler to suppress the warning automatically. If that’s not feasible for this or that LTS version, then do nothing at all.
  • Recommend to use the default keyword. Don’t recommend using #pragma, don’t recommend using public just to get rid of a warning.
15 Likes
  1. Significant - I’ve been using Unity since Unity 5.
  2. Ostensibly a puzzler, but have spent much time recently delving into ray-traced visuals and noise algorithms.
  3. Project setting, reorderable list - this seems to be the most balanced option.
  4. Roslyn analyzer is probably my preferred option.

And just to echo everyone else, making non-standard commentary on best practices is really not great. I love Unity, but the documentation already leaves much to be desired, and for folk learning software development by way of Unity, filling their heads with bad ideas is not going to be good.

1 Like
  1. 8+ years as a professional game developer (5+ Years with unity, since unity 4) , Head of Development at a studio with several shipped unity titles
  2. A VR shooter for PCVR and quest platforms
  3. “Suppress the Warning by default” as others have stated fix for the regression
  4. “Surpress the warning by default” is the best solution. I think “Roslyn Analyzer” and “Reorderable List in Project Settings” are worthy of exploration also.

I would also like to echo VGMFR’s comments. The idea of “Changing Best Practises” to encourage public fields just for serialization purposes is quite honestly ridiculous. It goes against nearly every principle of software engineering. On a related note, I’d suggest that making a field public would automatically NOT make a field serialized by default. My preference would be that in order to make a field serialized, the attribute would required, since the accessibility of a field by code has nothing to do with it’s serialization functionality, and it’s visibility in the inspector for that matter, They are 3 seperate things. This is my preference and I cannot be alone.

The fact that this is even being suggested is very concerning to me and my team given we rely on your technology. It’s not the thought of this being implemented that concerns me, it’s what it might represent, which a great disparity between philosophies.

Has this option been discussed internally and taken seriously? It would be interesting to have some insight into the thought process behind this suggestion.

@FlaSh0-G Most half decent IDEs will tell you that it’s redundant to initialize a field when the value is it’s default value. It’s not about being lazy, you are adding something that is a workaround, something that’s unnecessary and therefore obsolete.

9 Likes

Both “Suppress the Warning by Default” and “Nothing” works for me.

Using Roslyn Analyzer sounds like a solid solution, because it seems that’s the only option that specifically suppresses the warning for SerializeField.

The other ideas seem to suffer from side-effects, such as ignoring 0649 for cases other than SerializeField too. I still want to get 0649, just not for SerializeField.

1 Like

What’s your level of unity experience?
6 years of full-time professional work. 1 shipped game, very close to 2 shipped games.

What’s the current project you are working on?
Mesmer:
https://twitter.com/oleivarrudi/status/1301630336561020929
https://twitter.com/oleivarrudi/status/1301628364197855244

Which solution should we implement for 2018.4 LTS, 2019.4 LTS and 2020.2 based on the list below?
The project settings “pass arbitrary arguments to the compiler” is something I could see being useful in general, rather than just for this instance. It would for example allow studios to add warnaserror for specific warnings or whatever.
So definitely go for that one!

Which solution should we focus on for new releases of Unity 2021.1 and above, based on the list after the solutions for 2018.4, 2019.4, and 2020.2?
The analyzer. That’s the cleanest thing, since it targets this specific issue, and doesn’t suppress useful warnings. The analyzer should definitely ship as a default package rather than an opt-in thing, as using [SerializeField] private is a best practice.

Gonna second everyone else on “update best practices” not being the best of ideas. “Tell people to write worse code so we don’t have to fix a problem” is not the best plan!

This would be a big improvement, yes.

7 Likes

I only randomly stumbled upon this :stuck_out_tongue:

Anyway, it seems that you skipped half of my post… The only decent solution is having the warning suppressed automatically through the attribute. But until we get that, we have to pick between

  • living with the warnings
  • add ugly pragmas in there
  • use default or
  • disable that warning globally.

All I am saying is that until we get programmatic suppression, option 3 is the best one. Nothing more. Of course not having to pick any of these band aid solutions would be infinitely preferable.

Either way, what I originally wanted to say is that I agree with this:

3 Likes
  • CS master, then 9 years of Unity experience as a professional.

  • Working on projects, yes.

  • - ☐ Project Setting, reorderable list (Useful, but not a solution for this)
    - ☐ Project setting, checkbox (If you want ignore all warning writers, then just turn off warnings, or look away from the console, pray a little)
    - ☐ Suppress the Warning by Default (No, this is reintroducing an error)
    - :ballot_box_with_check: Nothing

  • - ☐ Assembly Definition Inspector (Useful, but not a solution for this)
    - :ballot_box_with_check: Roslyn Analyzer
    - ☐ Changing Best Practices (Don’t add more hoops now, I’m already a circus animal).

2 Likes
  • What’s your level of unity experience?
    About 4 years, a long time hobbyist, and a CS student.

  • What’s the current project you are working on?
    Working on a mid-sized RPG, other than that, small WebGL games from time to time

  • Which solution should we implement for 2018.4 LTS, 2019.4 LTS and 2020.2 based on the list below?
    I like the reorderable list. It could be useful even for other cases besides [SerializeField], i.e. it’s nicer than having a csc.rsp file sitting at the root of Assets folder. I’d suppress CS0649 by default, so that it doesn’t confuse new users.
    I also often globally suppress obsolete warnings for some Asset Store assets specifically (because I don’t want to re-edit the scripts every time I update the asset), so this Project Settings solution would be nice to have.

  • Which solution should we focus on for new releases of Unity 2021.1 and above, based on the list after the solutions for 2018.4, 2019.4, and 2020.2?

  • Roslyn Analyzer*, because it fixes specifically the [SerializeField] false positive, and doesn’t hide the cases when the warning is displayed legitimately. I’d perhaps add the analyzers package by default when starting a new project (there’s already a lot of “optional” default packages anyway, and this one would be in the category of “fix/improvement” rather than “feature”).
    Definitely do not change best practices, simply because making everything public is not the best practice, and it would be unwise to pretend it is just to avoid an annoying incorrect warning.

1 Like
  • What’s your level of unity experience?
    11 years of professional Unity development.

  • What’s the current project you are working on?
    Computer vision visualization for autonomous vehicles, and various long-term game passion projects.

  • Which solution should we implement for 2018.4 LTS, 2019.4 LTS and 2020.2 based on the list below?
    I agree with @Rallix . The re-orderable list would be useful in general, but CS0649 should be suppressed by default. If you don’t have the man-hours to complete the re-orderable list for 2020.2, then just turn this warning off until a more robust solution is completed.

  • Which solution should we focus on for new releases of Unity 2021.1 and above, based on the list after the solutions for 2018.4, 2019.4, and 2020.2?

  • Roslyn Analyzer* seems like the way to go if it can prevent false positives. I’m unsure on that front. Though I would encourage adding the package to all projects by default. This issue is confusing even for senior devs who might only have some familiarity with Unity. Good developers don’t like to disable warnings project-wide, I’m currently working in a very large project with #pragma warning disable CS0649 and

#pragma warning restore CS0649

surrounding all Serialized fields in every class. It’s a hell-scape.

This should not even be considered. This is the opposite of a best practice.

2 Likes

[quote=“miniwolf_unity, post:1, topic: 806898, username:miniwolf_unity”]
field should be public if you want it visible in the inspector. Rewrite the SerializeField documentation with a note that this pattern is not recommended and the issue that one can run into
[/quote]Can’t believe what I just read.

Just add Roslyn Analyzer and stop wasting time on anything else.

3 Likes

@miniwolf_unity 's proposition was probably a bait, just to see who would gulp it. :slight_smile:

1 Like

Dig for bit and there’s a fix that probably works for 2018.4+ (works for me in 2020.1)

  1. In project folder create a folder (I’ve called mine RosalynAnalyzers)
  2. Download NuGet Gallery | Microsoft.Unity.Analyzers 1.19.0, unzip by changing extension from nupkg to zip.
  3. Copy dll from “analyzers\dotnet\cs” to folder in step 1
  4. Create csc.rsp in Assets folder
  5. Add -a:RoslynAnalyzers\Microsoft.Unity.Analyzers.dll there
  6. Happy coding

I guess it works, before:

After:

Btw I’m also using great plugin by @tertle that makes analyzers work also with VS as some critical ones are missing like:

My RosalynAnalyzers folder:

1 Like

For Linux and Mac?