196 lines
8.5 KiB
C#
196 lines
8.5 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using Unity.Multiplayer.Center.Questionnaire;
|
||
using Unity.Multiplayer.Center.Recommendations;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using UnityEngine.UIElements;
|
||
|
||
namespace Unity.Multiplayer.Center.Window.UI.RecommendationView
|
||
{
|
||
internal class RecommendationView
|
||
{
|
||
RecommendationViewData m_Recommendation;
|
||
|
||
SolutionsToRecommendedPackageViewData m_AllPackages;
|
||
public SolutionsToRecommendedPackageViewData AllPackages
|
||
=> m_AllPackages ??= RecommenderSystem.GetSolutionsToRecommendedPackageViewData();
|
||
|
||
public RecommendationViewData CurrentRecommendation => m_Recommendation;
|
||
|
||
|
||
public ScrollView Root { get; } = new();
|
||
|
||
NetcodeSelectionView m_NetcodeSelectionView = new();
|
||
HostingModelSelectionView m_HostingModelSelectionView = new();
|
||
RecommendedPackagesSection m_RecommendedPackagesSection = new();
|
||
OtherSection m_OtherSection = new();
|
||
VisualElement m_NoRecommendationsView;
|
||
|
||
VisualElement m_Content;
|
||
|
||
PreReleaseHandling m_PreReleaseHandling;
|
||
|
||
//Todo: for now check on the view but actually should be on the model
|
||
public Action OnPackageSelectionChanged;
|
||
|
||
public RecommendationView()
|
||
{
|
||
Root.AddToClassList("recommendation-view");
|
||
Root.horizontalScrollerVisibility = ScrollerVisibility.Hidden;
|
||
var title = new VisualElement();
|
||
title.Add(new Label {text = "Multiplayer Solutions and Recommendations"});
|
||
title.AddToClassList("recommendation-view-headline");
|
||
Root.Add(title);
|
||
|
||
Root.Add(m_Content = new VisualElement() {name = "recommendation-view-section-container"});
|
||
var topContainer = new VisualElement();
|
||
topContainer.name = "main-sections-container";
|
||
topContainer.Add(m_NetcodeSelectionView);
|
||
topContainer.Add(m_HostingModelSelectionView);
|
||
m_Content.Add(topContainer);
|
||
|
||
m_NetcodeSelectionView.OnUserChangedSolution += OnUserChangedSolution;
|
||
m_HostingModelSelectionView.OnUserChangedSolution += OnUserChangedSolution;
|
||
|
||
m_RecommendedPackagesSection.OnPackageSelectionChanged += RaisePackageSelectionChanged;
|
||
m_HostingModelSelectionView.OnPackageSelectionChanged += RaisePackageSelectionChanged;
|
||
m_NetcodeSelectionView.OnPackageSelectionChanged += RaisePackageSelectionChanged;
|
||
|
||
m_Content.Add(m_RecommendedPackagesSection);
|
||
m_Content.Add(m_OtherSection);
|
||
m_NoRecommendationsView = EmptyView();
|
||
|
||
Root.Add(m_NoRecommendationsView);
|
||
|
||
UpdateView(false);
|
||
}
|
||
|
||
public void UpdateRecommendation(RecommendationViewData recommendation, PreReleaseHandling preReleaseHandling)
|
||
{
|
||
m_Recommendation = recommendation;
|
||
m_PreReleaseHandling = preReleaseHandling;
|
||
UpdateView(false);
|
||
}
|
||
|
||
public void Clear()
|
||
{
|
||
m_NetcodeSelectionView.OnUserChangedSolution -= OnUserChangedSolution;
|
||
m_HostingModelSelectionView.OnUserChangedSolution -= OnUserChangedSolution;
|
||
m_RecommendedPackagesSection.OnPackageSelectionChanged -= RaisePackageSelectionChanged;
|
||
m_HostingModelSelectionView.OnPackageSelectionChanged -= RaisePackageSelectionChanged;
|
||
m_NetcodeSelectionView.OnPackageSelectionChanged -= RaisePackageSelectionChanged;
|
||
|
||
Root.Clear();
|
||
}
|
||
|
||
void RaisePackageSelectionChanged()
|
||
{
|
||
OnPackageSelectionChanged?.Invoke();
|
||
}
|
||
|
||
void OnUserChangedSolution()
|
||
{
|
||
UpdateView(true);
|
||
}
|
||
|
||
void UpdateView(bool recordUndo)
|
||
{
|
||
var hideRecommendation = m_Recommendation == null;
|
||
SetRecommendationHidden(hideRecommendation);
|
||
|
||
if (hideRecommendation)
|
||
{
|
||
OnPackageSelectionChanged?.Invoke();
|
||
return;
|
||
}
|
||
|
||
RecommenderSystem.AdaptRecommendationToNetcodeSelection(m_Recommendation);
|
||
m_PreReleaseHandling.PatchPackages(m_Recommendation);
|
||
|
||
var selectedNetcode = RecommendationUtils.GetSelectedNetcode(m_Recommendation);
|
||
var selectedHostingModel = RecommendationUtils.GetSelectedHostingModel(m_Recommendation);
|
||
var selection = new SolutionSelection(selectedNetcode.Solution, selectedHostingModel.Solution);
|
||
var allPackages = AllPackages.GetPackagesForSelection(selection);
|
||
|
||
// Debug(selection, allPackages);
|
||
m_NetcodeSelectionView.UpdateData(m_Recommendation.NetcodeOptions,
|
||
RecommendationUtils.FilterByType(allPackages, RecommendationType.NetcodeFeatured));
|
||
m_HostingModelSelectionView.UpdateData(m_Recommendation.ServerArchitectureOptions,
|
||
RecommendationUtils.FilterByType(allPackages, RecommendationType.HostingFeatured));
|
||
m_RecommendedPackagesSection.UpdatePackageData(
|
||
RecommendationUtils.FilterByType(allPackages, RecommendationType.OptionalStandard));
|
||
|
||
var otherPackages = RecommendationUtils.FilterByType(allPackages, RecommendationType.NotRecommended);
|
||
otherPackages.AddRange(RecommendationUtils.FilterByType(allPackages, RecommendationType.Incompatible));
|
||
m_OtherSection.UpdatePackageData(otherPackages);
|
||
OnPackageSelectionChanged?.Invoke();
|
||
|
||
UpdateUserInputObject(m_Recommendation, recordUndo);
|
||
}
|
||
|
||
static void Debug(SolutionSelection selection, List<RecommendedPackageViewData> allPackages)
|
||
{
|
||
UnityEngine.Debug.Log("/////////////////////////////////////// " + selection);
|
||
foreach (var pack in allPackages)
|
||
{
|
||
UnityEngine.Debug.Log(pack.Name + " " + pack.RecommendationType);
|
||
}
|
||
}
|
||
|
||
void SetRecommendationHidden(bool hideRecommendation)
|
||
{
|
||
var flex = new StyleEnum<DisplayStyle>(DisplayStyle.Flex);
|
||
var none = new StyleEnum<DisplayStyle>(DisplayStyle.None);
|
||
m_Content.style.display = hideRecommendation ? none : flex;
|
||
m_NoRecommendationsView.style.display = hideRecommendation ? flex : none;
|
||
|
||
// To show the EmptyView in the center, we have to change the behavior of the scroll view container.
|
||
Root.Q<VisualElement>("unity-content-container").style.flexGrow = hideRecommendation ? 1 : 0;
|
||
}
|
||
|
||
static void UpdateUserInputObject(RecommendationViewData recommendation, bool recordUndo)
|
||
{
|
||
if(recordUndo)
|
||
Undo.RecordObject(UserChoicesObject.instance,"Selection Change");
|
||
|
||
var currentSelectedNetcode = UserChoicesObject.instance.SelectedSolutions.SelectedNetcodeSolution;
|
||
foreach (var netcodeOption in recommendation.NetcodeOptions)
|
||
{
|
||
if (netcodeOption.Selected)
|
||
currentSelectedNetcode = Logic.ConvertNetcodeSolution(netcodeOption);
|
||
}
|
||
|
||
var selectedHostingModel = UserChoicesObject.instance.SelectedSolutions.SelectedHostingModel;
|
||
foreach (var serverArchitectureOption in recommendation.ServerArchitectureOptions)
|
||
{
|
||
if (serverArchitectureOption.Selected)
|
||
selectedHostingModel = Logic.ConvertInfrastructure(serverArchitectureOption);
|
||
}
|
||
|
||
UserChoicesObject.instance.SetUserSelection(selectedHostingModel, currentSelectedNetcode);
|
||
UserChoicesObject.instance.Save();
|
||
}
|
||
|
||
static VisualElement EmptyView()
|
||
{
|
||
var emptyView = new VisualElement();
|
||
emptyView.name = "empty-view";
|
||
|
||
var emptyViewContentContainer = new VisualElement();
|
||
emptyViewContentContainer.name = "empty-view-content";
|
||
var emptyViewMessage = new Label
|
||
{
|
||
text = "You will see your recommendations and be able to explore Unity’s multiplayer offerings here once you specify the genre of your game, and the number of players per session.",
|
||
name = "empty-view-message"
|
||
};
|
||
var emptyViewIcon = new VisualElement();
|
||
emptyViewIcon.name = "empty-view-icon";
|
||
emptyViewContentContainer.Add(emptyViewIcon);
|
||
emptyViewContentContainer.Add(emptyViewMessage);
|
||
emptyView.Add(emptyViewContentContainer);
|
||
return emptyView;
|
||
}
|
||
}
|
||
}
|