test
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using Unity.Multiplayer.Center.Common.Analytics;
|
||||
using UnityEngine.Analytics;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Analytics
|
||||
{
|
||||
/// <summary>
|
||||
/// Package representation in the analytics data.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal struct Package
|
||||
{
|
||||
/// <summary>
|
||||
/// The identifier of the package.
|
||||
/// </summary>
|
||||
public string PackageId;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the user has selected this package for installation.
|
||||
/// </summary>
|
||||
public bool SelectedForInstall;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the package was recommended.
|
||||
/// </summary>
|
||||
public bool IsRecommended;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the package was already installed when the installation attempt event occured
|
||||
/// </summary>
|
||||
public bool IsAlreadyInstalled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single Answer to the GameSpecs questionnaire.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal struct GameSpec
|
||||
{
|
||||
/// <summary>
|
||||
/// The identifier of the answered question (does not change).
|
||||
/// </summary>
|
||||
public string QuestionId;
|
||||
|
||||
/// <summary>
|
||||
/// The text of the question as displayed in the UI (may change with versions).
|
||||
/// </summary>
|
||||
public string QuestionText;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the question accepts multiple answers.
|
||||
/// </summary>
|
||||
public bool AcceptsMultipleAnswers;
|
||||
|
||||
/// <summary>
|
||||
/// The identifier of the answered question (does not change).
|
||||
/// </summary>
|
||||
public string AnswerId;
|
||||
|
||||
/// <summary>
|
||||
/// The text of the answer as displayed in the UI (may change with versions).
|
||||
/// </summary>
|
||||
public string AnswerText;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal struct RecommendationData : IAnalytic.IData
|
||||
{
|
||||
/// <summary>
|
||||
/// The preset selected by the user.
|
||||
/// </summary>
|
||||
public int Preset;
|
||||
|
||||
/// <summary>
|
||||
/// The preset selected by the user (game genre) as displayed in the UI.
|
||||
/// </summary>
|
||||
public string PresetName;
|
||||
|
||||
/// <summary>
|
||||
/// The version defined in the Questionnaire data.
|
||||
/// </summary>
|
||||
public string QuestionnaireVersion;
|
||||
|
||||
/// <summary>
|
||||
/// All the selected answers to the questions of the game specs questionnaire.
|
||||
/// </summary>
|
||||
public GameSpec[] GameSpecs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// What type of content the user Interacted with (buttons).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal struct InteractionData : IAnalytic.IData
|
||||
{
|
||||
/// <summary>
|
||||
/// The identifier of the section that contains the button.
|
||||
/// </summary>
|
||||
public string SectionId;
|
||||
|
||||
/// <summary>
|
||||
/// Whether it is a call to action or a link.
|
||||
/// </summary>
|
||||
public InteractionDataType Type;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the button in the UI.
|
||||
/// </summary>
|
||||
public string DisplayName;
|
||||
|
||||
/// <summary>
|
||||
/// The target package for which the section is helpful.
|
||||
/// </summary>
|
||||
public string TargetPackageId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Payload of the installation event.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal struct InstallData : IAnalytic.IData
|
||||
{
|
||||
/// <summary>
|
||||
/// The preset selected by the user.
|
||||
/// </summary>
|
||||
public int Preset;
|
||||
|
||||
/// <summary>
|
||||
/// The preset selected by the user (game genre) as displayed in the UI.
|
||||
/// </summary>
|
||||
public string PresetName;
|
||||
|
||||
/// <summary>
|
||||
/// The version defined in the Questionnaire data.
|
||||
/// </summary>
|
||||
public string QuestionnaireVersion;
|
||||
|
||||
/// <summary>
|
||||
/// All the selected answers to the questions of the game specs questionnaire.
|
||||
/// </summary>
|
||||
public GameSpec[] GamesSpecs;
|
||||
|
||||
/// <summary>
|
||||
/// The packages that were in the recommendation tab of the multiplayer center
|
||||
/// </summary>
|
||||
public Package[] Packages;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4cee1dc929764056ac40ece91efef712
|
||||
timeCreated: 1714481696
|
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Unity.Multiplayer.Center.Common;
|
||||
using Unity.Multiplayer.Center.Questionnaire;
|
||||
using Unity.Multiplayer.Center.Recommendations;
|
||||
using Unity.Multiplayer.Center.Window.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Analytics
|
||||
{
|
||||
internal static class AnalyticsUtils
|
||||
{
|
||||
// hard-coded to avoid recomputing every time / resizing arrays
|
||||
public const int NumNetcodePackage = 2;
|
||||
public const int NumHostingPackages = 1;
|
||||
|
||||
/// <summary>
|
||||
/// From the recommendation view data (which contains the packages that the user sees and the user's selection),
|
||||
/// create the list of packages that will be sent to the analytics backend.
|
||||
/// </summary>
|
||||
/// <param name="data">The recommendation view data as shown in the recommendation tab</param>
|
||||
/// <param name="solutionToPackageData">The packages views</param>
|
||||
/// <returns>The list of packages to be sent along with the installation event.</returns>
|
||||
public static Package[] GetPackagesWithAnalyticsFormat(RecommendationViewData data, SolutionsToRecommendedPackageViewData solutionToPackageData)
|
||||
{
|
||||
var selectedNetcode = RecommendationUtils.GetSelectedNetcode(data);
|
||||
var selectedHostingModel = RecommendationUtils.GetSelectedHostingModel(data);
|
||||
var packages = solutionToPackageData.GetPackagesForSelection(selectedNetcode.Solution, selectedHostingModel.Solution);
|
||||
var packageCount = NumNetcodePackage + NumHostingPackages + packages.Length;
|
||||
|
||||
var result = new Package[packageCount];
|
||||
var resultIndex = 0;
|
||||
|
||||
AddSolutionPackages(data.NetcodeOptions, result, ref resultIndex);
|
||||
AddSolutionPackages(data.ServerArchitectureOptions, result, ref resultIndex);
|
||||
AddRecommendedPackages(packages, result, ref resultIndex);
|
||||
|
||||
Debug.Assert(resultIndex == packageCount, $"Expected {packageCount} packages, got {resultIndex}");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches all the inspector name attributes of the Preset enum and returns the displayNames
|
||||
/// Important! It assumes the enum values are 0, ... , N
|
||||
/// </summary>
|
||||
/// <returns>The array of preset names. The index in the array is the integer value of the enum value</returns>
|
||||
public static string[] GetPresetFullNames()
|
||||
{
|
||||
var t = typeof(Preset);
|
||||
var values = Enum.GetValues(t);
|
||||
var array = new string[values.Length];
|
||||
foreach (var value in values)
|
||||
{
|
||||
var preset = (Preset) value;
|
||||
var index = (int)preset;
|
||||
var asString = value.ToString();
|
||||
var memInfo = t.GetMember(asString);
|
||||
var attribute = memInfo[0].GetCustomAttribute<InspectorNameAttribute>(false);
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
array[index] = attribute.displayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Could not fetch the full name of the preset value {asString}");
|
||||
array[index] = asString;
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts AnswerData to game specs, providing the knowledge of the display names.
|
||||
/// It assumes there is exactly one answer in the answer list at this point.
|
||||
/// </summary>
|
||||
/// <param name="data">The answer data of the user</param>
|
||||
/// <param name="answerIdToAnswerName">Mapping answer id to display name</param>
|
||||
/// <param name="questionIdToQuestionName">Mapping question id to display name</param>
|
||||
/// <returns>The list of game spec that will be consumed by the analytics backend</returns>
|
||||
public static GameSpec[] ToGameSpecs(AnswerData data,
|
||||
IReadOnlyDictionary<string, string> answerIdToAnswerName,
|
||||
IReadOnlyDictionary<string, string> questionIdToQuestionName)
|
||||
{
|
||||
var result = new GameSpec[data.Answers.Count];
|
||||
for (var i = 0; i < result.Length; ++i)
|
||||
{
|
||||
var answer = data.Answers[i];
|
||||
var answerId = answer.Answers[0]; // TODO: make sure that this always exists
|
||||
result[i] = new GameSpec()
|
||||
{
|
||||
QuestionId = answer.QuestionId,
|
||||
QuestionText = questionIdToQuestionName[answer.QuestionId],
|
||||
AcceptsMultipleAnswers = false, // TODO: add test that verifies this assumption
|
||||
AnswerId = answerId,
|
||||
AnswerText = answerIdToAnswerName[answerId]
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the mapping from question id to question display name
|
||||
/// </summary>
|
||||
/// <param name="questionnaireData">The questionnaire data</param>
|
||||
/// <returns>The mapping</returns>
|
||||
public static IReadOnlyDictionary<string, string> GetQuestionDisplayNames(QuestionnaireData questionnaireData)
|
||||
{
|
||||
var dictionary = new Dictionary<string, string>();
|
||||
foreach (var question in questionnaireData.Questions)
|
||||
{
|
||||
dictionary[question.Id] = question.Title;
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the mapping from answer id to answer display name
|
||||
/// </summary>
|
||||
/// <param name="questionnaireData">The questionnaire data</param>
|
||||
/// <returns>The mapping</returns>
|
||||
public static IReadOnlyDictionary<string, string> GetAnswerDisplayNames(QuestionnaireData questionnaireData)
|
||||
{
|
||||
var dictionary = new Dictionary<string, string>();
|
||||
foreach (var question in questionnaireData.Questions)
|
||||
{
|
||||
foreach (var answer in question.Choices)
|
||||
{
|
||||
dictionary[answer.Id] = answer.Title;
|
||||
}
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
static void AddSolutionPackages(RecommendedSolutionViewData[] options, Package[] result, ref int resultIndex)
|
||||
{
|
||||
foreach (var t in options)
|
||||
{
|
||||
if(string.IsNullOrEmpty(t.MainPackage?.PackageId))
|
||||
continue;
|
||||
|
||||
result[resultIndex] = new Package()
|
||||
{
|
||||
PackageId = t.MainPackage.PackageId,
|
||||
SelectedForInstall = t.Selected && t.RecommendationType != RecommendationType.Incompatible,
|
||||
IsRecommended = t.RecommendationType is RecommendationType.MainArchitectureChoice,
|
||||
IsAlreadyInstalled = t.MainPackage.IsInstalledAsProjectDependency
|
||||
};
|
||||
++resultIndex;
|
||||
}
|
||||
}
|
||||
|
||||
static void AddRecommendedPackages(RecommendedPackageViewData[] packageViewDatas, Package[] result, ref int resultIndex)
|
||||
{
|
||||
foreach (var viewData in packageViewDatas)
|
||||
{
|
||||
result[resultIndex] = new Package()
|
||||
{
|
||||
PackageId = viewData.PackageId,
|
||||
// TODO: remove hidden?
|
||||
SelectedForInstall = viewData.Selected && viewData.RecommendationType != RecommendationType.Incompatible,
|
||||
IsRecommended = viewData.RecommendationType.IsRecommendedPackage(),
|
||||
IsAlreadyInstalled = viewData.IsInstalledAsProjectDependency
|
||||
};
|
||||
++resultIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54407f5deee4439eb1885bee01956e9c
|
||||
timeCreated: 1714483618
|
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Analytics;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Analytics
|
||||
{
|
||||
/// <summary>
|
||||
/// Does the same as the MultiplayerCenterAnalytics, but logs the events to the console instead of sending them.
|
||||
/// It is useful to debug fast, without the EditorAnalytics Debugger package (but it does not replace it).
|
||||
/// </summary>
|
||||
internal class DebugAnalytics : MultiplayerCenterAnalytics
|
||||
{
|
||||
public DebugAnalytics(string questionnaireVersion, IReadOnlyDictionary<string, string> questionDisplayNames,
|
||||
IReadOnlyDictionary<string,string> answerDisplayNames)
|
||||
: base(questionnaireVersion, questionDisplayNames, answerDisplayNames) { }
|
||||
|
||||
protected override void SendAnalytic(IAnalytic analytic)
|
||||
{
|
||||
analytic.TryGatherData(out var data, out var _);
|
||||
switch (data)
|
||||
{
|
||||
case InstallData installData:
|
||||
Debug.Log($"Event: {analytic.GetType()} - Data: {ToString(installData)}");
|
||||
break;
|
||||
case RecommendationData recommendationData:
|
||||
Debug.Log($"Event: {analytic.GetType()} - Data: {ToString(recommendationData)}");
|
||||
break;
|
||||
case InteractionData interactionEventAnalytic:
|
||||
Debug.Log($"Event: {analytic.GetType()} - Data: {ToString(interactionEventAnalytic)}");
|
||||
break;
|
||||
default:
|
||||
Debug.Log($"Unknown event: {analytic.GetType()} - Data: {data}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static string ToString(GameSpec p) => $"GameSpec [{p.QuestionText} -> {p.AnswerText}]";
|
||||
|
||||
static string ToString(Package p) => $"Package [{p.PackageId} - Selected {p.SelectedForInstall} - Reco {p.IsRecommended} - Inst {p.IsAlreadyInstalled}]";
|
||||
|
||||
static string ToString(InstallData data)
|
||||
{
|
||||
var packageStrings = new List<string>(data.Packages.Length);
|
||||
foreach (var package in data.Packages)
|
||||
{
|
||||
packageStrings.Add(ToString(package));
|
||||
}
|
||||
return $"{data.PresetName} - Packages [{data.Packages.Length}] packages: \n{string.Join("\n", packageStrings)}";
|
||||
}
|
||||
|
||||
static string ToString(RecommendationData data)
|
||||
{
|
||||
var gameSpecStrings = new List<string>(data.GameSpecs.Length);
|
||||
foreach (var gameSpec in data.GameSpecs)
|
||||
{
|
||||
gameSpecStrings.Add(ToString(gameSpec));
|
||||
}
|
||||
return $"{data.PresetName} - GameSpecs [{data.GameSpecs.Length}] gamespecs: \n{string.Join("\n", gameSpecStrings)}";
|
||||
}
|
||||
|
||||
static string ToString(InteractionData data) => $"{data.SectionId}({data.TargetPackageId}) - {data.Type} - {data.DisplayName}";
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd20f32039084a12a8e48dffd4d58f48
|
||||
timeCreated: 1714651117
|
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Multiplayer.Center.Common;
|
||||
using Unity.Multiplayer.Center.Common.Analytics;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Analytics;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Analytics
|
||||
{
|
||||
/// <summary>
|
||||
/// The interface for the Multiplayer Center Analytics provider (only one functional implementation, but the
|
||||
/// interface is needed for testing purposes)
|
||||
/// </summary>
|
||||
internal interface IMultiplayerCenterAnalytics
|
||||
{
|
||||
void SendInstallationEvent(AnswerData data, Preset preset, Package[] packages);
|
||||
void SendRecommendationEvent(AnswerData data, Preset preset);
|
||||
void SendGettingStartedInteractionEvent(string targetPackageId, string sectionId, InteractionDataType type, string displayName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The concrete implementation of the multiplayer center analytics provider.
|
||||
/// It convert
|
||||
/// </summary>
|
||||
internal class MultiplayerCenterAnalytics : IMultiplayerCenterAnalytics
|
||||
{
|
||||
const string k_VendorKey = "unity.multiplayer.center";
|
||||
const string k_InstallationEventName = "multiplayer_center_onInstallClicked";
|
||||
const string k_RecommendationEventName = "multiplayer_center_onRecommendation";
|
||||
const string k_GetStartedInteractionEventName = "multiplayer_center_onGetStartedInteraction";
|
||||
|
||||
readonly string m_QuestionnaireVersion;
|
||||
readonly IReadOnlyDictionary<string, string> m_AnswerIdToAnswerName;
|
||||
readonly IReadOnlyDictionary<string, string> m_QuestionIdToQuestionName;
|
||||
readonly string[] m_PresetFullNames = AnalyticsUtils.GetPresetFullNames();
|
||||
string PresetName(Preset v) => m_PresetFullNames[(int)v];
|
||||
|
||||
GameSpec[] FillGameSpecs(AnswerData data)
|
||||
{
|
||||
return AnalyticsUtils.ToGameSpecs(data, m_AnswerIdToAnswerName, m_QuestionIdToQuestionName);
|
||||
}
|
||||
|
||||
protected virtual void SendAnalytic(IAnalytic analytic)
|
||||
{
|
||||
EditorAnalytics.SendAnalytic(analytic);
|
||||
}
|
||||
|
||||
public MultiplayerCenterAnalytics(string questionnaireVersion, IReadOnlyDictionary<string, string> questionDisplayNames,
|
||||
IReadOnlyDictionary<string, string> answerDisplayNames)
|
||||
{
|
||||
m_QuestionnaireVersion = questionnaireVersion;
|
||||
m_QuestionIdToQuestionName = questionDisplayNames;
|
||||
m_AnswerIdToAnswerName = answerDisplayNames;
|
||||
}
|
||||
|
||||
public void SendGettingStartedInteractionEvent(string targetPackageId, string sectionId, InteractionDataType type, string displayName)
|
||||
{
|
||||
var analytic = new GetStartedInteractionEventAnalytic(sectionId, type, displayName, targetPackageId);
|
||||
SendAnalytic(analytic);
|
||||
}
|
||||
|
||||
public void SendInstallationEvent(AnswerData data, Preset preset, Package[] packages)
|
||||
{
|
||||
var analytic = new InstallationEventAnalytic(new InstallData()
|
||||
{
|
||||
Preset = (int)preset,
|
||||
PresetName = PresetName(preset),
|
||||
QuestionnaireVersion = m_QuestionnaireVersion,
|
||||
GamesSpecs = FillGameSpecs(data),
|
||||
Packages = packages
|
||||
});
|
||||
SendAnalytic(analytic);
|
||||
}
|
||||
|
||||
public void SendRecommendationEvent(AnswerData data, Preset preset)
|
||||
{
|
||||
var analytic = new RecommendationEventAnalytic(new RecommendationData()
|
||||
{
|
||||
Preset = (int)preset,
|
||||
PresetName = PresetName(preset),
|
||||
QuestionnaireVersion = m_QuestionnaireVersion,
|
||||
GameSpecs = FillGameSpecs(data)
|
||||
});
|
||||
SendAnalytic(analytic);
|
||||
}
|
||||
|
||||
[AnalyticInfo(eventName: k_InstallationEventName, vendorKey: k_VendorKey)]
|
||||
private class InstallationEventAnalytic : IAnalytic
|
||||
{
|
||||
InstallData m_Data;
|
||||
|
||||
public InstallationEventAnalytic(InstallData data)
|
||||
{
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
|
||||
{
|
||||
data = m_Data;
|
||||
error = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[AnalyticInfo(eventName: k_RecommendationEventName, vendorKey: k_VendorKey)]
|
||||
private class RecommendationEventAnalytic : IAnalytic
|
||||
{
|
||||
RecommendationData m_Data;
|
||||
|
||||
public RecommendationEventAnalytic(RecommendationData data)
|
||||
{
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
|
||||
{
|
||||
data = m_Data;
|
||||
error = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[AnalyticInfo(eventName: k_GetStartedInteractionEventName, vendorKey: k_VendorKey)]
|
||||
private class GetStartedInteractionEventAnalytic : IAnalytic
|
||||
{
|
||||
InteractionData m_Data;
|
||||
|
||||
public GetStartedInteractionEventAnalytic(string sectionId, InteractionDataType type, string displayName, string targetPackageId)
|
||||
{
|
||||
m_Data = new InteractionData()
|
||||
{
|
||||
SectionId = sectionId,
|
||||
Type = type,
|
||||
DisplayName = displayName,
|
||||
TargetPackageId = targetPackageId
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
|
||||
{
|
||||
data = m_Data;
|
||||
error = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 185e678d90804a8a85ab38276eca86fb
|
||||
timeCreated: 1714382339
|
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using Unity.Multiplayer.Center.Questionnaire;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Analytics
|
||||
{
|
||||
internal static class MultiplayerCenterAnalyticsFactory
|
||||
{
|
||||
public static IMultiplayerCenterAnalytics Create()
|
||||
{
|
||||
var questionnaire = QuestionnaireObject.instance;
|
||||
var questionnaireVersion = questionnaire.Questionnaire.Version;
|
||||
var questionDisplayNames = AnalyticsUtils.GetQuestionDisplayNames(questionnaire.Questionnaire);
|
||||
var answerDisplayNames = AnalyticsUtils.GetAnswerDisplayNames(questionnaire.Questionnaire);
|
||||
|
||||
// Uncomment this line to use the DebugAnalytics class instead of the MultiplayerCenterAnalytics class
|
||||
// return new DebugAnalytics(questionnaireVersion, questionDisplayNames, answerDisplayNames);
|
||||
|
||||
return new MultiplayerCenterAnalytics(questionnaireVersion, questionDisplayNames, answerDisplayNames);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bce0b24c28e45d884acfcf49a3b8945
|
||||
timeCreated: 1714640827
|
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using Unity.Multiplayer.Center.Common.Analytics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Multiplayer.Center.Analytics
|
||||
{
|
||||
/// <summary>
|
||||
/// The concrete implementation of the IOnboardingSectionAnalyticsProvider interface.
|
||||
/// It shall be created by the GettingStarted tab with the knowledge of the target package and the section id
|
||||
/// provided by the attribute of the onboarding section, so that the section implementer does not have to worry
|
||||
/// about it.
|
||||
/// </summary>
|
||||
internal class OnboardingSectionAnalyticsProvider : IOnboardingSectionAnalyticsProvider
|
||||
{
|
||||
readonly IMultiplayerCenterAnalytics m_Analytics;
|
||||
readonly string m_TargetPackageId;
|
||||
readonly string m_SectionId;
|
||||
|
||||
public OnboardingSectionAnalyticsProvider(IMultiplayerCenterAnalytics analytics, string targetPackageId, string sectionId)
|
||||
{
|
||||
Debug.Assert(analytics != null);
|
||||
m_Analytics = analytics;
|
||||
m_TargetPackageId = targetPackageId;
|
||||
m_SectionId = sectionId;
|
||||
}
|
||||
|
||||
public void SendInteractionEvent(InteractionDataType type, string displayName)
|
||||
{
|
||||
m_Analytics.SendGettingStartedInteractionEvent(m_TargetPackageId, m_SectionId, type, displayName);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9faa4a7023c43c5805642250c703f48
|
||||
timeCreated: 1714637861
|
Reference in New Issue
Block a user