using System; using System.Reflection; using Unity.Multiplayer.Center.Common.Analytics; using UnityEngine.UIElements; namespace Unity.Multiplayer.Center.Common { /// /// Onboarding section metadata to be picked up by the multiplayer center. /// This can only be used once per type. If you wish to make the same section appear in multiple categories/conditions, /// please create two types inheriting from the same base class. /// [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] public sealed class OnboardingSectionAttribute : Attribute { /// /// The UI category the section will fall into. /// public OnboardingSectionCategory Category { get; } /// /// The id of that section (defines uniqueness and whether priority should be used) /// public readonly string Id; /// /// Optional: condition to display the section. By default, if the type exists in the project, the section is shown. /// public DisplayCondition DisplayCondition { get; set; } /// /// Optional: dependency on a certain hosting model choice. /// public SelectedSolutionsData.HostingModel HostingModelDependency { get; set; } /// /// Optional: dependency on a certain netcode choice. /// public SelectedSolutionsData.NetcodeSolution NetcodeDependency { get; set; } /// /// Optional: priority in case several onboarding sections are defined for the same package/id. /// Use-case: new version of a package needs a different onboarding and overrides what we ship with the Multiplayer Center. /// public int Priority { get; set; } /// /// Optional: this is the order in which the sections will be displayed in the UI within the section. /// (the higher the Order value, the further down) /// public int Order { get; set; } /// /// Optional: the package identifier that this section is related to, e.g. "com.unity.transport". /// public string TargetPackageId { get; set; } /// /// Creates a new instance of the attribute. /// /// The section category. /// The identifier. public OnboardingSectionAttribute(OnboardingSectionCategory category, string id) { Category = category; Id = id; } } /// /// The UI category the section will fall into. /// public enum OnboardingSectionCategory { /// /// Comes at the top and should cover overarching topics for beginners /// Intro, /// /// Section about the fundamentals of gameplay synchronization implementation and debugging. /// This includes netcode and tools related to netcode, as well as alternative solutions. /// Netcode, /// /// Section gathering information about connecting players together, such as lobbies, voice chat, matchmaking /// and widgets. /// ConnectingPlayers, /// /// Section gathering information about deploying, running and optimizing a game server. /// ServerInfrastructure, /// /// Something else. /// Other, /// /// LiveOps sections which are meant to be used after some development happened on the game. /// LiveOps } /// /// A condition for a section to be displayed. /// public enum DisplayCondition { /// /// As long as the type exists in the project, the section is shown. /// Exception: a section with a higher priority is defined for the same id. /// None, /// /// A target package is defined in TargetPackageId and the package is installed /// If multiple types share the same id, the one with the highest priority is shown. /// PackageInstalled, /// /// Shown if no multiplayer package is installed (e.g. for the first time user that has not installed anything) /// Check SectionsFinder.k_TargetPackages to see which packages are checked /// NoPackageInstalled } /// /// Defines if a section depends on a certain hosting model. /// public enum InfrastructureDependency { /// /// No dependency, the section is shown if all other conditions are also met. /// None, /// /// Only available when the user has selected a client hosted infrastructure. /// ClientHosted, /// /// Only available when the user has selected a dedicated server infrastructure. /// DedicatedServer, /// /// Only available when the user has selected Cloud Code as their hosting model. /// CloudCode } /// /// A view for a single onboarding section. Classes implementing this interface should be marked with the /// . /// public interface IOnboardingSection { /// /// The visual element that will be added to the onboarding window. /// After Load is called, it should never be null. /// public VisualElement Root { get; } /// /// Makes the section ready to be displayed. /// May be called several times in a row. /// public void Load(); /// /// Frees anything that needs to be. /// public void Unload(); } /// /// For sections that depend on what the user selected in either the game specs or the solution selection. /// public interface ISectionDependingOnUserChoices : IOnboardingSection { /// /// Receives the answer data and handles it. This is called after Load. /// /// The latest value of answerData public void HandleAnswerData(AnswerData answerData) { } /// /// Receives the user selection data and handles it. This is called after Load. /// /// The latest value of the selection public void HandleUserSelectionData(SelectedSolutionsData selectedSolutionsData) { } /// /// Receives the preset data and handles it. This is called after Load. /// /// The latest preset value public void HandlePreset(Preset preset) { } } /// /// Implement this interface to have access to the Multiplayer Center analytics provider. /// Use the analytics provider to log events when the user interacts with the section. /// public interface ISectionWithAnalytics { /// /// This will be set before the load function is called. /// The implementor can then use the Analytics provider to send events to the analytics backend. /// public IOnboardingSectionAnalyticsProvider AnalyticsProvider { get; set; } } }