test
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores what the user answered in the GameSpecs questionnaire. The Preset is not included here.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AnswerData
|
||||
{
|
||||
/// <summary>
|
||||
/// The list of answers the user has given so far.
|
||||
/// </summary>
|
||||
public List<AnsweredQuestion> Answers = new();
|
||||
|
||||
/// <summary>
|
||||
/// Makes a deep copy of the object.
|
||||
/// </summary>
|
||||
/// <returns>The clone</returns>
|
||||
public AnswerData Clone()
|
||||
{
|
||||
return JsonUtility.FromJson(JsonUtility.ToJson(this), typeof(AnswerData)) as AnswerData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Answer to a single game spec question.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AnsweredQuestion
|
||||
{
|
||||
/// <summary>
|
||||
/// The question identifier as defined in the game spec questionnaire.
|
||||
/// </summary>
|
||||
public string QuestionId;
|
||||
|
||||
/// <summary>
|
||||
/// The answers selected by the user (most often, it contains only one element).
|
||||
/// </summary>
|
||||
public List<string> Answers;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89b6d933e4994d0980f6b48dc2b8779c
|
||||
timeCreated: 1695397313
|
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Unity.Multiplayer.Center.Common.Analytics;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class OnboardingSectionAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The UI category the section will fall into.
|
||||
/// </summary>
|
||||
public OnboardingSectionCategory Category { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The id of that section (defines uniqueness and whether priority should be used)
|
||||
/// </summary>
|
||||
public readonly string Id;
|
||||
|
||||
/// <summary>
|
||||
/// Optional: condition to display the section. By default, if the type exists in the project, the section is shown.
|
||||
/// </summary>
|
||||
public DisplayCondition DisplayCondition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: dependency on a certain hosting model choice.
|
||||
/// </summary>
|
||||
public SelectedSolutionsData.HostingModel HostingModelDependency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: dependency on a certain netcode choice.
|
||||
/// </summary>
|
||||
public SelectedSolutionsData.NetcodeSolution NetcodeDependency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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)
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: the package identifier that this section is related to, e.g. "com.unity.transport".
|
||||
/// </summary>
|
||||
public string TargetPackageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the attribute.
|
||||
/// </summary>
|
||||
/// <param name="category">The section category.</param>
|
||||
/// <param name="id">The identifier.</param>
|
||||
public OnboardingSectionAttribute(OnboardingSectionCategory category, string id)
|
||||
{
|
||||
Category = category;
|
||||
Id = id;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The UI category the section will fall into.
|
||||
/// </summary>
|
||||
public enum OnboardingSectionCategory
|
||||
{
|
||||
/// <summary>
|
||||
/// Comes at the top and should cover overarching topics for beginners
|
||||
/// </summary>
|
||||
Intro,
|
||||
|
||||
/// <summary>
|
||||
/// Section about the fundamentals of gameplay synchronization implementation and debugging.
|
||||
/// This includes netcode and tools related to netcode, as well as alternative solutions.
|
||||
/// </summary>
|
||||
Netcode,
|
||||
|
||||
/// <summary>
|
||||
/// Section gathering information about connecting players together, such as lobbies, voice chat, matchmaking
|
||||
/// and widgets.
|
||||
/// </summary>
|
||||
ConnectingPlayers,
|
||||
|
||||
/// <summary>
|
||||
/// Section gathering information about deploying, running and optimizing a game server.
|
||||
/// </summary>
|
||||
ServerInfrastructure,
|
||||
|
||||
/// <summary>
|
||||
/// Something else.
|
||||
/// </summary>
|
||||
Other,
|
||||
|
||||
/// <summary>
|
||||
/// LiveOps sections which are meant to be used after some development happened on the game.
|
||||
/// </summary>
|
||||
LiveOps
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A condition for a section to be displayed.
|
||||
/// </summary>
|
||||
public enum DisplayCondition
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
PackageInstalled,
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
NoPackageInstalled
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines if a section depends on a certain hosting model.
|
||||
/// </summary>
|
||||
public enum InfrastructureDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// No dependency, the section is shown if all other conditions are also met.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Only available when the user has selected a client hosted infrastructure.
|
||||
/// </summary>
|
||||
ClientHosted,
|
||||
|
||||
/// <summary>
|
||||
/// Only available when the user has selected a dedicated server infrastructure.
|
||||
/// </summary>
|
||||
DedicatedServer,
|
||||
|
||||
/// <summary>
|
||||
/// Only available when the user has selected Cloud Code as their hosting model.
|
||||
/// </summary>
|
||||
CloudCode
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A view for a single onboarding section. Classes implementing this interface should be marked with the
|
||||
/// <see cref="OnboardingSectionAttribute"/>.
|
||||
/// </summary>
|
||||
public interface IOnboardingSection
|
||||
{
|
||||
/// <summary>
|
||||
/// The visual element that will be added to the onboarding window.
|
||||
/// After Load is called, it should never be null.
|
||||
/// </summary>
|
||||
public VisualElement Root { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Makes the section ready to be displayed.
|
||||
/// May be called several times in a row.
|
||||
/// </summary>
|
||||
public void Load();
|
||||
|
||||
/// <summary>
|
||||
/// Frees anything that needs to be.
|
||||
/// </summary>
|
||||
public void Unload();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For sections that depend on what the user selected in either the game specs or the solution selection.
|
||||
/// </summary>
|
||||
public interface ISectionDependingOnUserChoices : IOnboardingSection
|
||||
{
|
||||
/// <summary>
|
||||
/// Receives the answer data and handles it. This is called after Load.
|
||||
/// </summary>
|
||||
/// <param name="answerData">The latest value of answerData</param>
|
||||
public void HandleAnswerData(AnswerData answerData) { }
|
||||
|
||||
/// <summary>
|
||||
/// Receives the user selection data and handles it. This is called after Load.
|
||||
/// </summary>
|
||||
/// <param name="selectedSolutionsData">The latest value of the selection</param>
|
||||
public void HandleUserSelectionData(SelectedSolutionsData selectedSolutionsData) { }
|
||||
|
||||
/// <summary>
|
||||
/// Receives the preset data and handles it. This is called after Load.
|
||||
/// </summary>
|
||||
/// <param name="preset">The latest preset value</param>
|
||||
public void HandlePreset(Preset preset) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public interface ISectionWithAnalytics
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public IOnboardingSectionAnalyticsProvider AnalyticsProvider { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1bd8e2f47a6c4478ab8f0ade7687e79b
|
||||
timeCreated: 1700730627
|
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Common.Analytics
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of interaction that the user has with a button in the getting started tab.
|
||||
/// </summary>
|
||||
public enum InteractionDataType
|
||||
{
|
||||
/// <summary>
|
||||
/// For a button that does something in the editor, e.g. a button that opens a window or imports a sample.
|
||||
/// </summary>
|
||||
CallToAction = 0,
|
||||
|
||||
/// <summary>
|
||||
/// For a button that opens a URL in the browser (e.g. a documentation link).
|
||||
/// </summary>
|
||||
Link = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For the object that provides the analytics functionality to send interaction events on some Onboarding section
|
||||
/// in the getting started tab.
|
||||
/// </summary>
|
||||
public interface IOnboardingSectionAnalyticsProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Send event for a button interaction in the getting started tab.
|
||||
/// </summary>
|
||||
/// <param name="type"> Whether it is a call to action or a link</param>
|
||||
/// <param name="displayName"> The name of the button in the UI</param>
|
||||
void SendInteractionEvent(InteractionDataType type, string displayName);
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 833328f3bcf144cc94f92e286e86b427
|
||||
timeCreated: 1714381093
|
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Game genres that can be selected. Each one is associated with pre-selected answers for the questionnaire,
|
||||
/// except for `None`.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[InspectorOrder()] // will sort the values alphabetically in the inspector
|
||||
public enum Preset
|
||||
{
|
||||
/// <summary>
|
||||
/// Start from scratch, no preset.
|
||||
/// </summary>
|
||||
[InspectorName("-")]
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Adventure genre.
|
||||
/// </summary>
|
||||
[InspectorName("Adventure")]
|
||||
Adventure,
|
||||
|
||||
/// <summary>
|
||||
/// Shooter, Battle Royale, Battle Arena genre.
|
||||
/// </summary>
|
||||
[InspectorName("Shooter, Battle Royale, Battle Arena")]
|
||||
Shooter,
|
||||
|
||||
/// <summary>
|
||||
/// Racing genre.
|
||||
/// </summary>
|
||||
[InspectorName("Racing")]
|
||||
Racing,
|
||||
|
||||
/// <summary>
|
||||
/// Card Battle, Turn-based, Tabletop genre.
|
||||
/// </summary>
|
||||
[InspectorName("Card Battle, Turn-based, Tabletop")]
|
||||
TurnBased,
|
||||
|
||||
/// <summary>
|
||||
/// Simulation genre.
|
||||
/// </summary>
|
||||
[InspectorName("Simulation")]
|
||||
Simulation,
|
||||
|
||||
/// <summary>
|
||||
/// Strategy genre.
|
||||
/// </summary>
|
||||
[InspectorName("Strategy")]
|
||||
Strategy,
|
||||
|
||||
/// <summary>
|
||||
/// Sports genre.
|
||||
/// </summary>
|
||||
[InspectorName("Sports")]
|
||||
Sports,
|
||||
|
||||
/// <summary>
|
||||
/// Role-Playing, MMO genre.
|
||||
/// </summary>
|
||||
[InspectorName("Role-Playing, MMO")]
|
||||
RolePlaying,
|
||||
|
||||
/// <summary>
|
||||
/// Async, Idle, Hyper Casual, Puzzle genre.
|
||||
/// </summary>
|
||||
[InspectorName("Async, Idle, Hyper Casual, Puzzle")]
|
||||
Async,
|
||||
|
||||
/// <summary>
|
||||
/// Fighting genre.
|
||||
/// </summary>
|
||||
[InspectorName("Fighting")]
|
||||
Fighting,
|
||||
|
||||
/// <summary>
|
||||
/// Arcade, Platformer, Sandbox genre.
|
||||
/// </summary>
|
||||
[InspectorName("Arcade, Platformer, Sandbox")]
|
||||
Sandbox
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a9ab22e4e004c7db707338bccb538b9
|
||||
timeCreated: 1713777478
|
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores the selection of the main solutions from the recommendation tab.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SelectedSolutionsData
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible hosting models that the user can select.
|
||||
/// </summary>
|
||||
public enum HostingModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Empty (no selection)
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Client hosted model
|
||||
/// </summary>
|
||||
ClientHosted,
|
||||
|
||||
/// <summary>
|
||||
/// Dedicated server model
|
||||
/// </summary>
|
||||
DedicatedServer,
|
||||
|
||||
/// <summary>
|
||||
/// Most of the logic will be in the cloud.
|
||||
/// </summary>
|
||||
CloudCode,
|
||||
|
||||
/// <summary>
|
||||
/// Distributed Authority (the authority over the game logic is spread across multiple clients).
|
||||
/// </summary>
|
||||
DistributedAuthority,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The possible netcode solutions that the user can select.
|
||||
/// </summary>
|
||||
public enum NetcodeSolution
|
||||
{
|
||||
/// <summary>
|
||||
/// Empty (no selection)
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Netcode for GameObjects
|
||||
/// </summary>
|
||||
NGO,
|
||||
|
||||
/// <summary>
|
||||
/// Netcode for Entities
|
||||
/// </summary>
|
||||
N4E,
|
||||
|
||||
/// <summary>
|
||||
/// Custom netcode solution, potentially based on Unity Transport
|
||||
/// </summary>
|
||||
CustomNetcode,
|
||||
|
||||
/// <summary>
|
||||
/// No netcode (no real time synchronization needed)
|
||||
/// </summary>
|
||||
NoNetcode
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The hosting model selected by the user.
|
||||
/// </summary>
|
||||
public HostingModel SelectedHostingModel;
|
||||
|
||||
/// <summary>
|
||||
/// The netcode solution selected by the user.
|
||||
/// </summary>
|
||||
public NetcodeSolution SelectedNetcodeSolution;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec737041edec4a5b93f7953a6ffe9f06
|
||||
timeCreated: 1711027351
|
@@ -0,0 +1,69 @@
|
||||
namespace Unity.Multiplayer.Center.Onboarding
|
||||
{
|
||||
/// <summary>
|
||||
/// Common style classes that can be accessed from the quickstart sections
|
||||
/// </summary>
|
||||
public static class StyleConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// Green checkmark to reflect a success
|
||||
/// Applicable to <c>VisualElement</c> to show a success state
|
||||
/// </summary>
|
||||
public const string CheckmarkClass = "checkmark-icon";
|
||||
|
||||
/// <summary>
|
||||
/// The style that enables to have foldable sections in the getting started tab.
|
||||
/// Applicable to <c>Foldout</c>
|
||||
/// </summary>
|
||||
public const string OnBoardingSectionFoldout = "section-foldout";
|
||||
|
||||
/// <summary>
|
||||
/// Default style for an onboarding section
|
||||
/// Apply to the top level element (Root) in Onboarding section
|
||||
/// Applicable to <c>VisualElement</c>
|
||||
/// </summary>
|
||||
public const string OnBoardingSectionClass = "onboarding-section";
|
||||
|
||||
/// <summary>
|
||||
/// Default style for the title of an onboarding section
|
||||
/// Apply to the title visual element (<c>Label</c>) in Onboarding section
|
||||
/// </summary>
|
||||
public const string OnboardingSectionTitle = "onboarding-section-title";
|
||||
|
||||
/// <summary>
|
||||
/// Button inside the header of a onboarding-section
|
||||
/// Applicable to <c>Button</c>
|
||||
/// </summary>
|
||||
public const string OnBoardingSectionMainButton = "onboarding-section-mainbutton";
|
||||
|
||||
/// <summary>
|
||||
/// Button inside the header of a onboarding-section
|
||||
/// Applicable to <c>Label</c>
|
||||
/// </summary>
|
||||
public const string OnBoardingShortDescription = "onboarding-section-short-description";
|
||||
|
||||
/// <summary>
|
||||
/// A button that opens a documentation page
|
||||
/// Applicable to <c>Button</c>
|
||||
/// </summary>
|
||||
public const string DocButtonClass = "doc-button";
|
||||
|
||||
/// <summary>
|
||||
/// An element that will take all the remaining space in a flex container
|
||||
/// Applicable to <c>VisualElement</c>
|
||||
/// </summary>
|
||||
public const string FlexSpaceClass = "flex-spacer";
|
||||
|
||||
/// <summary>
|
||||
/// Horizontal flex container
|
||||
/// Applicable to <c>VisualElement</c>
|
||||
/// </summary>
|
||||
public const string HorizontalContainerClass = "horizontal-container";
|
||||
|
||||
/// <summary>
|
||||
/// Darker background color in dark mode, lighter in light mode
|
||||
/// Applicable to <c>VisualElement</c>
|
||||
/// </summary>
|
||||
public const string HighlightBackgroundClass = "highlight-background-color";
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50d5ff9fe4ab4477b7ea648da183e9d1
|
||||
timeCreated: 1701879951
|
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "Unity.Multiplayer.Center.Common"
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84abd2ab34a74600a33a3bb9d72859fe
|
||||
timeCreated: 1700734156
|
Reference in New Issue
Block a user