Skip to content

feat: Prefab QoL [MTT-5116] #2322

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 15 commits into from
Jan 11, 2023
Merged

feat: Prefab QoL [MTT-5116] #2322

merged 15 commits into from
Jan 11, 2023

Conversation

ShadauxCat
Copy link
Collaborator

Moves prefab list to a ScriptableObject and makes it publicly accessible to be programmable. Credit for most of the work goes to @JesseOlmer, I provided some refinements and testing (including unit tests)

Changelog

  • Changed: Network prefabs are now stored in a ScriptableObject that can be shared between NetworkManagers, and have been exposed for public access. By default, a Default Prefabs List is created that contains all NetworkObject prefabs in the project, and new NetworkManagers will default to using that unless that option is turned off in the Netcode for GameObjects settings. Existing NetworkManagers will maintain their existing lists, which can be migrated to the new format via a button in their inspector.

Testing and Documentation

  • Includes unit tests.
  • Includes documentation for previously-undocumented public API entry points.

Moves prefab list to a ScriptableObject and makes it publicly accessible to be programmable. Credit for most of the work goes to @JesseOlmer, I provided some refinements and testing (including unit tests)
@ShadauxCat ShadauxCat requested a review from a team as a code owner November 22, 2022 21:11
@ShadauxCat ShadauxCat requested a review from a team as a code owner November 22, 2022 22:33
@@ -35,5 +43,39 @@ internal static void SetAutoAddNetworkObjectSetting(bool autoAddSetting)
{
EditorPrefs.SetBool(AutoAddNetworkObjectIfNoneExists, autoAddSetting);
}

public static NetcodeForGameObjectsSettings GetOrCreateSettings()
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment: It seems a little odd to me that this class is a mixture of editor prefs and persistent prefs.
Suggestion: If you want to stay consistent with Unity's asset serialization and also be able to take advantage of things like [FormerlySerializedAs] you can use these APIs to read/write scriptable object assets to the project folder:

UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget();
UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget();

Or alternatively, you can use ScriptableSingleton which does most of that for you automatically.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I see what you're saying... but this doesn't actually need to be persistent prefs, it can use EditorPrefs everywhere. The mismatch was the result of merging two different implementations of this together and not noticing that they were implemented in different ways.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think they actually need to be separate - the existing editorprefs are really editor preferences. how should this editor on this PC behave. The prefab prefs are project-level... you want that behavior consistent on everyone's PC who is working on the project.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, fair. I didn't realize EditorPrefs were shared between projects.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I had the same knee jerk reaction when looking at the original implementation, but there are advantages to having the NetworkPrefabs configuration serialized in reasonably "readable" json formatted text file. This could be easily converted over to a editor preferences via EditorPrefs.SetString, but I am not sure a netcode project's NetworkPrefab settings (specific to the game/product) qualifies as an editor preference.

Might be worth investigating the ScriptableObject path... just to determine if we are gaining or losing potential future functionality (either side of the fence).

The good news is that the json text can be easily saved to and read from whichever medium/location turns out to be the best place to store this information. 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Switched it over to ScriptableSingleton. That eased some of the logic and it's still a plain text format. :)

}
private static NetworkPrefabsList s_PrefabsList;

// Unfortunately this method is required by the asset pipeline to be static
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: This comment seems extraneous, it doesn't explain what's unfortunate about this pattern or why it shouldn't be static. As an engineer without context about this code, I think this actually detracts from it rather than improves it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That comment came from @JesseOlmer so I won't speak for him as to the intention behind it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Unfortunately this method is required by the asset pipeline to be static

This was mostly a note to myself during experimentation... It's unfortunate because static things are harder to mock, override, disable, etc. I didn't actually write ANY tests for any of this code so not sure how much this being static actually made things harder ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Had a feeling that was your thought process here... and yeah, it made testing harder... tests are having to set static variables and make sure they unset them at the end because if they don't, the actual editor settings get changed... it's yucky.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah...it is what it is:
https://docs.unity3d.com/2022.2/Documentation/ScriptReference/AssetPostprocessor.OnPostprocessAllAssets.html
One of those scenarios where creating an internal set of callbacks might help (?) with testing (and be valid due to it being static and all).

{
if (m_NetworkManager.NetworkConfig.Prefabs.NetworkPrefabsList == null)
{
EditorGUILayout.HelpBox("You have no prefab list selected. You will have to add your prefabs manually at runtime for netcode to work.", MessageType.Warning);
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: Should this be Info? It seems like having no prefabs is a valid use case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is a valid use case, but not an easy or intuitive one. People have to write their own code to manage the prefabs list on both sides. I felt warning was more appropriate to call out "this isn't going to work unless you're really putting effort into making it work"... but not opposed to changing it to info

- When performing a migration from the old prefab list to the new one, the path used to generate the new prefab list will be:
  - Next to the prefab containing the NetworkManager component if the NetworkManager is part of a prefab
  - Next to the scene the NetworkManager is in if it's not part of a prefab

- NetworkManager can now have multiple prefab lists attached to it

Also, I moved the code from NetworkAnimator's OnBeforeSerialize into the OnValidate event, as OnBeforeSerialize gets called in various circumstances that result in Unity throwing an error now that a NetworkAnimator can be a part of a NetworkPrefabsList.
# Conflicts:
#	com.unity.netcode.gameobjects/CHANGELOG.md
#	com.unity.netcode.gameobjects/Editor/Configuration/NetcodeSettingsProvider.cs
Copy link
Collaborator

@NoelStephensUnity NoelStephensUnity left a comment

Choose a reason for hiding this comment

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

Looks good Kitty! 👍

@ShadauxCat ShadauxCat merged commit b007fbd into develop Jan 11, 2023
@ShadauxCat ShadauxCat deleted the feat/prefab_qol branch January 11, 2023 19:26
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.

4 participants