initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 50add270142df411fac7beb21e6ede90
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,86 @@
using System;
using Unity.Services.Core.Editor;
using UnityEditor;
using UnityEngine;
namespace Unity.Cloud.Collaborate.EditorGameService
{
static class EditorGameServiceAnalyticsSender
{
static class AnalyticsComponent
{
public const string ProjectSettings = "Project Settings";
public const string TopMenu = "Top Menu";
}
static class AnalyticsAction
{
public const string Configure = "Configure";
public const string OpenChanges = "Open Changes Panel";
public const string OpenHistory = "Open History Panel";
public const string CloudStorageDashboard = "Open Cloud Storage Web Dashboard";
public const string LearnMore = "Learn More";
}
const int k_Version = 1;
const string k_EventName = "editorgameserviceeditor";
static IEditorGameServiceIdentifier s_Identifier;
static IEditorGameServiceIdentifier Identifier
{
get
{
if (s_Identifier == null)
{
s_Identifier = EditorGameServiceRegistry.Instance.GetEditorGameService<CloudCollabServiceIdentifier>().Identifier;
}
return s_Identifier;
}
}
internal static void SendProjectSettingsOpenChangesEvent()
{
SendEvent(AnalyticsComponent.ProjectSettings, AnalyticsAction.OpenChanges);
}
internal static void SendProjectSettingsOpenHistoryEvent()
{
SendEvent(AnalyticsComponent.ProjectSettings, AnalyticsAction.OpenHistory);
}
internal static void SendProjectSettingsCloudStorageDashboardEvent()
{
SendEvent(AnalyticsComponent.ProjectSettings, AnalyticsAction.CloudStorageDashboard);
}
internal static void SendProjectSettingsLearnMoreEvent()
{
SendEvent(AnalyticsComponent.ProjectSettings, AnalyticsAction.LearnMore);
}
internal static void SendTopMenuConfigureEvent()
{
SendEvent(AnalyticsComponent.TopMenu, AnalyticsAction.Configure);
}
static void SendEvent(string component, string action)
{
EditorAnalytics.SendEventWithLimit(k_EventName, new EditorGameServiceEvent
{
action = action,
component = component,
package = Identifier.GetKey()
}, k_Version);
}
/// <remarks>Lowercase is used here for compatibility with analytics.</remarks>
[Serializable]
public struct EditorGameServiceEvent
{
public string action;
public string component;
public string package;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99f46086bc2624dbd8746ee5a4460cad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,66 @@
using System;
using System.Reflection;
using Unity.Services.Core.Editor;
using UnityEngine;
using Collab = UnityEditor.Collaboration.Collab;
namespace Unity.Cloud.Collaborate.EditorGameService
{
class CloudCollabEnabler : EditorGameServiceFlagEnabler
{
const string k_ProjectSettingsSettingName = "Collab";
bool m_IsEnabled = GetEnabledStatusWithReflection();
protected override string FlagName { get; } = "collab";
protected override void EnableLocalSettings()
{
m_IsEnabled = true;
Collab.instance.SetCollabEnabledForCurrentProject(true);
SetEnabledStatusWithReflection(true);
}
protected override void DisableLocalSettings()
{
m_IsEnabled = false;
Collab.instance.SetCollabEnabledForCurrentProject(false);
SetEnabledStatusWithReflection(false);
}
public override bool IsEnabled()
{
return m_IsEnabled;
}
static bool GetEnabledStatusWithReflection()
{
var playerSettingsType = Type.GetType("UnityEditor.PlayerSettings,UnityEditor.dll");
var isEnabled = false;
if (playerSettingsType != null)
{
var getCloudServiceEnabledMethod = playerSettingsType.GetMethod("GetCloudServiceEnabled", BindingFlags.Static | BindingFlags.NonPublic);
if (getCloudServiceEnabledMethod != null)
{
var enabledStateResult = getCloudServiceEnabledMethod.Invoke(null, new object[] {k_ProjectSettingsSettingName});
isEnabled = Convert.ToBoolean(enabledStateResult);
}
}
return isEnabled;
}
static void SetEnabledStatusWithReflection(bool value)
{
var playerSettingsType = Type.GetType("UnityEditor.PlayerSettings,UnityEditor.dll");
if (playerSettingsType != null)
{
var setCloudServiceEnabledMethod = playerSettingsType.GetMethod("SetCloudServiceEnabled", BindingFlags.Static | BindingFlags.NonPublic);
if (setCloudServiceEnabledMethod != null)
{
setCloudServiceEnabledMethod.Invoke(null, new object[] {k_ProjectSettingsSettingName, value});
}
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 499c53660f3b74fc0a5bc2b1c56121ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,51 @@
using Unity.Cloud.Collaborate.EditorGameService;
using Unity.Cloud.Collaborate.Models.Providers;
using Unity.Services.Core.Editor;
using UnityEditor;
using UnityEngine;
using Collab = UnityEditor.Collaboration.Collab;
using CollabInfo = UnityEditor.Collaboration.CollabInfo;
namespace Unity.Cloud.Collaborate.EditorGameService
{
class CloudCollabService : IEditorGameService
{
public CloudCollabService()
{
Collab.instance.StateChanged += OnCollabStateChanged;
}
~CloudCollabService()
{
Collab.instance.StateChanged -= OnCollabStateChanged;
}
public string Name { get; } = "Collaborate";
public IEditorGameServiceIdentifier Identifier { get; } = new CloudCollabServiceIdentifier();
public bool RequiresCoppaCompliance { get; } = false;
public bool HasDashboard { get; } = true;
public string GetFormattedDashboardUrl()
{
#if ENABLE_EDITOR_GAME_SERVICES
return $"https://developer.cloud.unity3d.com/collab/orgs/{CloudProjectSettings.organizationKey}/projects/{CloudProjectSettings.projectId}/assets/";
#else
return string.Empty;
#endif
}
public IEditorGameServiceEnabler Enabler { get; } = new CloudCollabEnabler();
void OnCollabStateChanged(CollabInfo collabInfo)
{
if (Collab.instance.IsCollabEnabledForCurrentProject() && !Enabler.IsEnabled())
{
Enabler.Enable();
}
else if (!Collab.instance.IsCollabEnabledForCurrentProject() && Enabler.IsEnabled())
{
Enabler.Disable();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 960021b62cced40368fb95baa077fc2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,16 @@
using Unity.Services.Core.Editor;
namespace Unity.Cloud.Collaborate.EditorGameService
{
/// <summary>
/// Identifier for the Cloud Collab Service
/// </summary>
public struct CloudCollabServiceIdentifier : IEditorGameServiceIdentifier
{
/// <summary>
/// Get the Identifier key for Cloud Collab
/// </summary>
/// <returns>The Identifier key</returns>
public string GetKey() => "Collab";
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: da9ace77b96f45fc9a84632f551d0aba
timeCreated: 1618488831

View file

@ -0,0 +1,39 @@
using System.Collections.Generic;
using Unity.Cloud.Collaborate.EditorGameService.SettingsProviderVisuals;
using Unity.Services.Core.Editor;
using UnityEditor;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.EditorGameService
{
class CloudCollabSettingsProvider : EditorGameServiceSettingsProvider
{
const string k_CollaborateName = "Version Control";
CloudCollabVisuals m_Visuals;
CloudCollabSettingsProvider(IEnumerable<string> keywords = null)
: base(GenerateProjectSettingsPath(k_CollaborateName), SettingsScope.Project, keywords) { }
protected override IEditorGameService EditorGameService { get; } = EditorGameServiceRegistry.Instance.GetEditorGameService<CloudCollabServiceIdentifier>();
protected override string Title { get; } = k_CollaborateName;
protected override string Description { get; } = "Create together seamlessly";
protected override VisualElement GenerateServiceDetailUI()
{
m_Visuals = new CloudCollabVisuals();
m_Visuals.Init(EditorGameService);
return m_Visuals.GetVisuals();
}
[SettingsProvider]
static SettingsProvider CreateSettingsProvider()
{
#if ENABLE_EDITOR_GAME_SERVICES
return new CloudCollabSettingsProvider();
#else
return null;
#endif
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e166244551374dbeb6e41e53ad61cfde
timeCreated: 1618401736

View file

@ -0,0 +1,19 @@
#if ENABLE_EDITOR_GAME_SERVICES
using UnityEditor;
namespace Unity.Cloud.Collaborate.EditorGameService
{
static class CloudCollabTopMenu
{
const string k_ServiceMenuRoot = "Services/Version Control/";
const int k_ConfigureMenuPriority = 100;
[MenuItem(k_ServiceMenuRoot + "Configure", priority = k_ConfigureMenuPriority)]
static void ShowProjectSettings()
{
EditorGameServiceAnalyticsSender.SendTopMenuConfigureEvent();
SettingsService.OpenProjectSettings("Project/Services/Version Control");
}
}
}
#endif

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d129b9605eb84f75bda7b7c433713464
timeCreated: 1618317965

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1bdd3385e91345fe98a0bbac2006104f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,76 @@
using Unity.Services.Core.Editor;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.EditorGameService.SettingsProviderVisuals
{
class CloudCollabVisuals : IVisuals
{
IVisuals m_CurrentVisuals;
/// <remarks>A standard if else is used here instead of the ternary conditional operator to prevent an implicit conversion error in the 2020 editor.</remarks>
public void Init(IEditorGameService editorGameService)
{
if (editorGameService.Enabler.IsEnabled())
{
m_CurrentVisuals = new EnabledVisuals();
}
else
{
m_CurrentVisuals = new DisabledVisuals();
}
}
public VisualElement GetVisuals()
{
var output = m_CurrentVisuals.GetVisuals();
SetupStyleSheets(output);
return output;
}
static void SetupStyleSheets(VisualElement parentElement)
{
if (parentElement == null)
{
return;
}
parentElement.AddToClassList("collab");
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(Uss.Path.Common);
if (styleSheet != null)
{
parentElement.styleSheets.Add(styleSheet);
}
}
}
static class Uxml
{
public static class Path
{
public const string Disabled = "Packages/com.unity.collab-proxy/Editor/Collaborate/EditorGameService/SettingsProviderVisuals/UXML/CollabProjectSettingsDisabled.uxml";
public const string Enabled = "Packages/com.unity.collab-proxy/Editor/Collaborate/EditorGameService/SettingsProviderVisuals/UXML/CollabProjectSettingsEnabled.uxml";
}
public static class Node
{
public const string PublishSection = "CollabPublishSection";
public const string HistorySection = "CollabHistorySection";
public const string OpenHistoryLink = "OpenHistory";
public const string OpenChangesLink = "OpenChanges";
public const string GoToStorageLink = "GoToWebDashboard";
public const string LearnMoreLink = "LearnMore";
}
}
static class Uss
{
public static class Path
{
public const string Common = "Packages/com.unity.collab-proxy/Editor/Collaborate/EditorGameService/SettingsProviderVisuals/USS/ServicesProjectSettingsCommon.uss";
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e0a05dd61b1d491fb711fdbb2884cbae
timeCreated: 1618412815

View file

@ -0,0 +1,22 @@
using UnityEditor;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.EditorGameService.SettingsProviderVisuals
{
class DisabledVisuals : IVisuals
{
public VisualElement GetVisuals()
{
VisualElement containerUI = null;
var containerAsset = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(Uxml.Path.Disabled);
if (containerAsset != null)
{
containerUI = containerAsset.CloneTree().contentContainer;
LearnMoreVisualHelper.SetupLearnMore(containerUI);
}
return containerUI;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f6fdc5bdb8ac4ea099a6b3194d7099da
timeCreated: 1618493000

View file

@ -0,0 +1,96 @@
using Unity.Cloud.Collaborate.UserInterface;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.EditorGameService.SettingsProviderVisuals
{
class EnabledVisuals : IVisuals
{
#if ENABLE_EDITOR_GAME_SERVICES
const string k_StorageUrl = "https://dashboard.unity3d.com/organizations/{0}/projects/{1}/collaborate/usage";
#else
const string k_StorageUrl = "https://core.cloud.unity3d.com/orgs/{0}/projects/{1}/usage";
#endif
public VisualElement GetVisuals()
{
VisualElement containerUI = null;
var containerAsset = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(Uxml.Path.Enabled);
if (containerAsset != null)
{
containerUI = containerAsset.CloneTree().contentContainer;
SetupHistorySection(containerUI);
SetupPublishSection(containerUI);
SetupCloudStorage(containerUI);
LearnMoreVisualHelper.SetupLearnMore(containerUI);
}
return containerUI;
}
void SetupPublishSection(VisualElement containerUI)
{
var publishSection = containerUI.Q(Uxml.Node.PublishSection);
if (publishSection != null)
{
publishSection.style.display = DisplayStyle.Flex;
}
var openChangesButton = containerUI.Q<Button>(Uxml.Node.OpenChangesLink);
if (openChangesButton != null)
{
openChangesButton.clicked += ShowChangesWindow;
}
}
static void ShowChangesWindow()
{
EditorGameServiceAnalyticsSender.SendProjectSettingsOpenChangesEvent();
CollaborateWindow.Init(CollaborateWindow.FocusTarget.Changes);
}
void SetupHistorySection(VisualElement containerUI)
{
var historySection = containerUI.Q(Uxml.Node.HistorySection);
if (historySection != null)
{
historySection.style.display = DisplayStyle.Flex;
}
var openHistoryButton = containerUI.Q<Button>(Uxml.Node.OpenHistoryLink);
if (openHistoryButton != null)
{
openHistoryButton.clicked += ShowHistoryWindow;
}
}
static void ShowHistoryWindow()
{
EditorGameServiceAnalyticsSender.SendProjectSettingsOpenHistoryEvent();
CollaborateWindow.Init(CollaborateWindow.FocusTarget.History);
}
static void SetupCloudStorage(VisualElement containerUI)
{
var goToStorageButton = containerUI.Q(Uxml.Node.GoToStorageLink);
if (goToStorageButton != null)
{
var clickable = new Clickable(GoToCloudStorageDashboard);
goToStorageButton.AddManipulator(clickable);
}
}
static void GoToCloudStorageDashboard()
{
EditorGameServiceAnalyticsSender.SendProjectSettingsCloudStorageDashboardEvent();
#if ENABLE_EDITOR_GAME_SERVICES
Application.OpenURL(string.Format(k_StorageUrl, CloudProjectSettings.organizationKey, CloudProjectSettings.projectId));
#else
Application.OpenURL(string.Format(k_StorageUrl, CloudProjectSettings.organizationId, CloudProjectSettings.projectId));
#endif
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 42eb5d9546d84a8495c7d6cf6934b392
timeCreated: 1618492994

View file

@ -0,0 +1,9 @@
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.EditorGameService.SettingsProviderVisuals
{
interface IVisuals
{
VisualElement GetVisuals();
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1c95bf231e194e44b636d25d28145278
timeCreated: 1618493066

View file

@ -0,0 +1,26 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.EditorGameService.SettingsProviderVisuals
{
static class LearnMoreVisualHelper
{
static readonly string k_LearnMoreAboutTeamsUrl = "https://unity3d.com/teams";
public static void SetupLearnMore(VisualElement containerUI)
{
var learnMoreButton = containerUI.Q(Uxml.Node.LearnMoreLink);
if (learnMoreButton != null)
{
var clickable = new Clickable(GoToLearnMore);
learnMoreButton.AddManipulator(clickable);
}
}
static void GoToLearnMore()
{
EditorGameServiceAnalyticsSender.SendProjectSettingsLearnMoreEvent();
Application.OpenURL(k_LearnMoreAboutTeamsUrl);
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e3d3d11296f94862bd5c8d5a542f4248
timeCreated: 1623172425

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3a9723526cb024130b47fd301eee9e7d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,61 @@
.project-settings-service-specific-container {
flex-grow:1;
}
.project-settings-header-container {
flex-direction:row;
}
.project-settings-title-container,
.project-settings-section-container {
padding:4px 4px 4px 8px;
flex-direction:column;
flex-wrap:wrap;
}
.project-settings-title{
font-size:16px;
-unity-font-style:bold;
}
.label-container {
flex-direction:row;
align-items:flex-start;
padding-top: 5px;
padding-bottom: 5px;
}
.service-link-button,
.field-block.link-button {
border-width:0px;
-unity-text-align:middle-left;
align-self:flex-start;
padding-left:1px;
padding-right:2px;
margin-left:1px;
margin-right:1px;
background-color:rgba(0, 0, 0, 0);
cursor:link;
flex-grow:0;
}
.field-block.link-button {
border-width:0px;
-unity-text-align:middle-left;
align-self:flex-end;
padding-left:1px;
padding-right:2px;
margin-left:1px;
margin-right:1px;
background-color:rgba(0, 0, 0, 0);
cursor:link;
flex-grow:0;
}
.collab .service-icon {
background-image:resource("Builtin Skins/Shared/Images/ServicesWindow-ServiceIcon-Collab.png");
}
.link-container {
align-self: flex-end;
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4324e2e7d76c7448096a033e3c2c6b0f
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2435ae6e6a1574586846f6ee42da70b4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,13 @@
<UXML xmlns="UnityEngine.UIElements">
<VisualElement class="project-settings-title-container">
<Label text="Quickly and easily access your project from anywhere. Sync and share with the entire team." class="label-container"/>
</VisualElement>
<VisualElement class="project-settings-title-container">
<Label text="Ask the organization owner or manager for access to Unity Teams to use the Collaborate service." class="label-container"/>
</VisualElement>
<VisualElement class="separator" />
<VisualElement name="LearnMore" class="field-block link-container">
<TextElement text="Learn More" class="link-button"/>
<VisualElement class="external-link-icon"/>
</VisualElement>
</UXML>

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 4e24487a7d7704dd89983851b8b09a7f
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

View file

@ -0,0 +1,31 @@
<UXML xmlns="UnityEngine.UIElements">
<VisualElement name="CollabPublishSection">
<VisualElement class="project-settings-title-container">
<Label text="Publish" class="project-settings-title"/>
<Label text="Review and share file changes." class="label-container"/>
<Button class="service-link-button" name="OpenChanges" text="Open the changes panel"/>
</VisualElement>
<VisualElement class="separator" />
</VisualElement>
<VisualElement name="CollabHistorySection">
<VisualElement class="project-settings-title-container">
<Label text="History" class="project-settings-title"/>
<Label text="See all published changes, and optionally restore to an earlier publish." class="label-container"/>
<Button class="service-link-button" name="OpenHistory" text="Open the history panel"/>
</VisualElement>
<VisualElement class="separator" />
</VisualElement>
<VisualElement class="project-settings-title-container">
<Label text="Cloud Storage" class="project-settings-title"/>
<Label text="Manage cloud storage on the Unity Dashboard, including storage limits and current usage." class="label-container"/>
<VisualElement name="GoToWebDashboard" class="field-block link-container">
<TextElement text="Go to the web dashboard" class="link-button"/>
<VisualElement class="external-link-icon"/>
</VisualElement>
</VisualElement>
<VisualElement class="separator" />
<VisualElement name="LearnMore" class="field-block link-container">
<TextElement text="Learn More" class="link-button"/>
<VisualElement class="external-link-icon"/>
</VisualElement>
</UXML>

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c1d9e7d786a3841e7858003b3515bbac
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}