diff --git a/Editor/IncrementalBuildPipeline/BeeBuildProgramCommon.Data/BeeBuildProgramCommon.Data.gen.csproj b/Editor/IncrementalBuildPipeline/BeeBuildProgramCommon.Data/BeeBuildProgramCommon.Data.gen.csproj
index 92891ca1c2..2a20527d3f 100644
--- a/Editor/IncrementalBuildPipeline/BeeBuildProgramCommon.Data/BeeBuildProgramCommon.Data.gen.csproj
+++ b/Editor/IncrementalBuildPipeline/BeeBuildProgramCommon.Data/BeeBuildProgramCommon.Data.gen.csproj
@@ -7,7 +7,7 @@
false
false
latest
- 1071
+ 1701
diff --git a/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/Data.cs b/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/Data.cs
index 4996a3ff91..35507fb75a 100644
--- a/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/Data.cs
+++ b/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/Data.cs
@@ -47,6 +47,7 @@ public class PlayerBuildConfig
public string ApplicationIdentifier;
public string Architecture;
public ScriptingBackend ScriptingBackend;
+ public bool NoGUID;
public bool InstallIntoBuildsFolder;
public bool GenerateIdeProject;
public bool Development;
@@ -60,6 +61,7 @@ public class PlayerBuildConfig
public class BuiltFilesOutput
{
public string[] Files = new string[0];
+ public string BootConfigArtifact;
}
public class LinkerConfig
@@ -97,6 +99,8 @@ public class Il2CppConfig
public string SysRootPath;
public string ToolChainPath;
public string RelativeDataPath;
+ public bool GenerateUsymFile;
+ public string UsymtoolPath;
}
public class Services
diff --git a/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/PlayerBuildProgramLibrary.Data.gen.csproj b/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/PlayerBuildProgramLibrary.Data.gen.csproj
index 324c757f81..ca26ba36b7 100644
--- a/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/PlayerBuildProgramLibrary.Data.gen.csproj
+++ b/Editor/IncrementalBuildPipeline/PlayerBuildProgramLibrary.Data/PlayerBuildProgramLibrary.Data.gen.csproj
@@ -7,7 +7,7 @@
false
false
latest
- 1071
+ 1701
PlayerBuildProgramLibrary.Data
diff --git a/Editor/IncrementalBuildPipeline/ScriptCompilationBuildProgram.Data/ScriptCompilationBuildProgram.Data.gen.csproj b/Editor/IncrementalBuildPipeline/ScriptCompilationBuildProgram.Data/ScriptCompilationBuildProgram.Data.gen.csproj
index 7edeeb057f..010f8a8c43 100644
--- a/Editor/IncrementalBuildPipeline/ScriptCompilationBuildProgram.Data/ScriptCompilationBuildProgram.Data.gen.csproj
+++ b/Editor/IncrementalBuildPipeline/ScriptCompilationBuildProgram.Data/ScriptCompilationBuildProgram.Data.gen.csproj
@@ -7,7 +7,7 @@
false
false
latest
- 1071
+ 1701
diff --git a/Editor/Mono/ActiveEditorTracker.bindings.cs b/Editor/Mono/ActiveEditorTracker.bindings.cs
index 631817a74f..e903abcfbd 100644
--- a/Editor/Mono/ActiveEditorTracker.bindings.cs
+++ b/Editor/Mono/ActiveEditorTracker.bindings.cs
@@ -59,7 +59,7 @@ public override int GetHashCode()
public Editor[] activeEditors { get { return (Editor[])Internal_GetActiveEditors(this); } }
[FreeFunction]
- internal static extern void Internal_GetActiveEditorsNonAlloc(ActiveEditorTracker self, Editor[] editors);
+ internal static extern void Internal_GetActiveEditorsNonAlloc(ActiveEditorTracker self, [Unmarshalled] Editor[] editors);
// List version
internal void GetObjectsLockedByThisTracker(List lockedObjects)
diff --git a/Editor/Mono/Animation/AnimationUtility.bindings.cs b/Editor/Mono/Animation/AnimationUtility.bindings.cs
index 668fd87bb7..f26cf83f7e 100644
--- a/Editor/Mono/Animation/AnimationUtility.bindings.cs
+++ b/Editor/Mono/Animation/AnimationUtility.bindings.cs
@@ -134,7 +134,7 @@ public static AnimationClip[] GetAnimationClips(GameObject gameObject)
extern internal static AnimationClip[] GetAnimationClipsInAnimationPlayer([NotNull] GameObject gameObject);
// Sets the array of AnimationClips to be referenced in the Animation component
- extern public static void SetAnimationClips([NotNull] Animation animation, AnimationClip[] clips);
+ extern public static void SetAnimationClips([NotNull] Animation animation, [Unmarshalled] AnimationClip[] clips);
public static EditorCurveBinding[] GetAnimatableBindings(GameObject targetObject, GameObject root)
{
@@ -201,7 +201,7 @@ public static Type PropertyModificationToEditorCurveBinding(PropertyModification
extern public static ObjectReferenceKeyframe[] GetObjectReferenceCurve([NotNull] AnimationClip clip, EditorCurveBinding binding);
- public static void SetObjectReferenceCurve(AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes)
+ public static void SetObjectReferenceCurve(AnimationClip clip, EditorCurveBinding binding, [Unmarshalled]ObjectReferenceKeyframe[] keyframes)
{
Internal_SetObjectReferenceCurve(clip, binding, keyframes, true);
Internal_InvokeOnCurveWasModified(clip, binding, keyframes != null ? CurveModifiedType.CurveModified : CurveModifiedType.CurveDeleted);
@@ -232,7 +232,7 @@ internal static void SetObjectReferenceCurveNoSync(AnimationClip clip, EditorCur
}
[NativeThrows]
- extern private static void Internal_SetObjectReferenceCurve([NotNull] AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes, bool updateMuscleClip);
+ extern private static void Internal_SetObjectReferenceCurve([NotNull] AnimationClip clip, EditorCurveBinding binding, [Unmarshalled] ObjectReferenceKeyframe[] keyframes, bool updateMuscleClip);
extern public static AnimationCurve GetEditorCurve([NotNull] AnimationClip clip, EditorCurveBinding binding);
@@ -270,6 +270,8 @@ internal static void SetEditorCurveNoSync(AnimationClip clip, EditorCurveBinding
[NativeThrows]
extern private static void Internal_SetEditorCurve([NotNull] AnimationClip clip, EditorCurveBinding binding, AnimationCurve curve, bool syncEditorCurves);
+ extern internal static bool IsDiscreteIntBinding(EditorCurveBinding binding);
+
extern internal static void SyncEditorCurves([NotNull] AnimationClip clip);
private static void Internal_InvokeOnCurveWasModified(AnimationClip clip, EditorCurveBinding binding, CurveModifiedType type)
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowControl.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowControl.cs
index da5fb4aa72..bbb79c3da4 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowControl.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowControl.cs
@@ -920,7 +920,7 @@ private List GetKeys(PropertyModification[] modificatio
int keyIndex = curve.GetKeyframeIndex(state.time);
if (keyIndex >= 0)
{
- keys.Add(curve.m_Keyframes[keyIndex]);
+ keys.Add(curve.keyframes[keyIndex]);
}
}
}
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowCurve.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowCurve.cs
index 966a51b453..c7d0cf939e 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowCurve.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowCurve.cs
@@ -15,7 +15,7 @@ internal class AnimationWindowCurve : IComparable, IEquata
{
public const float timeEpsilon = 0.00001f;
- public List m_Keyframes;
+ private List m_Keyframes;
private EditorCurveBinding m_Binding;
private int m_BindingHashCode;
@@ -46,6 +46,8 @@ internal class AnimationWindowCurve : IComparable, IEquata
public bool animationIsEditable { get { return m_SelectionBinding != null ? m_SelectionBinding.animationIsEditable : true; } }
public int selectionID { get { return m_SelectionBinding != null ? m_SelectionBinding.id : 0; } }
+ public IReadOnlyList keyframes => m_Keyframes;
+
private object defaultValue
{
get
@@ -190,17 +192,10 @@ public AnimationCurve ToAnimationCurve()
AnimationCurve animationCurve = new AnimationCurve();
List keys = new List();
- float lastFrameTime = float.MinValue;
-
for (int i = 0; i < length; i++)
{
- // Make sure we don't get two keyframes in an exactly the same time. We just ignore those.
- if (Mathf.Abs(m_Keyframes[i].time - lastFrameTime) > AnimationWindowCurve.timeEpsilon)
- {
- Keyframe newKeyframe = m_Keyframes[i].ToKeyframe();
- keys.Add(newKeyframe);
- lastFrameTime = m_Keyframes[i].time;
- }
+ Keyframe newKeyframe = m_Keyframes[i].ToKeyframe();
+ keys.Add(newKeyframe);
}
animationCurve.keys = keys.ToArray();
@@ -212,17 +207,10 @@ public ObjectReferenceKeyframe[] ToObjectCurve()
int length = m_Keyframes.Count;
List keys = new List();
- float lastFrameTime = float.MinValue;
-
for (int i = 0; i < length; i++)
{
- // Make sure we don't get two keyframes in an exactly the same time. We just ignore those.
- if (Mathf.Abs(m_Keyframes[i].time - lastFrameTime) > AnimationWindowCurve.timeEpsilon)
- {
- ObjectReferenceKeyframe newKeyframe = m_Keyframes[i].ToObjectReferenceKeyframe();
- lastFrameTime = newKeyframe.time;
- keys.Add(newKeyframe);
- }
+ ObjectReferenceKeyframe newKeyframe = m_Keyframes[i].ToObjectReferenceKeyframe();
+ keys.Add(newKeyframe);
}
keys.Sort((a, b) => a.time.CompareTo(b.time));
@@ -301,6 +289,11 @@ public void RemoveKeyframe(AnimationKeyTime time)
}
}
+ public void RemoveKeyframe(AnimationWindowKeyframe keyframe)
+ {
+ m_Keyframes.Remove(keyframe);
+ }
+
public bool HasKeyframe(AnimationKeyTime time)
{
return GetKeyframeIndex(time) != -1;
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowEvent.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowEvent.cs
index 613cfa17ff..4b3cce3606 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowEvent.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowEvent.cs
@@ -13,10 +13,46 @@
namespace UnityEditor
{
- internal struct AnimationWindowEventMethod
+ ///
+ /// Holds the context for AnimationEvent editing.
+ ///
+ class AnimationEventEditorState
{
- public string name;
- public Type parameterType;
+ static bool s_ShowOverloadedFunctionsDetails = true;
+ static bool s_ShowDuplicatedFunctionsDetails = true;
+
+ bool m_ShowOverloadedFunctionsDetails = s_ShowOverloadedFunctionsDetails;
+ bool m_ShowDuplicatedFunctionsDetails = s_ShowDuplicatedFunctionsDetails;
+
+ ///
+ /// Used to track whether or not to show extra details about duplicated function names found in among the potential supported functions
+ ///
+ public bool ShowOverloadedFunctionsDetails
+ {
+ get => m_ShowOverloadedFunctionsDetails;
+ set
+ {
+ m_ShowOverloadedFunctionsDetails = s_ShowOverloadedFunctionsDetails = value;
+ }
+ }
+
+ ///
+ /// Used to track whether or not to show extra details about overloaded function names found in among the potential supported functions
+ ///
+ public bool ShowDuplicatedFunctionsDetails
+ {
+ get => m_ShowDuplicatedFunctionsDetails;
+ set
+ {
+ m_ShowDuplicatedFunctionsDetails = s_ShowDuplicatedFunctionsDetails = value;
+ }
+ }
+
+ public AnimationEventEditorState()
+ {
+ m_ShowOverloadedFunctionsDetails = s_ShowOverloadedFunctionsDetails;
+ m_ShowDuplicatedFunctionsDetails = s_ShowDuplicatedFunctionsDetails;
+ }
}
internal class AnimationWindowEvent : ScriptableObject
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowEventInspector.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowEventInspector.cs
index 126b3879a1..54ad4942ad 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowEventInspector.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowEventInspector.cs
@@ -5,7 +5,6 @@
using System.Linq;
using UnityEngine;
using UnityEditor;
-using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System;
@@ -17,15 +16,18 @@ namespace UnityEditor
[CanEditMultipleObjects]
internal class AnimationWindowEventInspector : Editor
{
+ public static GUIContent s_OverloadWarning = EditorGUIUtility.TrTextContent("Some functions were overloaded in MonoBehaviour components and may not work as intended if used with Animation Events!");
+ public static GUIContent s_DuplicatesWarning = EditorGUIUtility.TrTextContent("Some functions have the same name across several Monobehaviour components and may not work as intended if used with Animation Events!");
+
const string kNotSupportedPostFix = " (Function Not Supported)";
const string kNoneSelected = "(No Function Selected)";
- public static GUIContent s_OverloadWarning = EditorGUIUtility.TrTextContent("Some functions were overloaded in MonoBehaviour components and may not work as intended if used with Animation Events!");
+ AnimationEventEditorState m_State = new();
public override void OnInspectorGUI()
{
var awes = targets.Select(o => o as AnimationWindowEvent).ToArray();
- OnEditAnimationEvents(awes);
+ OnEditAnimationEvents(awes, m_State);
}
protected override void OnHeaderGUI()
@@ -34,12 +36,17 @@ protected override void OnHeaderGUI()
DrawHeaderGUI(this, targetTitle);
}
- public static void OnEditAnimationEvent(AnimationWindowEvent awe)
+ public static void OnEditAnimationEvent(AnimationWindowEvent awe, AnimationEventEditorState state)
{
- OnEditAnimationEvents(new AnimationWindowEvent[] {awe});
+ OnEditAnimationEvents(new AnimationWindowEvent[] {awe}, state);
}
- public static void OnEditAnimationEvents(AnimationWindowEvent[] awEvents)
+ // These are used so we don't alloc new lists on every call
+ static List supportedMethods;
+ static List overloads;
+ static List duplicates;
+
+ public static void OnEditAnimationEvents(AnimationWindowEvent[] awEvents, AnimationEventEditorState state)
{
AnimationWindowEventData data = GetData(awEvents);
if (data.events == null || data.selectedEvents == null || data.selectedEvents.Length == 0)
@@ -53,64 +60,60 @@ public static void OnEditAnimationEvents(AnimationWindowEvent[] awEvents)
if (data.root != null)
{
- List methods = new List();
- HashSet overloads = new HashSet();
- CollectSupportedMethods(data.root, methods, overloads);
+ supportedMethods ??= new List();
+ overloads ??= new List();
+ duplicates ??= new List();
- var methodsFormatted = new List(methods.Count);
+ supportedMethods.Clear();
+ overloads.Clear();
+ duplicates.Clear();
+ CollectSupportedMethods(data.root, supportedMethods, overloads, duplicates);
- for (int i = 0; i < methods.Count; ++i)
- {
- AnimationWindowEventMethod method = methods[i];
+ int selected = supportedMethods.FindIndex(method => method.Name == firstEvent.functionName);
- string postFix = " ( )";
- if (method.parameterType != null)
- {
- if (method.parameterType == typeof(float))
- postFix = " ( float )";
- else if (method.parameterType == typeof(int))
- postFix = " ( int )";
- else
- postFix = string.Format(" ( {0} )", method.parameterType.Name);
- }
+ // A non-empty array used for rendering the contents of the popup
+ // It is of size 1 greater than the list of supported methods to account for the "None" option
+ string[] methodsFormatted = new string[supportedMethods.Count + 1];
- methodsFormatted.Add(method.name + postFix);
+ for (int i = 0; i < supportedMethods.Count; ++i)
+ {
+ AnimationMethodMap methodMap = supportedMethods[i];
+ string menuPath = methodMap.methodMenuPath;
+ methodsFormatted[i] = menuPath;
}
- int notSupportedIndex = methods.Count;
- int selected = methods.FindIndex(method => method.name == firstEvent.functionName);
+ // Add a final option to set the function to no selected function
+ int notSupportedIndex = supportedMethods.Count;
if (selected == -1)
{
- selected = methods.Count;
-
- AnimationWindowEventMethod newMethod = new AnimationWindowEventMethod();
- newMethod.name = firstEvent.functionName;
- newMethod.parameterType = null;
-
- methods.Add(newMethod);
+ selected = notSupportedIndex;
+ // Display that the current function is not supported if applicable
if (string.IsNullOrEmpty(firstEvent.functionName))
- methodsFormatted.Add(kNoneSelected);
+ methodsFormatted[notSupportedIndex] = kNoneSelected;
else
- methodsFormatted.Add(firstEvent.functionName + kNotSupportedPostFix);
+ methodsFormatted[notSupportedIndex] = firstEvent.functionName + kNotSupportedPostFix;
+
+ var emptyMethodMap = new AnimationMethodMap();
+ supportedMethods.Add(emptyMethodMap);
}
EditorGUIUtility.labelWidth = 130;
EditorGUI.showMixedValue = !singleFunctionName;
int wasSelected = singleFunctionName ? selected : -1;
- selected = EditorGUILayout.Popup("Function: ", selected, methodsFormatted.ToArray());
+ selected = EditorGUILayout.Popup("Function: ", selected, methodsFormatted);
if (wasSelected != selected && selected != -1 && selected != notSupportedIndex)
{
foreach (var evt in data.selectedEvents)
{
- evt.functionName = methods[selected].name;
+ evt.functionName = supportedMethods[selected].Name;
evt.stringParameter = string.Empty;
}
}
EditorGUI.showMixedValue = false;
- var selectedParameter = methods[selected].parameterType;
+ var selectedParameter = supportedMethods[selected].parameterType;
if (singleFunctionName && selectedParameter != null)
{
@@ -127,6 +130,24 @@ public static void OnEditAnimationEvents(AnimationWindowEvent[] awEvents)
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox(s_OverloadWarning.text, MessageType.Warning, true);
+ state.ShowOverloadedFunctionsDetails = EditorGUILayout.Foldout(state.ShowOverloadedFunctionsDetails, "Show Details");
+ if (state.ShowOverloadedFunctionsDetails)
+ {
+ string overloadedFunctionDetails = "Overloaded Functions: \n" + GetFormattedMethodsText(overloads);
+ GUILayout.Label(overloadedFunctionDetails, EditorStyles.helpBox);
+ }
+ }
+
+ if (duplicates.Count > 0)
+ {
+ EditorGUILayout.Space();
+ EditorGUILayout.HelpBox(s_DuplicatesWarning.text, MessageType.Warning, true);
+ state.ShowDuplicatedFunctionsDetails = EditorGUILayout.Foldout(state.ShowDuplicatedFunctionsDetails, "Show Details");
+ if (state.ShowDuplicatedFunctionsDetails)
+ {
+ string duplicatedFunctionDetails = "Duplicated Functions: \n" + GetFormattedMethodsText(duplicates);
+ GUILayout.Label(duplicatedFunctionDetails, EditorStyles.helpBox);
+ }
}
}
else
@@ -152,7 +173,7 @@ public static void OnEditAnimationEvents(AnimationWindowEvent[] awEvents)
using (new EditorGUI.DisabledScope(true))
{
AnimationEvent dummyEvent = new AnimationEvent();
- DoEditRegularParameters(new AnimationEvent[] {dummyEvent}, typeof(AnimationEvent));
+ DoEditRegularParameters(new AnimationEvent[] { dummyEvent }, typeof(AnimationEvent));
}
}
}
@@ -161,6 +182,44 @@ public static void OnEditAnimationEvents(AnimationWindowEvent[] awEvents)
SetData(awEvents, data);
}
+ static string GetFormattedMethodsText(List methods)
+ {
+ string text = "";
+ foreach (AnimationMethodMap methodMap in methods)
+ {
+ text += string.Format("{0}.{1} ( {2} )\n", methodMap.sourceBehaviour.GetType().Name, methodMap.Name, GetTypeName(methodMap.parameterType));
+ }
+ text = text.Trim();
+ return text;
+ }
+
+ static string GetTypeName(Type t)
+ {
+ if (t == null)
+ return "";
+ if (t == typeof(int))
+ return "int";
+ if (t == typeof(float))
+ return "float";
+ if (t == typeof(string))
+ return "string";
+ if (t == typeof(bool))
+ return "bool";
+ return t.Name;
+ }
+
+ static string GetFormattedMethodName(AnimationMethodMap methodMap)
+ {
+ string targetName = methodMap.sourceBehaviour.GetType().Name;
+ string methodName = methodMap.Name;
+ string args = GetTypeName(methodMap.parameterType);
+
+ if (methodName.StartsWith("set_") || methodName.StartsWith("get_"))
+ return string.Format("{0}/Properties/{1} ( {2} )", targetName, methodName, args);
+ else
+ return string.Format("{0}/Methods/{1} ( {2} )", targetName, methodName, args);
+ }
+
public static void OnDisabledAnimationEvent()
{
AnimationEvent dummyEvent = new AnimationEvent();
@@ -168,11 +227,13 @@ public static void OnDisabledAnimationEvent()
using (new EditorGUI.DisabledScope(true))
{
dummyEvent.functionName = EditorGUILayout.TextField(EditorGUIUtility.TrTextContent("Function"), dummyEvent.functionName);
- DoEditRegularParameters(new AnimationEvent[] {dummyEvent}, typeof(AnimationEvent));
+ DoEditRegularParameters(new AnimationEvent[] { dummyEvent }, typeof(AnimationEvent));
}
}
- public static void CollectSupportedMethods(GameObject gameObject, List supportedMethods, HashSet overloadedMethods)
+ static Dictionary> s_TypeAnimationMethodMapCache = new Dictionary>();
+
+ static void CollectSupportedMethods(GameObject gameObject, List supportedMethods, List overloadedMethods, List duplicatedMethods)
{
if (gameObject == null)
return;
@@ -187,59 +248,99 @@ public static void CollectSupportedMethods(GameObject gameObject, List validMethods))
{
- MethodInfo method = methods[i];
- string name = method.Name;
+ var pendingValidMethods = new List();
+ MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly );
+ for (int i = 0; i < methods.Length; i++)
+ {
+ MethodInfo method = methods[i];
+ string name = method.Name;
- if (!IsSupportedMethodName(name))
- continue;
+ if (!IsSupportedMethodName(name))
+ continue;
- ParameterInfo[] parameters = method.GetParameters();
- if (parameters.Length > 1)
- continue;
+ ParameterInfo[] parameters = method.GetParameters();
+ if (parameters.Length > 1)
+ continue;
- Type parameterType = null;
+ Type parameterType = null;
- if (parameters.Length == 1)
- {
- parameterType = parameters[0].ParameterType;
- if (!(parameterType == typeof(string) ||
- parameterType == typeof(float) ||
- parameterType == typeof(int) ||
- parameterType == typeof(AnimationEvent) ||
- parameterType == typeof(UnityEngine.Object) ||
- parameterType.IsSubclassOf(typeof(UnityEngine.Object)) ||
- parameterType.IsEnum))
- continue;
+ if (parameters.Length == 1)
+ {
+ parameterType = parameters[0].ParameterType;
+ if (!(parameterType == typeof(string) ||
+ parameterType == typeof(float) ||
+ parameterType == typeof(int) ||
+ parameterType == typeof(AnimationEvent) ||
+ parameterType == typeof(UnityEngine.Object) ||
+ parameterType.IsSubclassOf(typeof(UnityEngine.Object)) ||
+ parameterType.IsEnum))
+ continue;
+ }
+
+ AnimationMethodMap newMethodMap = new AnimationMethodMap
+ {
+ sourceBehaviour = behaviour,
+ methodInfo = method,
+ parameterType = parameterType
+ };
+
+ newMethodMap.methodMenuPath = GetFormattedMethodName(newMethodMap);
+
+ pendingValidMethods.Add(newMethodMap);
}
- AnimationWindowEventMethod newMethod = new AnimationWindowEventMethod();
- newMethod.name = method.Name;
- newMethod.parameterType = parameterType;
+ validMethods = pendingValidMethods.AsReadOnly();
+ s_TypeAnimationMethodMapCache.Add(type, validMethods);
+ }
+ foreach (var method in validMethods)
+ {
// Since AnimationEvents only stores method name, it can't handle functions with multiple overloads.
- // Only retrieve first found function, but discard overloads.
- int existingMethodIndex = supportedMethods.FindIndex(m => m.name == name);
+ // or functions with the same name across multiple monobehaviours
+ // Only retrieve first found method, and discard overloads and duplicate names.
+ int existingMethodIndex = supportedMethods.FindIndex(m => m.Name == method.Name);
if (existingMethodIndex != -1)
{
// The method is only ambiguous if it has a different signature to the one we saw before
- if (supportedMethods[existingMethodIndex].parameterType != parameterType)
+ if (supportedMethods[existingMethodIndex].parameterType != method.parameterType)
+ {
+ overloadedMethods.Add(method);
+ }
+ // Otherwise, there is another monobehaviour with the same method name.
+ else
{
- overloadedMethods.Add(name);
+ duplicatedMethods.Add(method);
}
}
else
{
- supportedMethods.Add(newMethod);
+ supportedMethods.Add(method);
}
}
+
type = type.BaseType;
}
}
}
+ ///
+ /// Maps the methodInfo and paramter type of a considered animation method to a source monobeheaviour.
+ /// Mimics the structure of
+ ///
+ struct AnimationMethodMap
+ {
+ public Object sourceBehaviour;
+ public MethodInfo methodInfo;
+ public Type parameterType;
+
+ // Used for caching
+ public string methodMenuPath;
+
+ public string Name => methodInfo?.Name ?? "";
+ }
+
public static string FormatEvent(GameObject root, AnimationEvent evt)
{
if (string.IsNullOrEmpty(evt.functionName))
@@ -272,7 +373,7 @@ public static string FormatEvent(GameObject root, AnimationEvent evt)
if (method == null)
continue;
- var parameterTypes = method.GetParameters().Select(p => p.ParameterType);
+ var parameterTypes = method.GetParameters();
return evt.functionName + FormatEventArguments(parameterTypes, evt);
}
@@ -381,15 +482,15 @@ private static bool IsSupportedMethodName(string name)
return name != "Main" && name != "Start" && name != "Awake" && name != "Update";
}
- private static string FormatEventArguments(IEnumerable paramTypes, AnimationEvent evt)
+ private static string FormatEventArguments(ParameterInfo[] paramTypes, AnimationEvent evt)
{
- if (!paramTypes.Any())
+ if (paramTypes.Length == 0)
return " ( )";
- if (paramTypes.Count() > 1)
+ if (paramTypes.Length > 1)
return kNotSupportedPostFix;
- var paramType = paramTypes.First();
+ var paramType = paramTypes[0].ParameterType;
if (paramType == typeof(string))
return " ( \"" + evt.stringParameter + "\" )";
@@ -426,6 +527,9 @@ private struct AnimationWindowEventData
public AnimationEvent[] selectedEvents;
}
+
+ // this are used so we don't alloc new lists on every call
+ static List getDataSelectedEvents;
private static AnimationWindowEventData GetData(AnimationWindowEvent[] awEvents)
{
var data = new AnimationWindowEventData();
@@ -444,14 +548,15 @@ private static AnimationWindowEventData GetData(AnimationWindowEvent[] awEvents)
if (data.events != null)
{
- List selectedEvents = new List();
+ getDataSelectedEvents ??= new List();
+ getDataSelectedEvents.Clear();
foreach (var awEvent in awEvents)
{
if (awEvent.eventIndex >= 0 && awEvent.eventIndex < data.events.Length)
- selectedEvents.Add(data.events[awEvent.eventIndex]);
+ getDataSelectedEvents.Add(data.events[awEvent.eventIndex]);
}
- data.selectedEvents = selectedEvents.ToArray();
+ data.selectedEvents = getDataSelectedEvents.ToArray();
}
return data;
@@ -481,7 +586,7 @@ private static void SetData(AnimationWindowEvent[] awEvents, AnimationWindowEven
static void ResetValues(MenuCommand command)
{
AnimationWindowEvent awEvent = command.context as AnimationWindowEvent;
- AnimationWindowEvent[] awEvents = new AnimationWindowEvent[] {awEvent};
+ AnimationWindowEvent[] awEvents = new AnimationWindowEvent[] { awEvent };
AnimationWindowEventData data = GetData(awEvents);
if (data.events == null || data.selectedEvents == null || data.selectedEvents.Length == 0)
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs
index 1d1ae47c7e..1154cf213e 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs
@@ -342,7 +342,7 @@ private void DoValueField(Rect rect, AnimationWindowHierarchyNode node, int row)
if (curve.valueType == typeof(bool))
{
- value = GUI.Toggle(valueFieldRect, m_HierarchyItemValueControlIDs[row], (float)value != 0, GUIContent.none, EditorStyles.toggle) ? 1f : 0f;
+ value = GUI.Toggle(valueFieldRect, m_HierarchyItemValueControlIDs[row], Convert.ToSingle(value) != 0f, GUIContent.none, EditorStyles.toggle) ? 1f : 0f;
}
else
{
@@ -365,7 +365,7 @@ private void DoValueField(Rect rect, AnimationWindowHierarchyNode node, int row)
valueFieldRect,
valueFieldDragRect,
id,
- (int)value,
+ Convert.ToInt32(value),
EditorGUI.kIntFieldFormatString,
m_AnimationSelectionTextField,
true,
@@ -382,7 +382,7 @@ private void DoValueField(Rect rect, AnimationWindowHierarchyNode node, int row)
valueFieldRect,
valueFieldDragRect,
id,
- (float)value,
+ Convert.ToSingle(value),
"g5",
m_AnimationSelectionTextField,
true);
@@ -392,7 +392,8 @@ private void DoValueField(Rect rect, AnimationWindowHierarchyNode node, int row)
Event.current.Use();
}
- if (float.IsInfinity((float)value) || float.IsNaN((float)value))
+ var floatValue = Convert.ToSingle(value);
+ if (float.IsInfinity(floatValue) || float.IsNaN(floatValue))
value = 0f;
}
}
@@ -491,7 +492,7 @@ private void DoCurveColorIndicator(Rect rect, AnimationWindowHierarchyNode node)
{
foreach (var curve in node.curves)
{
- if (curve.m_Keyframes.Any(key => state.time.ContainsTime(key.time)))
+ if (curve.keyframes.Any(key => state.time.ContainsTime(key.time)))
{
hasKey = true;
}
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowKeyframe.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowKeyframe.cs
index cbdfa58b5e..e9fa64f7fa 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowKeyframe.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowKeyframe.cs
@@ -149,9 +149,9 @@ public int GetHash()
public int GetIndex()
{
- for (int i = 0; i < curve.m_Keyframes.Count; i++)
+ for (int i = 0; i < curve.keyframes.Count; i++)
{
- if (curve.m_Keyframes[i] == this)
+ if (curve.keyframes[i] == this)
{
return i;
}
@@ -167,11 +167,11 @@ public Keyframe ToKeyframe()
// case 1395978
// Negative int values converted to float create NaN values. Limiting discrete int values to only positive values
// until we rewrite the animation backend with dedicated int curves.
- floatValue = UnityEngine.Animations.DiscreteEvaluationAttributeUtilities.ConvertDiscreteIntToFloat(Math.Max((int)value, 0));
+ floatValue = UnityEngine.Animations.DiscreteEvaluationAttributeUtilities.ConvertDiscreteIntToFloat(Math.Max(Convert.ToInt32(value), 0));
}
else
{
- floatValue = (float)value;
+ floatValue = Convert.ToSingle(value);
}
var keyframe = new Keyframe(time, floatValue, inTangent, outTangent);
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs
index c7fc0557f5..d0c4120b18 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs
@@ -514,7 +514,7 @@ private void SaveSelectedKeys(string undoLabel)
List toBeDeleted = new List();
// If selected keys are dragged over non-selected keyframe at exact same time, then delete the unselected ones underneath
- foreach (AnimationWindowKeyframe other in snapshot.curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe other in snapshot.curve.keyframes)
{
// Keyframe is in selection, skip.
if (snapshot.selectedKeys.Exists(liveEditKey => liveEditKey.key == other))
@@ -529,7 +529,7 @@ private void SaveSelectedKeys(string undoLabel)
foreach (AnimationWindowKeyframe deletedKey in toBeDeleted)
{
- snapshot.curve.m_Keyframes.Remove(deletedKey);
+ snapshot.curve.RemoveKeyframe(deletedKey);
}
}
@@ -984,7 +984,7 @@ public AnimationWindowKeyframe activeKeyframe
{
foreach (AnimationWindowCurve curve in filteredCurves)
{
- foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe keyframe in curve.keyframes)
{
if (keyframe.GetHash() == m_ActiveKeyframeHash)
m_ActiveKeyframeCache = keyframe;
@@ -1009,7 +1009,7 @@ public List selectedKeys
m_SelectedKeysCache = new List();
foreach (AnimationWindowCurve curve in filteredCurves)
{
- foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe keyframe in curve.keyframes)
{
if (KeyIsSelected(keyframe))
{
@@ -1139,7 +1139,7 @@ public void DeleteKeys(List keys)
curves.Add(keyframe.curve);
UnselectKey(keyframe);
- keyframe.curve.m_Keyframes.Remove(keyframe);
+ keyframe.curve.RemoveKeyframe(keyframe);
}
SaveCurves(activeAnimationClip, curves, kEditCurveUndoLabel);
@@ -1162,7 +1162,7 @@ public void StartLiveEdit()
{
LiveEditCurve snapshot = new LiveEditCurve();
snapshot.curve = selectedKey.curve;
- foreach (AnimationWindowKeyframe key in selectedKey.curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe key in selectedKey.curve.keyframes)
{
LiveEditKeyframe liveEditKey = new LiveEditKeyframe();
liveEditKey.keySnapshot = new AnimationWindowKeyframe(key);
@@ -1400,7 +1400,7 @@ public void CopyAllActiveCurves()
{
foreach (AnimationWindowCurve curve in activeCurves)
{
- foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe keyframe in curve.keyframes)
{
s_KeyframeClipboard.Add(new AnimationWindowKeyframe(keyframe));
}
@@ -1476,14 +1476,16 @@ public void PasteKeys()
// Only allow pasting of key frame from numerical curves to numerical curves or from pptr curves to pptr curves.
if ((newKeyframe.time >= 0.0f) && (newKeyframe.curve != null) && (newKeyframe.curve.isPPtrCurve == keyframe.curve.isPPtrCurve))
{
- if (newKeyframe.curve.HasKeyframe(AnimationKeyTime.Time(newKeyframe.time, newKeyframe.curve.clip.frameRate)))
- newKeyframe.curve.RemoveKeyframe(AnimationKeyTime.Time(newKeyframe.time, newKeyframe.curve.clip.frameRate));
+ var keyTime = AnimationKeyTime.Time(newKeyframe.time, newKeyframe.curve.clip.frameRate);
+
+ if (newKeyframe.curve.HasKeyframe(keyTime))
+ newKeyframe.curve.RemoveKeyframe(keyTime);
// When copy-pasting multiple keyframes (curve), its a continous thing. This is why we delete the existing keyframes in the pasted range.
if (lastTargetCurve == newKeyframe.curve)
newKeyframe.curve.RemoveKeysAtRange(lastTime, newKeyframe.time);
- newKeyframe.curve.m_Keyframes.Add(newKeyframe);
+ newKeyframe.curve.AddKeyframe(newKeyframe, keyTime);
SelectKey(newKeyframe);
// TODO: Optimize to only save curve once instead once per keyframe
SaveCurve(newKeyframe.curve.clip, newKeyframe.curve, kEditCurveUndoLabel);
@@ -1838,7 +1840,7 @@ public float clipFrameRate
// Reposition all keyframes to match the new sampling rate
foreach (var curve in allCurves)
{
- foreach (var key in curve.m_Keyframes)
+ foreach (var key in curve.keyframes)
{
int frame = AnimationKeyTime.Time(key.time, clipFrameRate).frame;
key.time = AnimationKeyTime.Frame(frame, value).time;
diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs
index 89ae6d3ddf..09e02c7084 100644
--- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs
+++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs
@@ -280,7 +280,7 @@ public static AnimationWindowKeyframe AddKeyframeToCurve(AnimationWindowCurve cu
}
else if (type == typeof(bool) || type == typeof(float) || type == typeof(int))
{
- Keyframe tempKey = new Keyframe(time.time, (float)value);
+ Keyframe tempKey = new Keyframe(time.time, Convert.ToSingle(value));
if (type == typeof(bool))
{
AnimationUtility.SetKeyLeftTangentMode(ref tempKey, TangentMode.Constant);
@@ -888,7 +888,7 @@ public static float GetNextKeyframeTime(AnimationWindowCurve[] curves, float cur
foreach (AnimationWindowCurve curve in curves)
{
- foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe keyframe in curve.keyframes)
{
AnimationKeyTime keyTime = AnimationKeyTime.Time(keyframe.time, frameRate);
if (keyTime.frame <= candidateKeyTime.frame && keyTime.frame >= nextTime.frame)
@@ -914,7 +914,7 @@ public static float GetPreviousKeyframeTime(AnimationWindowCurve[] curves, float
foreach (AnimationWindowCurve curve in curves)
{
- foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe keyframe in curve.keyframes)
{
AnimationKeyTime keyTime = AnimationKeyTime.Time(keyframe.time, frameRate);
if (keyTime.frame >= candidateKeyTime.frame && keyTime.frame <= previousTime.frame)
@@ -1299,8 +1299,8 @@ public static AnimationWindowKeyframe CurveSelectionToAnimationWindowKeyframe(Cu
{
int curveID = curve.GetHashCode();
if (curveID == curveSelection.curveID)
- if (curve.m_Keyframes.Count > curveSelection.key)
- return curve.m_Keyframes[curveSelection.key];
+ if (curve.keyframes.Count > curveSelection.key)
+ return curve.keyframes[curveSelection.key];
}
return null;
diff --git a/Editor/Mono/Animation/AnimationWindow/DopeLine.cs b/Editor/Mono/Animation/AnimationWindow/DopeLine.cs
index c576b1cf2c..da6b52f5f0 100644
--- a/Editor/Mono/Animation/AnimationWindow/DopeLine.cs
+++ b/Editor/Mono/Animation/AnimationWindow/DopeLine.cs
@@ -98,7 +98,7 @@ public List keys
{
m_Keys = new List();
foreach (AnimationWindowCurve curve in m_Curves)
- foreach (AnimationWindowKeyframe key in curve.m_Keyframes)
+ foreach (AnimationWindowKeyframe key in curve.keyframes)
m_Keys.Add(key);
m_Keys.Sort((a, b) => a.time.CompareTo(b.time));
diff --git a/Editor/Mono/Animation/AnimationWindow/DopeSheetEditor.cs b/Editor/Mono/Animation/AnimationWindow/DopeSheetEditor.cs
index eb2bb1b48a..ae4b219977 100644
--- a/Editor/Mono/Animation/AnimationWindow/DopeSheetEditor.cs
+++ b/Editor/Mono/Animation/AnimationWindow/DopeSheetEditor.cs
@@ -806,7 +806,7 @@ private void AssignSpriteToSpriteRenderer(AnimationWindowCurve curve)
if (rootGameObject == null)
return;
- var hasValidCurve = curve.m_Keyframes.Count > 0 && curve.binding.type == typeof(SpriteRenderer);
+ var hasValidCurve = curve.keyframes.Count > 0 && curve.binding.type == typeof(SpriteRenderer);
if (!hasValidCurve)
return;
@@ -815,7 +815,7 @@ private void AssignSpriteToSpriteRenderer(AnimationWindowCurve curve)
if (!hasValidSpriteRenderer)
return;
- var keyframe = curve.m_Keyframes[0];
+ var keyframe = curve.keyframes[0];
var sprite = keyframe.value as Sprite;
if (sprite != null)
{
@@ -1126,12 +1126,12 @@ public void FrameSelected()
{
foreach (AnimationWindowCurve curve in state.activeCurves)
{
- int keyCount = curve.m_Keyframes.Count;
+ int keyCount = curve.keyframes.Count;
if (keyCount > 1)
{
- Vector2 pt1 = new Vector2(curve.m_Keyframes[0].time, 0.0f);
- Vector2 pt2 = new Vector2(curve.m_Keyframes[keyCount - 1].time, 0.0f);
+ Vector2 pt1 = new Vector2(curve.keyframes[0].time, 0.0f);
+ Vector2 pt2 = new Vector2(curve.keyframes[keyCount - 1].time, 0.0f);
if (firstKey)
{
diff --git a/Editor/Mono/Animation/EditorCurveBinding.bindings.cs b/Editor/Mono/Animation/EditorCurveBinding.bindings.cs
index b8e5a4bfbb..8c64e62385 100644
--- a/Editor/Mono/Animation/EditorCurveBinding.bindings.cs
+++ b/Editor/Mono/Animation/EditorCurveBinding.bindings.cs
@@ -8,6 +8,7 @@
using UnityEngine.Playables;
using UnityEngine.Scripting.APIUpdating;
using UnityEngine.Internal;
+using UnityEngine;
namespace UnityEditor
{
@@ -128,6 +129,16 @@ static public EditorCurveBinding DiscreteCurve(string inPath, System.Type inType
binding.m_isSerializeReferenceCurve = 0;
binding.m_isUnknownCurve = 0;
+ if (!AnimationUtility.IsDiscreteIntBinding(binding))
+ {
+ Debug.LogWarning(
+ $"Property [" + inPropertyName + "] is not a supported discrete curve binding. " +
+ "Discrete curves only support [" + typeof(Enum) + "] and [" + typeof(int) + " with the `DiscreteEvaluation` attribute].");
+
+ binding.m_isDiscreteCurve = 0;
+ binding.m_isUnknownCurve = 1;
+ }
+
return binding;
}
diff --git a/Editor/Mono/Animation/TransitionPreview.cs b/Editor/Mono/Animation/TransitionPreview.cs
index 1c2433fb7a..8a7e0da84f 100644
--- a/Editor/Mono/Animation/TransitionPreview.cs
+++ b/Editor/Mono/Animation/TransitionPreview.cs
@@ -269,7 +269,7 @@ private void ResampleTransition(AnimatorStateTransition transition, AvatarMask l
AnimatorStateInfo currentState = m_AvatarPreview.Animator.GetCurrentAnimatorStateInfo(m_LayerIndex);
m_LeftStateWeightA = currentState.normalizedTime;
m_LeftStateTimeA = currentTime;
- while (!hasFinished && currentTime < maxDuration)
+ while (!hasFinished)
{
m_AvatarPreview.Animator.Update(stepTime);
@@ -284,7 +284,7 @@ private void ResampleTransition(AnimatorStateTransition transition, AvatarMask l
hasStarted = true;
}
- if (hasTransitioned && currentTime >= maxDuration)
+ if (hasTransitioned || currentTime >= maxDuration)
{
hasFinished = true;
}
@@ -303,7 +303,7 @@ private void ResampleTransition(AnimatorStateTransition transition, AvatarMask l
m_LeftStateTimeB = currentTime;
}
- if (hasTransitioned)
+ if (hasTransitioned || hasFinished)
{
m_RightStateWeightB = currentState.normalizedTime;
m_RightStateTimeB = currentTime;
@@ -329,6 +329,11 @@ private void ResampleTransition(AnimatorStateTransition transition, AvatarMask l
float leftDuration = (m_LeftStateTimeB - m_LeftStateTimeA) / (m_LeftStateWeightB - m_LeftStateWeightA);
float rightDuration = (m_RightStateTimeB - m_RightStateTimeA) / (m_RightStateWeightB - m_RightStateWeightA);
+ // Ensure step times make sense based on these timings
+ // If step time is too small, the samping will take too long
+ currentStateStepTime = Mathf.Max(currentStateStepTime, leftDuration / 600.0f);
+ nextStateStepTime = Mathf.Max(nextStateStepTime, rightDuration / 600.0f);
+
if (m_MustSampleMotions)
{
// Do this as infrequently as possible
diff --git a/Editor/Mono/AnimatorController.bindings.cs b/Editor/Mono/AnimatorController.bindings.cs
index eee994fcb2..40803d59f3 100644
--- a/Editor/Mono/AnimatorController.bindings.cs
+++ b/Editor/Mono/AnimatorController.bindings.cs
@@ -33,6 +33,7 @@ extern public AnimatorControllerLayer[] layers
[FreeFunction(Name = "AnimatorControllerBindings::GetLayers", HasExplicitThis = true)]
get;
[FreeFunction(Name = "AnimatorControllerBindings::SetLayers", HasExplicitThis = true, ThrowsException = true)]
+ [param: Unmarshalled]
set;
}
@@ -41,6 +42,7 @@ extern public AnimatorControllerParameter[] parameters
[FreeFunction(Name = "AnimatorControllerBindings::GetParameters", HasExplicitThis = true)]
get;
[FreeFunction(Name = "AnimatorControllerBindings::SetParameters", HasExplicitThis = true, ThrowsException = true)]
+ [param: Unmarshalled]
set;
}
@@ -133,6 +135,6 @@ internal extern bool isAssetBundled
extern internal ScriptableObject[] Internal_GetEffectiveBehaviours([NotNull] AnimatorState state, int layerIndex);
[FreeFunction(Name = "AnimatorControllerBindings::Internal_SetEffectiveBehaviours", HasExplicitThis = true)]
- extern internal void Internal_SetEffectiveBehaviours([NotNull] AnimatorState state, int layerIndex, ScriptableObject[] behaviours);
+ extern internal void Internal_SetEffectiveBehaviours([NotNull] AnimatorState state, int layerIndex, [Unmarshalled] ScriptableObject[] behaviours);
}
}
diff --git a/Editor/Mono/Annotation/SceneFXWindow.cs b/Editor/Mono/Annotation/SceneFXWindow.cs
index 4b7a97b2e6..c8b3b6eb94 100644
--- a/Editor/Mono/Annotation/SceneFXWindow.cs
+++ b/Editor/Mono/Annotation/SceneFXWindow.cs
@@ -4,6 +4,7 @@
using System;
using UnityEngine;
+using UnityEngine.Rendering;
namespace UnityEditor
{
@@ -74,6 +75,12 @@ private void Draw(Rect rect)
DrawListElement(drawPos, "Skybox", state.showSkybox, value => state.showSkybox = value);
drawPos.y += EditorGUI.kSingleLineHeight;
+ if(SupportedRenderingFeatures.active.supportsClouds)
+ {
+ DrawListElement(drawPos, "Clouds", state.showClouds, value => state.showClouds = value);
+ drawPos.y += EditorGUI.kSingleLineHeight;
+ }
+
DrawListElement(drawPos, "Fog", state.showFog, value => state.showFog = value);
drawPos.y += EditorGUI.kSingleLineHeight;
diff --git a/Editor/Mono/AssemblyHelper.cs b/Editor/Mono/AssemblyHelper.cs
index 73a0f4acab..afd649332e 100644
--- a/Editor/Mono/AssemblyHelper.cs
+++ b/Editor/Mono/AssemblyHelper.cs
@@ -7,14 +7,11 @@
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
-using System.Diagnostics;
using Mono.Cecil;
-using UnityEditor.Build;
using UnityEditor.Modules;
using UnityEditorInternal;
using UnityEngine;
using System.Runtime.InteropServices;
-using UnityEditor.VisualStudioIntegration;
using UnityEngine.Scripting;
using Debug = UnityEngine.Debug;
using Unity.Profiling;
@@ -24,181 +21,11 @@
namespace UnityEditor
{
- internal partial class AssemblyHelper
+ internal class AssemblyHelper
{
static Dictionary managedToDllType = new Dictionary();
static BuildPlayerDataExtractor m_BuildPlayerDataExtractor = new BuildPlayerDataExtractor();
- static public string[] GetNamesOfAssembliesLoadedInCurrentDomain()
- {
- var assemblies = AppDomain.CurrentDomain.GetAssemblies();
- var locations = new List();
- foreach (var a in assemblies)
- {
- try
- {
- locations.Add(a.Location);
- }
- catch (NotSupportedException)
- {
- //we have some "dynamic" assmeblies that do not have a filename
- }
- }
- return locations.ToArray();
- }
-
- static public string ExtractInternalAssemblyName(string path)
- {
- try
- {
- AssemblyDefinition definition = AssemblyDefinition.ReadAssembly(path);
- return definition.Name.Name;
- }
- catch
- {
- return "";
- }
- }
-
- static AssemblyDefinition GetAssemblyDefinitionCached(string path, Dictionary cache)
- {
- if (cache.ContainsKey(path))
- return cache[path];
-
- AssemblyDefinition definition = AssemblyDefinition.ReadAssembly(path);
- cache[path] = definition;
- return definition;
- }
-
- static private bool CouldBelongToDotNetOrWindowsRuntime(string assemblyPath)
- {
- return assemblyPath.IndexOf("mscorlib.dll") != -1 ||
- assemblyPath.IndexOf("System.") != -1 ||
- assemblyPath.IndexOf("Microsoft.") != -1 ||
- assemblyPath.IndexOf("Windows.") != -1 ||
- assemblyPath.IndexOf("WinRTLegacy.dll") != -1 ||
- assemblyPath.IndexOf("platform.dll") != -1;
- }
-
- static private bool IgnoreAssembly(string assemblyPath, BuildTarget target, ScriptingImplementation scriptingImplementation)
- {
-#pragma warning disable 618
- if (target == BuildTarget.WSAPlayer || scriptingImplementation == ScriptingImplementation.CoreCLR)
- {
- if (CouldBelongToDotNetOrWindowsRuntime(assemblyPath))
- return true;
- }
- else if (target == BuildTarget.XboxOne)
- {
- var profile = PlayerSettings.GetApiCompatibilityLevel(NamedBuildTarget.XboxOne);
- if (profile == ApiCompatibilityLevel.NET_4_6 || profile == ApiCompatibilityLevel.NET_Standard_2_0)
- {
- if (CouldBelongToDotNetOrWindowsRuntime(assemblyPath))
- return true;
- }
- }
-
- return IsInternalAssembly(assemblyPath);
- }
-
- static private void AddReferencedAssembliesRecurse(string assemblyPath, List alreadyFoundAssemblies, string[] allAssemblyPaths, string[] foldersToSearch, Dictionary cache, BuildTarget target, ScriptingImplementation scriptingImplementation)
- {
- if (IgnoreAssembly(assemblyPath, target, scriptingImplementation))
- return;
-
- if (!File.Exists(assemblyPath))
- return;
-
- AssemblyDefinition assembly = GetAssemblyDefinitionCached(assemblyPath, cache);
- if (assembly == null)
- throw new System.ArgumentException("Referenced Assembly " + Path.GetFileName(assemblyPath) + " could not be found!");
-
- // Ignore it if we already added the assembly
- if (alreadyFoundAssemblies.IndexOf(assemblyPath) != -1)
- return;
-
- alreadyFoundAssemblies.Add(assemblyPath);
-
- var architectureSpecificPlugins = PluginImporter.GetImporters(target).Where(i =>
- {
- var cpu = i.GetPlatformData(target, "CPU");
- return !string.IsNullOrEmpty(cpu) && !string.Equals(cpu, "AnyCPU", StringComparison.InvariantCultureIgnoreCase);
- }).Select(i => Path.GetFileName(i.assetPath)).Distinct();
-
- // Go through all referenced assemblies
- foreach (AssemblyNameReference referencedAssembly in assembly.MainModule.AssemblyReferences)
- {
- // Special cases for Metro
- if (referencedAssembly.Name == "BridgeInterface") continue;
- if (referencedAssembly.Name == "WinRTBridge") continue;
- if (referencedAssembly.Name == "UnityEngineProxy") continue;
- if (IgnoreAssembly(referencedAssembly.Name + ".dll", target, scriptingImplementation)) continue;
-
- string foundPath = FindAssemblyName(referencedAssembly.FullName, referencedAssembly.Name, allAssemblyPaths, foldersToSearch, cache);
-
- if (foundPath == "")
- {
- // Ignore architecture specific plugin references
- var found = false;
- foreach (var extension in new[] { ".dll", ".winmd" })
- {
- if (architectureSpecificPlugins.Any(p => string.Equals(p, referencedAssembly.Name + extension, StringComparison.InvariantCultureIgnoreCase)))
- {
- found = true;
- break;
- }
- }
- if (found)
- continue;
- throw new System.ArgumentException(string.Format("The Assembly {0} is referenced by {1} ('{2}'). But the dll is not allowed to be included or could not be found.",
- referencedAssembly.Name,
- assembly.MainModule.Assembly.Name.Name,
- assemblyPath));
- }
-
- AddReferencedAssembliesRecurse(foundPath, alreadyFoundAssemblies, allAssemblyPaths, foldersToSearch, cache, target, scriptingImplementation);
- }
- }
-
- static string FindAssemblyName(string fullName, string name, string[] allAssemblyPaths, string[] foldersToSearch, Dictionary cache)
- {
- // Search in provided assemblies
- for (int i = 0; i < allAssemblyPaths.Length; i++)
- {
- if (!File.Exists(allAssemblyPaths[i]))
- continue;
-
- AssemblyDefinition definition = GetAssemblyDefinitionCached(allAssemblyPaths[i], cache);
- if (definition.MainModule.Assembly.Name.Name == name)
- return allAssemblyPaths[i];
- }
-
- // Search in GAC
- foreach (string folder in foldersToSearch)
- {
- string pathInGacFolder = Path.Combine(folder, name + ".dll");
- if (File.Exists(pathInGacFolder))
- return pathInGacFolder;
- }
- return "";
- }
-
- [RequiredByNativeCode]
- static public string[] FindAssembliesReferencedBy(string[] paths, string[] foldersToSearch, BuildTarget target, ScriptingImplementation scriptingImplementation)
- {
- List unique = new List();
- string[] allAssemblyPaths = paths;
-
- var cache = new Dictionary();
- for (int i = 0; i < paths.Length; i++)
- AddReferencedAssembliesRecurse(paths[i], unique, allAssemblyPaths, foldersToSearch, cache, target, scriptingImplementation);
-
- for (int i = 0; i < paths.Length; i++)
- unique.Remove(paths[i]);
-
- return unique.ToArray();
- }
-
static public bool IsUnityEngineModule(AssemblyDefinition assembly)
{
return assembly.CustomAttributes.Any(a => a.AttributeType.FullName == typeof(UnityEngineModuleAssembly).FullName);
@@ -209,33 +36,6 @@ static public bool IsUnityEngineModule(Assembly assembly)
return assembly.GetCustomAttributes(typeof(UnityEngineModuleAssembly), false).Length > 0;
}
- private static bool IsTypeAUserExtendedScript(TypeReference type)
- {
- if (type == null || type.FullName == "System.Object")
- return false;
-
- try
- {
- var typeDefinition = type.Resolve();
- var attributes = typeDefinition.CustomAttributes;
- for (var i = 0; i < attributes.Count; i++)
- {
- if (attributes[i].Constructor.DeclaringType.FullName == "UnityEngine.ExtensionOfNativeClassAttribute")
- return true;
- }
-
- if (typeDefinition.BaseType != null)
- return IsTypeAUserExtendedScript(typeDefinition.BaseType);
- }
- catch (AssemblyResolutionException)
- {
- // just eat exception if we fail to load assembly here.
- // failure should be handled better in other places.
- }
-
- return false;
- }
-
public static string[] GetDefaultAssemblySearchPaths()
{
// Add the path to all available precompiled assemblies
@@ -359,36 +159,6 @@ public static bool IsInternalAssembly(string file)
return ModuleUtils.GetAdditionalReferencesForUserScripts().Any(p => p.Equals(file));
}
- const int kDefaultDepth = 10;
- internal static ICollection FindAssemblies(string basePath)
- {
- return FindAssemblies(basePath, kDefaultDepth);
- }
-
- internal static ICollection FindAssemblies(string basePath, int maxDepth)
- {
- var assemblies = new List();
-
- if (0 == maxDepth)
- return assemblies;
-
- try
- {
- DirectoryInfo directory = new DirectoryInfo(basePath);
- assemblies.AddRange(directory.GetFiles()
- .Where(file => IsManagedAssembly(file.FullName))
- .Select(file => file.FullName));
- foreach (DirectoryInfo subdirectory in directory.GetDirectories())
- assemblies.AddRange(FindAssemblies(subdirectory.FullName, maxDepth - 1));
- }
- catch (Exception)
- {
- // Return what we have now
- }
-
- return assemblies;
- }
-
///
/// Performs a depth-first-search topological sort on the input assemblies,
/// based on the outgoing assembly references from each assembly. The
diff --git a/Editor/Mono/AssemblyInfo/AssemblyInfo.cs b/Editor/Mono/AssemblyInfo/AssemblyInfo.cs
index 2682979939..bae9fb7fec 100644
--- a/Editor/Mono/AssemblyInfo/AssemblyInfo.cs
+++ b/Editor/Mono/AssemblyInfo/AssemblyInfo.cs
@@ -7,6 +7,7 @@
// ADD_NEW_PLATFORM_HERE
[assembly: InternalsVisibleTo("Unity.LiveNotes")]
+[assembly: InternalsVisibleTo("Unity.Audio.Tests")]
[assembly: InternalsVisibleTo("Unity.Burst")]
[assembly: InternalsVisibleTo("Unity.Burst.Editor")]
[assembly: InternalsVisibleTo("Unity.Cloud.Collaborate.Editor")]
@@ -29,7 +30,6 @@
[assembly: InternalsVisibleTo("Unity.Timeline.Editor")]
[assembly: InternalsVisibleTo("Unity.PackageManagerUI.Develop.Editor")]
[assembly: InternalsVisibleTo("Unity.DeviceSimulator.Editor")]
-
[assembly: InternalsVisibleTo("Unity.Timeline.EditorTests")]
[assembly: InternalsVisibleTo("UnityEditor.Graphs")]
[assembly: InternalsVisibleTo("UnityEditor.UWP.Extensions")]
@@ -50,7 +50,6 @@
[assembly: InternalsVisibleTo("UnityEditor.WindowsStandalone.Extensions")]
[assembly: InternalsVisibleTo("UnityEditor.OSXStandalone.Extensions")]
[assembly: InternalsVisibleTo("UnityEditor.Lumin.Extensions")]
-[assembly: InternalsVisibleTo("UnityEditor.Stadia.Extensions")]
[assembly: InternalsVisibleTo("UnityEditor.GameCoreScarlett.Extensions")]
[assembly: InternalsVisibleTo("UnityEditor.GameCoreXboxOne.Extensions")]
[assembly: InternalsVisibleTo("UnityEditor.GameCoreCommon.Extensions")]
@@ -130,6 +129,7 @@
[assembly: InternalsVisibleTo("UnityEditor.TextCoreTextEngineModule")]
[assembly: InternalsVisibleTo("Unity.TextMeshPro.Editor")]
[assembly: InternalsVisibleTo("Unity.Animation.Editor.AnimationWindow")]
+[assembly: InternalsVisibleTo("Unity.RenderPipelines.Multiple_SRP.EditorTests")]
[assembly: InternalsVisibleTo("Unity.SceneTemplate.Editor")]
[assembly: InternalsVisibleTo("com.unity.purchasing.udp.Editor")]
diff --git a/Editor/Mono/AssemblyValidation.cs b/Editor/Mono/AssemblyValidation.cs
index 16f2d3315e..d6d55f3a55 100644
--- a/Editor/Mono/AssemblyValidation.cs
+++ b/Editor/Mono/AssemblyValidation.cs
@@ -137,6 +137,34 @@ public static Error[] ValidateAssemblies(string[] assemblyPaths, bool enableLogg
return errors;
}
+ [RequiredByNativeCode]
+ internal static Error[] ValidateRoslynAnalyzers(string[] analyzerPaths)
+ {
+ var readerParameters = new ReaderParameters
+ {
+ ReadingMode = ReadingMode.Deferred
+ };
+ List errors = new List();
+ foreach(var analyzer in analyzerPaths)
+ {
+ using (var analyzerDefinition = AssemblyDefinition.ReadAssembly(analyzer, readerParameters))
+ {
+ var netstandardVersion = analyzerDefinition.MainModule.AssemblyReferences.Where(r => r.Name == "netstandard").FirstOrDefault();
+ if (netstandardVersion != null && netstandardVersion.Version >= new Version(2, 1))
+ {
+ errors.Add(new Error
+ {
+ assemblyPath = analyzer,
+ flags = ErrorFlags.ReferenceHasErrors,
+ message = $"{analyzerDefinition.Name.Name} references {netstandardVersion}. A roslyn analyzer should reference netstandard version 2.0"
+ });
+ }
+
+ }
+ }
+ return errors.ToArray();
+ }
+
[RequiredByNativeCode]
public static Error[] ValidateAssemblyDefinitionFiles()
{
diff --git a/Editor/Mono/AssetDatabase/AssetDatabaseSearching.cs b/Editor/Mono/AssetDatabase/AssetDatabaseSearching.cs
index c3bd1ded72..fedd4d13e0 100644
--- a/Editor/Mono/AssetDatabase/AssetDatabaseSearching.cs
+++ b/Editor/Mono/AssetDatabase/AssetDatabaseSearching.cs
@@ -88,7 +88,7 @@ private static IEnumerator FindInFolders(SearchFilter searchFilter, Func subAsse
texImporter.sRGBTexture = false; // extra texture does not contain color data, hence shouldn't be sRGB.
texImporter.SaveAndReimport();
}
+
+
}
}
}
diff --git a/Editor/Mono/AssetPipeline/TextureImporter.bindings.cs b/Editor/Mono/AssetPipeline/TextureImporter.bindings.cs
index 09252985c2..77c87e4adf 100644
--- a/Editor/Mono/AssetPipeline/TextureImporter.bindings.cs
+++ b/Editor/Mono/AssetPipeline/TextureImporter.bindings.cs
@@ -468,7 +468,6 @@ public void SetTextureSettings(TextureImporterSettings src)
internal extern bool removeMatte { get; set; }
public extern bool ignorePngGamma { get; set; }
- internal static readonly int MaxTextureSizeAllowedForReadable = 8192; //keep in sync with TextureImporter.h
// This is for remapping Sprite that are renamed.
extern internal bool GetNameFromInternalIDMap(long id, ref string name);
diff --git a/Editor/Mono/AssetPreviewUpdater.cs b/Editor/Mono/AssetPreviewUpdater.cs
index bed2f81cdc..d0c3538ae6 100644
--- a/Editor/Mono/AssetPreviewUpdater.cs
+++ b/Editor/Mono/AssetPreviewUpdater.cs
@@ -3,6 +3,8 @@
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using UnityEngine;
+using UnityEngine.Rendering;
+using UnityEngine.Scripting;
namespace UnityEditor
{
@@ -16,14 +18,11 @@ public static Texture2D CreatePreviewForAsset(Object obj, Object[] subAssets, st
// Generate a preview texture for an asset
public static Texture2D CreatePreview(Object obj, Object[] subAssets, string assetPath, int width, int height)
{
- if (obj == null)
- return null;
-
- System.Type type = CustomEditorAttributes.FindCustomEditorType(obj, false);
+ var type = CustomEditorAttributes.FindCustomEditorType(obj, false);
if (type == null)
return null;
- System.Reflection.MethodInfo info = type.GetMethod("RenderStaticPreview");
+ var info = type.GetMethod("RenderStaticPreview");
if (info == null)
{
Debug.LogError("Fail to find RenderStaticPreview base method");
@@ -33,13 +32,20 @@ public static Texture2D CreatePreview(Object obj, Object[] subAssets, string ass
if (info.DeclaringType == typeof(Editor))
return null;
-
- Editor editor = Editor.CreateEditor(obj);
-
+ var editor = Editor.CreateEditor(obj);
if (editor == null)
return null;
- Texture2D tex = editor.RenderStaticPreview(assetPath, subAssets, width, height);
+ //Check that Render Pipeline is ready
+ //Beware: AssetImportWorkers have their own Render Pipeline instance. Render Pipeline will be separately created for each one of them.
+ var pipelineWasNotInitialized = !RenderPipelineManager.pipelineSwitchCompleted;
+
+ //We always keep this call to initialize Render Pipeline when Render Pipeline was not ready
+ var previewTexture = editor.RenderStaticPreview(assetPath, subAssets, width, height);
+
+ //If after render our Render Pipeline is initialized we re-render to have a valid result
+ if (pipelineWasNotInitialized && RenderPipelineManager.pipelineSwitchCompleted)
+ previewTexture = editor.RenderStaticPreview(assetPath, subAssets, width, height);
// For debugging we write the preview to a file (keep)
//{
@@ -50,8 +56,7 @@ public static Texture2D CreatePreview(Object obj, Object[] subAssets, string ass
//}
Object.DestroyImmediate(editor);
-
- return tex;
+ return previewTexture;
}
}
}
diff --git a/Editor/Mono/AssetStore/AssetStoreWindow.cs b/Editor/Mono/AssetStore/AssetStoreWindow.cs
index f0533b3eaa..028877f5ae 100644
--- a/Editor/Mono/AssetStore/AssetStoreWindow.cs
+++ b/Editor/Mono/AssetStore/AssetStoreWindow.cs
@@ -13,9 +13,6 @@ namespace UnityEditor
[EditorWindowTitle(title = "Asset Store", icon = "Asset Store")]
internal class AssetStoreWindow : EditorWindow
{
- // Use this for initialization
- // Index at 1499 because "Package Manager" is 1500, pairing tools for user to get external content
- [MenuItem("Window/Asset Store", false, 1499)]
public static AssetStoreWindow Init()
{
if (EditorPrefs.GetBool("AlwaysOpenAssetStoreInBrowser", false))
@@ -32,14 +29,22 @@ public static AssetStoreWindow Init()
}
}
- private static void OpenAssetStoreInBrowser()
+ [MenuItem("Window/Asset Store", false, 1497)]
+ public static void OpenAssetStoreInBrowser()
{
string assetStoreUrl = UnityConnect.instance.GetConfigurationURL(CloudConfigUrl.CloudAssetStoreUrl);
- if (UnityEditor.Connect.UnityConnect.instance.loggedIn)
- UnityEditor.Connect.UnityConnect.instance.OpenAuthorizedURLInWebBrowser(assetStoreUrl);
+ assetStoreUrl += "?utm_source=unity-editor-window-menu&utm_medium=desktop-app";
+ if (UnityConnect.instance.loggedIn)
+ UnityConnect.instance.OpenAuthorizedURLInWebBrowser(assetStoreUrl);
else Application.OpenURL(assetStoreUrl);
}
+ [MenuItem("Window/My Assets", false, 1498)]
+ public static void OpenMyAssetsInPackageManager()
+ {
+ PackageManagerWindow.SelectPackageAndFilterStatic(string.Empty, PackageManager.UI.Internal.PackageFilterTab.AssetStore);
+ }
+
public void OnEnable()
{
this.antiAliasing = 4;
diff --git a/Editor/Mono/AttributeHelper.cs b/Editor/Mono/AttributeHelper.cs
index a7aa63dac9..95d72e45d3 100644
--- a/Editor/Mono/AttributeHelper.cs
+++ b/Editor/Mono/AttributeHelper.cs
@@ -145,7 +145,7 @@ struct MonoCreateAssetItem
}
[RequiredByNativeCode]
- static MonoCreateAssetItem[] ExtractCreateAssetMenuItems(Assembly assembly)
+ static MonoCreateAssetItem[] ExtractCreateAssetMenuItems()
{
var result = new List();
@@ -166,6 +166,11 @@ static MonoCreateAssetItem[] ExtractCreateAssetMenuItems(Assembly assembly)
if (!System.IO.Path.HasExtension(fileName))
fileName = fileName + ".asset";
+ // trim the trailing space from the menu name:
+ // 1. visually it is hard to differentialte menu names with or without spaces.
+ // 2. when asset menu is searched, it will search the trimmed menu name, so it will create a edge case where a menu name with space could not be found after creation.
+ menuItemName = menuItemName.TrimEnd();
+
var item = new MonoCreateAssetItem
{
menuItem = menuItemName,
diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs
index 199bacfb82..2975edd030 100644
--- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs
+++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs
@@ -238,8 +238,14 @@ static List FindAllAudioMixerControllers()
foreach (var prop in AssetDatabase.FindAllAssets(new SearchFilter() { classNames = new[] { "AudioMixerController" } }))
{
var controller = prop.pptrValue as AudioMixerController;
+
if (controller)
- result.Add(controller);
+ {
+ if (controller.HasValidSnapshots())
+ result.Add(controller);
+ else
+ Debug.LogError($"Can not display audio mixer window for '{controller.name}' as it could not be properly initialized. The mixer asset is possibly corrupted.");
+ }
}
return result;
}
@@ -341,6 +347,12 @@ public void UndoRedoPerformed(in UndoRedoInfo info)
void OnMixerControllerChanged()
{
+ if (m_Controller != null && !m_Controller.HasValidSnapshots())
+ {
+ Debug.LogError($"Can not display audio mixer window for '{m_Controller.name}' as it could not be properly initialized. The mixer asset is possibly corrupted.");
+ return;
+ }
+
if (m_Controller)
m_Controller.ClearEventHandlers();
@@ -369,9 +381,15 @@ void DetectControllerChange()
AudioMixerController oldController = m_Controller;
if (Selection.activeObject is AudioMixerController)
m_Controller = Selection.activeObject as AudioMixerController;
+
if (m_Controller != oldController)
{
- OnMixerControllerChanged();
+ if (m_Controller.HasValidSnapshots())
+ OnMixerControllerChanged();
+ else
+ {
+ Debug.LogError($"Can not display audio mixer window for '{m_Controller.name}' as it could not be properly initialized. The mixer asset is possibly corrupted.");
+ }
}
}
diff --git a/Editor/Mono/BuildPipeline.bindings.cs b/Editor/Mono/BuildPipeline.bindings.cs
index 9d3bc9cd6e..2fe82e481f 100644
--- a/Editor/Mono/BuildPipeline.bindings.cs
+++ b/Editor/Mono/BuildPipeline.bindings.cs
@@ -183,7 +183,10 @@ public enum BuildAssetBundleOptions
//AssetBundleAllowEditorOnlyScriptableObjects = 1 << 14,
//Removes the Unity Version number in the Archive File & Serialized File headers during the build.
- AssetBundleStripUnityVersion = 32768 // 1 << 15
+ AssetBundleStripUnityVersion = 32768, // 1 << 15
+
+ // Calculate bundle hash on the bundle content
+ UseContentHash = 65536 // 1 << 16
}
// Keep in sync with CanAppendBuild in EditorUtility.h
@@ -381,6 +384,11 @@ private static BuildReport BuildPlayer(string[] scenes, string locationPathName,
{
return BuildPlayerInternal(scenes, locationPathName, assetBundleManifestPath, buildTargetGroup, target, subtarget, options, extraScriptingDefines);
}
+ catch (System.ArgumentException argumentException)
+ {
+ Debug.LogException(argumentException);
+ return null;
+ }
catch (System.Exception exception)
{
// In some case BuildPlayer might let a null reference exception fall through. Prevent data loss by just exiting.
@@ -498,8 +506,8 @@ public static string BuildStreamedSceneAssetBundle(string[] levels, string locat
private static BuildReport BuildPlayerInternal(string[] levels, string locationPathName, string assetBundleManifestPath, BuildTargetGroup buildTargetGroup, BuildTarget target, int subtarget, BuildOptions options, string[] extraScriptingDefines)
{
- if (!BuildPlayerWindow.DefaultBuildMethods.IsBuildPathValid(locationPathName))
- throw new Exception("Invalid Build Path: " + locationPathName);
+ if (!BuildPlayerWindow.DefaultBuildMethods.IsBuildPathValid(locationPathName, out var msg))
+ throw new ArgumentException($"Invalid build path: '{locationPathName}'. {msg}");
return BuildPlayerInternalNoCheck(levels, locationPathName, assetBundleManifestPath, buildTargetGroup, target, subtarget, options, extraScriptingDefines, false);
}
@@ -738,6 +746,7 @@ private static bool DoesBuildTargetSupportPlayerConnectionPlayerToEditor(BuildTa
targetPlatform == BuildTarget.StandaloneWindows ||
targetPlatform == BuildTarget.StandaloneWindows64 ||
targetPlatform == BuildTarget.StandaloneLinux64 ||
+ targetPlatform == BuildTarget.iOS ||
// Android: support connection from player to Editor in both cases
// connecting to 127.0.0.1 (when both Editor and Android are on localhost using USB cable)
// connecting to , the Android and PC has to be on the same subnet
diff --git a/Editor/Mono/BuildPipeline/BuildPlatform.cs b/Editor/Mono/BuildPipeline/BuildPlatform.cs
index 794017dd2a..08dc117a97 100644
--- a/Editor/Mono/BuildPipeline/BuildPlatform.cs
+++ b/Editor/Mono/BuildPipeline/BuildPlatform.cs
@@ -191,10 +191,5 @@ public List GetValidPlatforms()
{
return GetValidPlatforms(false);
}
-
- public static string[] GetValidPlatformNames()
- {
- return instance.GetValidPlatforms().ConvertAll(platform => platform.name).ToArray();
- }
}
}
diff --git a/Editor/Mono/BuildPipeline/DesktopStandaloneBuildWindowExtension.cs b/Editor/Mono/BuildPipeline/DesktopStandaloneBuildWindowExtension.cs
index 08000cf330..76f9f4afa6 100644
--- a/Editor/Mono/BuildPipeline/DesktopStandaloneBuildWindowExtension.cs
+++ b/Editor/Mono/BuildPipeline/DesktopStandaloneBuildWindowExtension.cs
@@ -19,15 +19,26 @@ internal abstract class DesktopStandaloneBuildWindowExtension : DefaultBuildWind
protected bool m_HasMonoPlayers;
protected bool m_HasIl2CppPlayers;
protected bool m_HasCoreCLRPlayers;
- protected bool m_HasServerPlayers;
+ protected bool m_HasServerMonoPlayers;
+ protected bool m_HasServerIl2CppPlayers;
protected bool m_IsRunningOnHostPlatform;
+ public bool MonoPlayersInstalled(NamedBuildTarget namedBuildTarget)
+ {
+ return namedBuildTarget == NamedBuildTarget.Server ? m_HasServerMonoPlayers : m_HasMonoPlayers;
+ }
+
+ public bool Il2CppPlayersInstalled(NamedBuildTarget namedBuildTarget)
+ {
+ return namedBuildTarget == NamedBuildTarget.Server ? m_HasServerIl2CppPlayers : m_HasIl2CppPlayers;
+ }
+
public static void SetArchitectureForPlatform(BuildTarget buildTarget, OSArchitecture architecture)
{
EditorUserBuildSettings.SetPlatformSettings(BuildPipeline.GetBuildTargetName(buildTarget), EditorUserBuildSettings.kSettingArchitecture, architecture.ToString().ToLower());
}
- public DesktopStandaloneBuildWindowExtension(bool hasMonoPlayers, bool hasIl2CppPlayers, bool hasCoreCLRPlayers, bool hasServerPlayers)
+ public DesktopStandaloneBuildWindowExtension(bool hasMonoPlayers, bool hasIl2CppPlayers, bool hasCoreCLRPlayers, bool hasServerMonoPlayers, bool hasServerIl2CppPlayers)
{
SetupStandaloneSubtargets();
@@ -35,7 +46,8 @@ public DesktopStandaloneBuildWindowExtension(bool hasMonoPlayers, bool hasIl2Cpp
m_HasIl2CppPlayers = hasIl2CppPlayers;
m_HasCoreCLRPlayers = hasCoreCLRPlayers;
m_HasMonoPlayers = hasMonoPlayers;
- m_HasServerPlayers = hasServerPlayers;
+ m_HasServerMonoPlayers = hasServerMonoPlayers;
+ m_HasServerIl2CppPlayers = hasServerIl2CppPlayers;
}
private void SetupStandaloneSubtargets()
@@ -84,30 +96,6 @@ struct BuildTargetInfo
public OSArchitecture architecture;
}
- private static Dictionary GetArchitecturesForPlatform(BuildTarget target)
- {
- switch (target)
- {
- case BuildTarget.StandaloneWindows:
- case BuildTarget.StandaloneWindows64:
- return new Dictionary
- {
- { EditorGUIUtility.TrTextContent("Intel 64-bit"), new BuildTargetInfo
- {
- buildTarget = BuildTarget.StandaloneWindows64,
- architecture = OSArchitecture.x64
- }},
- { EditorGUIUtility.TrTextContent("Intel 32-bit"), new BuildTargetInfo
- {
- buildTarget = BuildTarget.StandaloneWindows,
- architecture = OSArchitecture.x86
- }},
- };
- default:
- return null;
- }
- }
-
private static BuildTarget DefaultTargetForPlatform(BuildTarget target)
{
switch (target)
@@ -186,30 +174,7 @@ public override void ShowPlatformBuildOptions()
int selectedIndex = Math.Max(0, Array.IndexOf(m_StandaloneSubtargets, DefaultTargetForPlatform(selectedTarget)));
int newIndex = EditorGUILayout.Popup(m_StandaloneTarget, selectedIndex, m_StandaloneSubtargetStrings);
- if (newIndex == selectedIndex)
- {
- Dictionary architectures = GetArchitecturesForPlatform(selectedTarget);
- if (null != architectures)
- {
- // Display architectures for the current target platform
- GUIContent[] architectureNames = new List(architectures.Keys).ToArray();
- int selectedArchitecture = 0;
-
- // Grab m_Architecture index for currently selected target
- foreach (var architecture in architectures)
- {
- if (architecture.Value.buildTarget == selectedTarget)
- {
- selectedArchitecture = System.Math.Max(0, System.Array.IndexOf(architectureNames, architecture.Key));
- break;
- }
- }
-
- selectedArchitecture = EditorGUILayout.Popup(m_Architecture, selectedArchitecture, architectureNames);
- newTarget = architectures[architectureNames[selectedArchitecture]];
- }
- }
- else
+ if (newIndex != selectedIndex)
{
newTarget = DefaultArchitectureForTarget(m_StandaloneSubtargets[newIndex]);
}
@@ -223,7 +188,6 @@ public override void ShowPlatformBuildOptions()
}
ShowArchitectureSpecificOptions();
-
ShowBackendErrorIfNeeded();
}
@@ -248,12 +212,15 @@ protected virtual string GetCannotBuildPlayerInCurrentSetupError()
if (namedBuildTarget == NamedBuildTarget.Server)
{
- if(!m_HasServerPlayers)
- return $"Dedicated Server support for {GetHostPlatformName()} is not installed.";
+ if (scriptingBackend == ScriptingImplementation.Mono2x && !m_HasServerMonoPlayers)
+ return $"Dedicated Server support (Mono) for {GetHostPlatformName()} is not installed.";
if (scriptingBackend == ScriptingImplementation.IL2CPP && !m_IsRunningOnHostPlatform)
return string.Format("{0} IL2CPP player can only be built on {0}.", GetHostPlatformName());
+ if (scriptingBackend == ScriptingImplementation.IL2CPP && !m_HasServerIl2CppPlayers)
+ return $"Dedicated Server support (IL2CPP) for {GetHostPlatformName()} is not installed.";
+
return null;
}
@@ -261,7 +228,7 @@ protected virtual string GetCannotBuildPlayerInCurrentSetupError()
{
case ScriptingImplementation.Mono2x:
{
- if (!m_HasMonoPlayers)
+ if (!MonoPlayersInstalled(namedBuildTarget))
return "Currently selected scripting backend (Mono) is not installed.";
break;
}
@@ -276,7 +243,7 @@ protected virtual string GetCannotBuildPlayerInCurrentSetupError()
{
if (!m_IsRunningOnHostPlatform)
return string.Format("{0} IL2CPP player can only be built on {0}.", GetHostPlatformName());
- if (!m_HasIl2CppPlayers)
+ if (!Il2CppPlayersInstalled(namedBuildTarget))
return "Currently selected scripting backend (IL2CPP) is not installed.";
break;
}
@@ -286,8 +253,6 @@ protected virtual string GetCannotBuildPlayerInCurrentSetupError()
}
}
-
-
return null;
}
diff --git a/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs b/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs
index f958200bbb..7daf4ab71d 100644
--- a/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs
+++ b/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs
@@ -5,6 +5,7 @@
using System;
using UnityEditor;
using UnityEditor.Build;
+using UnityEditor.Build.Reporting;
using UnityEditor.Modules;
using UnityEditorInternal;
using UnityEngine;
@@ -22,7 +23,7 @@ protected virtual string GetVariationName(BuildPostProcessArgs args)
GetPlatformString(args),
GetServer(args) ? "server" : "player",
GetDevelopment(args) ? "development" : "nondevelopment",
- GetScriptingBackend(args).ToString().ToLower());
+ GetScriptingBackend(args).ToString().ToLowerInvariant());
}
protected bool GetServer(BuildPostProcessArgs args) =>
@@ -66,9 +67,9 @@ protected DesktopStandalonePostProcessor(bool hasMonoPlayers, bool hasIl2CppPlay
m_HasServerCoreCLRPlayers = hasServerCoreCLRPlayers;
}
- public override string PrepareForBuild(BuildOptions options, BuildTarget target)
+ public override string PrepareForBuild(BuildPlayerOptions buildOptions)
{
- var namedBuildTarget = NamedBuildTarget.FromActiveSettings(target);
+ var namedBuildTarget = NamedBuildTarget.FromActiveSettings(buildOptions.target);
var isServer = namedBuildTarget == NamedBuildTarget.Server;
switch (PlayerSettings.GetScriptingBackend(namedBuildTarget))
@@ -96,7 +97,7 @@ public override string PrepareForBuild(BuildOptions options, BuildTarget target)
return $"Unknown scripting backend: {PlayerSettings.GetScriptingBackend(namedBuildTarget)}";
}
- return base.PrepareForBuild(options, target);
+ return base.PrepareForBuild(buildOptions);
}
internal class ScriptingImplementations : DefaultScriptingImplementations
diff --git a/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs b/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs
index 46b8d4f9e5..a860e27b47 100644
--- a/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs
+++ b/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs
@@ -458,6 +458,54 @@ internal static string GetExePath(string toolName)
return $"{deployDirectory}/{expectedToolExecutableName}";
}
+ internal static string GetLibrarySearchPaths(string name, string tfm, string customRoot = null)
+ {
+ var il2CppFolder = GetIl2CppFolder(out var isDevelopmentLocation);
+ var expectedToolExecutableName = $"{name}.dll";
+
+ if (isDevelopmentLocation)
+ {
+ // Locating the correct development build to use is a little tricky. Complications come from
+ // 1) We don't know if the Debug or Release build is desired. To overcome this we will pick whichever was modified most recently
+
+ var topLevel = il2CppFolder;
+ if (customRoot != null)
+ topLevel = Path.Combine(topLevel, customRoot);
+
+ var toolBinDirectory = Path.Combine(topLevel, name, "bin").ToNPath();
+ var candidates = toolBinDirectory.Files($"*{expectedToolExecutableName}", recurse: true)
+ .Where(f => f.Parent.FileName == tfm)
+ .OrderByDescending(f => f.GetLastWriteTimeUtc())
+ .ToArray();
+
+ if (candidates.Length == 0)
+ throw new InvalidOperationException($"{name} does not appear to be built in {il2CppFolder}");
+
+ return candidates[0].Parent.ToString();
+ }
+
+ throw new ArgumentException($"Could not locate assembly for {name}");
+ }
+
+ internal static string ConstructBeeLibrarySearchPath()
+ {
+ var projectBinDirs = new[]
+ {
+ GetLibrarySearchPaths("Unity.Options", "netstandard2.0", "repos/UnityOptions"),
+ GetLibrarySearchPaths("Unity.Linker.Api", "netstandard2.0"),
+ GetLibrarySearchPaths("Unity.IL2CPP.Api", "netstandard2.0"),
+ GetLibrarySearchPaths("Unity.Api.Attributes", "netstandard2.0"),
+ GetLibrarySearchPaths("Unity.IL2CPP.Bee.IL2CPPExeCompileCppBuildProgram.Data", "netstandard2.0"),
+ GetLibrarySearchPaths("Unity.IL2CPP.Bee.BuildLogic", "net6.0"),
+ // Now the quirky part. We need to locate the platform build logic assemblies.
+ // While il2cpp will have these during some build scenarios (IDE build or build.pl)
+ // the project that will always have all of the is il2cpp-compile
+ GetExePath("il2cpp-compile").ToNPath().Parent
+ };
+
+ return projectBinDirs.Aggregate(string.Empty, (accum, next) => $"{accum}{Path.PathSeparator}{next}");
+ }
+
internal static string GetAdditionalArguments()
{
var arguments = new List();
diff --git a/Editor/Mono/BuildPipeline/NamedBuildTarget.cs b/Editor/Mono/BuildPipeline/NamedBuildTarget.cs
index 85fec0e406..5d6e08be5e 100644
--- a/Editor/Mono/BuildPipeline/NamedBuildTarget.cs
+++ b/Editor/Mono/BuildPipeline/NamedBuildTarget.cs
@@ -41,9 +41,11 @@ namespace UnityEditor.Build
public static readonly NamedBuildTarget WebGL = new NamedBuildTarget("WebGL");
public static readonly NamedBuildTarget WindowsStoreApps = new NamedBuildTarget("Windows Store Apps");
public static readonly NamedBuildTarget PS4 = new NamedBuildTarget("PS4");
+ public static readonly NamedBuildTarget PS5 = new NamedBuildTarget("PS5");
public static readonly NamedBuildTarget XboxOne = new NamedBuildTarget("XboxOne");
public static readonly NamedBuildTarget tvOS = new NamedBuildTarget("tvOS");
public static readonly NamedBuildTarget NintendoSwitch = new NamedBuildTarget("Nintendo Switch");
+ [System.Obsolete("Stadia has been removed in 2023.1")]
public static readonly NamedBuildTarget Stadia = new NamedBuildTarget("Stadia");
public static readonly NamedBuildTarget LinuxHeadlessSimulation = new NamedBuildTarget("LinuxHeadlessSimulation");
[System.Obsolete("CloudRendering is deprecated, please use LinuxHeadlessSimulation (UnityUpgradable) -> LinuxHeadlessSimulation", false)]
@@ -98,8 +100,6 @@ public static NamedBuildTarget FromBuildTargetGroup(BuildTargetGroup buildTarget
return NamedBuildTarget.tvOS;
case BuildTargetGroup.Switch:
return NamedBuildTarget.NintendoSwitch;
- case BuildTargetGroup.Stadia:
- return NamedBuildTarget.Stadia;
case BuildTargetGroup.LinuxHeadlessSimulation:
return NamedBuildTarget.LinuxHeadlessSimulation;
case BuildTargetGroup.EmbeddedLinux:
diff --git a/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs b/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs
index 697ad5a5f4..f8ce4c306c 100644
--- a/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs
+++ b/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs
@@ -82,12 +82,12 @@ internal static string GetStreamingAssetsBundleManifestPath()
}
[RequiredByNativeCode]
- static public string PrepareForBuild(BuildOptions options, BuildTargetGroup targetGroup, BuildTarget target)
+ static public string PrepareForBuild(BuildPlayerOptions buildOptions)
{
- var postprocessor = ModuleManager.GetBuildPostProcessor(targetGroup, target);
+ var postprocessor = ModuleManager.GetBuildPostProcessor(buildOptions.targetGroup, buildOptions.target);
if (postprocessor == null)
return null;
- return postprocessor.PrepareForBuild(options, target);
+ return postprocessor.PrepareForBuild(buildOptions);
}
static public string GetExtensionForBuildTarget(BuildTargetGroup targetGroup, BuildTarget target, int subtarget, BuildOptions options)
@@ -284,7 +284,10 @@ static public void Postprocess(BuildTargetGroup targetGroup, BuildTarget target,
// Rethrow exceptions during build postprocessing as BuildFailedException, so we don't pretend the build was fine.
throw new BuildFailedException(e);
}
- report.AddAppendix(props);
+ if (props != null)
+ {
+ report.AddAppendix(props);
+ }
return;
}
diff --git a/Editor/Mono/BuildPlayerSceneTreeView.cs b/Editor/Mono/BuildPlayerSceneTreeView.cs
index c2aacb8a9c..115c8792d7 100644
--- a/Editor/Mono/BuildPlayerSceneTreeView.cs
+++ b/Editor/Mono/BuildPlayerSceneTreeView.cs
@@ -13,21 +13,22 @@ internal class BuildPlayerSceneTreeViewItem : TreeViewItem
{
private const string kAssetsFolder = "Assets/";
private const string kSceneExtension = ".unity";
-
public static int kInvalidCounter = -1;
+ private string m_FullName;
+
public bool active;
public int counter;
- public string fullName;
- public GUID guid;
- public void UpdateName()
+ public string fullName
{
- var name = AssetDatabase.GUIDToAssetPath(guid.ToString());
- if (name != fullName)
+ get => m_FullName;
+ set
{
- fullName = name;
+ if (m_FullName == value)
+ return;
- displayName = fullName;
+ m_FullName = value;
+ displayName = m_FullName;
if (displayName.StartsWith(kAssetsFolder))
displayName = displayName.Remove(0, kAssetsFolder.Length);
var ext = displayName.LastIndexOf(kSceneExtension);
@@ -35,13 +36,21 @@ public void UpdateName()
displayName = displayName.Substring(0, ext);
}
}
+ public GUID guid;
+
+ public void UpdateName()
+ {
+ var name = AssetDatabase.GUIDToAssetPath(guid.ToString());
+ if (!string.IsNullOrEmpty(name) && name != fullName)
+ fullName = name;
+ }
- public BuildPlayerSceneTreeViewItem(int id, int depth, GUID g, bool state) : base(id, depth)
+ public BuildPlayerSceneTreeViewItem(EditorBuildSettingsScene scene) : base(scene.guid.GetHashCode(), 0)
{
- active = state;
+ active = scene.enabled;
counter = kInvalidCounter;
- guid = g;
- fullName = "";
+ guid = scene.guid;
+ fullName = scene.path;
UpdateName();
}
}
@@ -71,7 +80,7 @@ protected override TreeViewItem BuildRoot()
List scenes = new List(EditorBuildSettings.scenes);
foreach (var sc in scenes)
{
- var item = new BuildPlayerSceneTreeViewItem(sc.guid.GetHashCode(), 0, sc.guid, sc.enabled);
+ var item = new BuildPlayerSceneTreeViewItem(sc);
root.AddChild(item);
}
return root;
@@ -314,6 +323,11 @@ public EditorBuildSettingsScene[] GetSceneList()
{
var sceneItem = rootItem.children[index] as BuildPlayerSceneTreeViewItem;
sceneList[index] = new EditorBuildSettingsScene(sceneItem.fullName, sceneItem.active);
+
+ // If the scene was deleted AssetPathToGUID may not work and the guid will be lost
+ // In that case restore it to the previous value
+ if (sceneList[index].guid.Empty() && !sceneItem.guid.Empty())
+ sceneList[index].guid = sceneItem.guid;
}
return sceneList;
}
diff --git a/Editor/Mono/BuildPlayerWindow.cs b/Editor/Mono/BuildPlayerWindow.cs
index 49a8f1b160..4788522ffa 100644
--- a/Editor/Mono/BuildPlayerWindow.cs
+++ b/Editor/Mono/BuildPlayerWindow.cs
@@ -47,6 +47,7 @@ class Styles
public string noModuleLoaded = L10n.Tr("No {0} module loaded.");
public GUIContent openDownloadPage = EditorGUIUtility.TrTextContent("Open Download Page");
public GUIContent installModuleWithHub = EditorGUIUtility.TrTextContent("Install with Unity Hub");
+ public string EditorWillNeedToBeReloaded = L10n.Tr("Note: Editor will need to be restarted to load any newly installed modules");
public string infoText = L10n.Tr("{0} is not included in your Unity Pro license. Your {0} build will include a Unity Personal Edition splash screen.\n\nYou must be eligible to use Unity Personal Edition to use this build option. Please refer to our EULA for further information.");
public GUIContent eula = EditorGUIUtility.TrTextContent("Eula");
public string addToYourPro = L10n.Tr("Add {0} to your Unity Pro license");
@@ -76,7 +77,7 @@ public GUIContent GetDownloadErrorForTarget(BuildTarget target)
public GUIContent explicitNullChecks = EditorGUIUtility.TrTextContent("Explicit Null Checks");
public GUIContent explicitDivideByZeroChecks = EditorGUIUtility.TrTextContent("Divide By Zero Checks");
public GUIContent explicitArrayBoundsChecks = EditorGUIUtility.TrTextContent("Array Bounds Checks");
- public GUIContent learnAboutUnityCloudBuild = EditorGUIUtility.TrTextContent("Learn about Unity Cloud Build");
+ public GUIContent learnAboutUnityCloudBuild = EditorGUIUtility.TrTextContent("Learn about Unity Build Automation");
public GUIContent compressionMethod = EditorGUIUtility.TrTextContent("Compression Method", "Compression applied to Player data (scenes and resources).\nDefault - none or default platform compression.\nLZ4 - fast compression suitable for Development Builds.\nLZ4HC - higher compression rate variance of LZ4, causes longer build times. Works best for Release Builds.");
public readonly GUIContent assetImportOverrides = EditorGUIUtility.TrTextContent("Asset Import Overrides", "Asset import overrides for local development. Reducing maximum texture size or compression settings can speed up asset imports and platform switches.");
@@ -239,6 +240,10 @@ void AddOpenScenes()
for (int i = 0; i < SceneManager.sceneCount; i++)
{
Scene scene = SceneManager.GetSceneAt(i);
+
+ if (EditorSceneManager.IsAuthoringScene(scene))
+ continue;
+
if (scene.path.Length == 0 && !EditorSceneManager.SaveScene(scene, "", false))
continue;
@@ -542,73 +547,6 @@ static bool IsAnyStandaloneModuleLoaded()
ModuleManager.IsPlatformSupportLoadedByBuildTarget(BuildTarget.StandaloneWindows);
}
- static bool IsColorSpaceValid(BuildPlatform platform)
- {
- if (PlayerSettings.colorSpace == ColorSpace.Linear)
- {
- var hasMinGraphicsAPI = true;
-
- var apis = PlayerSettings.GetGraphicsAPIs(platform.defaultTarget);
- if (platform.namedBuildTarget == NamedBuildTarget.Android)
- {
- hasMinGraphicsAPI = (apis.Contains(GraphicsDeviceType.Vulkan) || apis.Contains(GraphicsDeviceType.OpenGLES3)) && !apis.Contains(GraphicsDeviceType.OpenGLES2);
- }
- else if (platform.namedBuildTarget == NamedBuildTarget.iOS || platform.namedBuildTarget == NamedBuildTarget.tvOS)
- {
- hasMinGraphicsAPI = !apis.Contains(GraphicsDeviceType.OpenGLES3) && !apis.Contains(GraphicsDeviceType.OpenGLES2);
- }
- else if (platform.namedBuildTarget == NamedBuildTarget.WebGL)
- {
- // must have OpenGLES3-only
- hasMinGraphicsAPI = apis.Contains(GraphicsDeviceType.OpenGLES3) && !apis.Contains(GraphicsDeviceType.OpenGLES2);
- }
-
- return hasMinGraphicsAPI;
- }
- else
- {
- return true;
- }
- }
-
- static bool IsHDRCubemapEncodingValid(BuildPlatform platform)
- {
- var encoding = PlayerSettings.GetHDRCubemapEncodingQualityForPlatformGroup(platform.namedBuildTarget.ToBuildTargetGroup());
- return IsGITextureEncodingValid(platform, encoding == HDRCubemapEncodingQuality.Low);
- }
-
- static bool IsLightmapEncodingValid(BuildPlatform platform)
- {
- var encoding = PlayerSettings.GetLightmapEncodingQualityForPlatformGroup(platform.namedBuildTarget.ToBuildTargetGroup());
- return IsGITextureEncodingValid(platform, encoding == LightmapEncodingQuality.Low);
- }
-
- static bool IsGITextureEncodingValid(BuildPlatform platform, bool isLowQuality)
- {
- if (isLowQuality)
- return true;
-
- var hasMinGraphicsAPI = true;
-
- if (platform.namedBuildTarget == NamedBuildTarget.iOS)
- {
- var apis = PlayerSettings.GetGraphicsAPIs(BuildTarget.iOS);
- hasMinGraphicsAPI = apis.Contains(GraphicsDeviceType.Metal) && !apis.Contains(GraphicsDeviceType.OpenGLES3) && !apis.Contains(GraphicsDeviceType.OpenGLES2);
- }
- else if (platform.namedBuildTarget == NamedBuildTarget.tvOS)
- {
- var apis = PlayerSettings.GetGraphicsAPIs(BuildTarget.tvOS);
- hasMinGraphicsAPI = apis.Contains(GraphicsDeviceType.Metal) && !apis.Contains(GraphicsDeviceType.OpenGLES3) && !apis.Contains(GraphicsDeviceType.OpenGLES2);
- }
- else if (platform.namedBuildTarget == NamedBuildTarget.Android)
- {
- var apis = PlayerSettings.GetGraphicsAPIs(BuildTarget.Android);
- hasMinGraphicsAPI = (apis.Contains(GraphicsDeviceType.Vulkan) || apis.Contains(GraphicsDeviceType.OpenGLES3)) && !apis.Contains(GraphicsDeviceType.OpenGLES2);
- }
-
- return hasMinGraphicsAPI;
- }
-
static bool IsVirtualTexturingSettingsValid(BuildPlatform platform)
{
if (!PlayerSettings.GetVirtualTexturingSupportEnabled())
@@ -798,6 +736,7 @@ void ShowBuildTargetSettings()
Help.BrowseURL(url);
}
}
+ GUILayout.Label(styles.EditorWillNeedToBeReloaded, EditorStyles.wordWrappedMiniLabel);
GUIBuildButtons(false, false, false, platform, postprocessor);
return;
}
@@ -1070,25 +1009,7 @@ private static void GUIBuildButtons(IBuildWindowExtension buildWindowExtension,
// Disable the 'Build' and 'Build And Run' buttons when the project setup doesn't satisfy the platform requirements
if (enableBuildButton && enableBuildAndRunButton)
{
- if (!IsColorSpaceValid(platform))
- {
- enableBuildAndRunButton = false;
- enableBuildButton = false;
- EditorGUILayout.HelpBox(styles.invalidColorSpaceMessage);
- }
- else if (!IsLightmapEncodingValid(platform))
- {
- enableBuildAndRunButton = false;
- enableBuildButton = false;
- EditorGUILayout.HelpBox(styles.invalidLightmapEncodingMessage);
- }
- else if (!IsHDRCubemapEncodingValid(platform))
- {
- enableBuildAndRunButton = false;
- enableBuildButton = false;
- EditorGUILayout.HelpBox(styles.invalidHDRCubemapEncodingMessage);
- }
- else if (!IsVirtualTexturingSettingsValid(platform))
+ if (!IsVirtualTexturingSettingsValid(platform))
{
enableBuildAndRunButton = false;
enableBuildButton = false;
diff --git a/Editor/Mono/BuildPlayerWindowBuildMethods.cs b/Editor/Mono/BuildPlayerWindowBuildMethods.cs
index 3c93a95af5..7f78736505 100644
--- a/Editor/Mono/BuildPlayerWindowBuildMethods.cs
+++ b/Editor/Mono/BuildPlayerWindowBuildMethods.cs
@@ -9,6 +9,7 @@
using System.Collections;
using System.IO;
using System;
+using System.Linq;
using UnityEditor.Build.Reporting;
using UnityEditor.Connect;
using UnityEditor.Profiling;
@@ -313,7 +314,7 @@ internal static BuildPlayerOptions GetBuildPlayerOptionsInternal(bool askForBuil
EditorBuildSettingsScene[] editorScenes = EditorBuildSettings.scenes;
foreach (EditorBuildSettingsScene scene in editorScenes)
{
- if (scene.enabled)
+ if (scene.enabled && !string.IsNullOrEmpty(scene.path))
scenesList.Add(scene.path);
}
@@ -359,10 +360,26 @@ private static bool PickBuildLocation(BuildTargetGroup targetGroup, BuildTarget
}
string title = "Build " + BuildPlatforms.instance.GetBuildTargetDisplayName(targetGroup, target, subtarget);
- string path = EditorUtility.SaveBuildPanel(target, title, defaultFolder, defaultName, extension, out updateExistingBuild);
- if (path == string.Empty)
- return false;
+ string path;
+ bool isValidPath = false;
+ do
+ {
+ path = EditorUtility.SaveBuildPanel(target, title, defaultFolder, defaultName, extension, out updateExistingBuild);
+ if (path == string.Empty)
+ return false;
+
+ if (IsBuildPathValid(path, out var msg))
+ {
+ isValidPath = true;
+ }
+ else if (!EditorUtility.DisplayDialog("Invalid build path", msg, "Ok", "Cancel"))
+ {
+ Debug.LogError($"Invalid build path: '{path}'. {msg}");
+ return false;
+ }
+
+ } while (!isValidPath);
if (isWindowsStandalone)
{
@@ -370,9 +387,6 @@ private static bool PickBuildLocation(BuildTargetGroup targetGroup, BuildTarget
path = Path.Combine(path, Paths.MakeValidFileName(PlayerSettings.productName) + '.' + extension);
}
- if (!IsBuildPathValid(path))
- return false;
-
// Enforce extension if needed
if (extension != string.Empty && FileUtil.GetPathExtension(path).ToLower() != extension)
path += '.' + extension;
@@ -413,14 +427,14 @@ private static string NormalizePath(string path)
fullPath = string.IsNullOrEmpty(fullPath) ? string.Empty : Path.GetFullPath(fullPath);
- fullPath = fullPath.ToLower();
if (Path.DirectorySeparatorChar == '/')
return fullPath;
return fullPath.Replace(Path.DirectorySeparatorChar, '/');
}
- internal static bool IsBuildPathValid(string path)
+ internal static bool IsBuildPathValid(string path, out string errorMessage)
{
+ errorMessage = default;
var cleanedPath = NormalizePath(path);
if (cleanedPath.Equals(string.Empty) &&
IsInstallInBuildFolderOption())
@@ -428,22 +442,37 @@ internal static bool IsBuildPathValid(string path)
var basePath = NormalizePath(Application.dataPath + "/../");
- var assetsPath = NormalizePath(basePath + "/Assets");
- var settingsPath = NormalizePath(basePath + "/ProjectSettings");
- var tempPath = NormalizePath(basePath + "/Temp");
- var libraryPath = NormalizePath(basePath + "/Library");
- var userSettingsPath = NormalizePath(basePath + "/UserSettings");
- var userDesktopPath = NormalizePath(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
+ // Allow build into the Temp folder (used by Unity TestRunner)
+ var invalidPaths = new[]
+ {
+ NormalizePath(basePath + "/Assets"),
+ NormalizePath(basePath + "/ProjectSettings"),
+ NormalizePath(basePath + "/Library"),
+ NormalizePath(basePath + "/Packages"),
+ NormalizePath(basePath + "/UserSettings")
+ };
+
+ var invalidPath = invalidPaths.FirstOrDefault(p => cleanedPath.Contains(p, StringComparison.OrdinalIgnoreCase));
+ if (!string.IsNullOrEmpty(invalidPath))
+ {
+ var dirName = Path.GetFileName(invalidPath);
+ errorMessage = $"The '{dirName}' directory is an internal work directory of Unity and " +
+ "projects should not be built inside it. Please choose another directory for the build output.";
+ return false;
+ }
- if (basePath.Contains(cleanedPath) ||
- cleanedPath == assetsPath ||
- cleanedPath == settingsPath ||
- cleanedPath == tempPath ||
- cleanedPath == libraryPath ||
- cleanedPath == userSettingsPath ||
- cleanedPath == userDesktopPath)
+ if (cleanedPath.Equals(basePath, StringComparison.OrdinalIgnoreCase))
+ {
+ errorMessage = "The project root directory should not be used as a build output directory. " +
+ "Please create a subdirectory for the build output.";
+ return false;
+ }
+
+ var userDesktopPath = NormalizePath(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
+ if (cleanedPath.Equals(userDesktopPath, StringComparison.OrdinalIgnoreCase))
{
- Debug.LogError("Invalid build path: " + cleanedPath);
+ errorMessage = "The desktop directory should not be used as a build output directory. " +
+ "Please create a subdirectory for the build output.";
return false;
}
diff --git a/Editor/Mono/BuildTarget.cs b/Editor/Mono/BuildTarget.cs
index c54218c403..eed1434c7e 100644
--- a/Editor/Mono/BuildTarget.cs
+++ b/Editor/Mono/BuildTarget.cs
@@ -121,6 +121,7 @@ public enum BuildTarget
[System.Obsolete("Lumin has been removed in 2022.2")]
Lumin = 39,
+ [System.Obsolete("Stadia has been removed in 2023.1")]
Stadia = 40,
[System.Obsolete("CloudRendering is deprecated, please use LinuxHeadlessSimulation (UnityUpgradable) -> LinuxHeadlessSimulation", false)]
diff --git a/Editor/Mono/BuildTargetConverter.cs b/Editor/Mono/BuildTargetConverter.cs
index 1b71ce181e..7f32bd4a99 100644
--- a/Editor/Mono/BuildTargetConverter.cs
+++ b/Editor/Mono/BuildTargetConverter.cs
@@ -46,8 +46,6 @@ internal static class BuildTargetConverter
return RuntimePlatform.GameCoreXboxSeries;
case BuildTarget.GameCoreXboxOne:
return RuntimePlatform.GameCoreXboxOne;
- case BuildTarget.Stadia:
- return RuntimePlatform.Stadia;
case BuildTarget.EmbeddedLinux:
return RuntimePlatform.EmbeddedLinuxArm64;
case BuildTarget.QNX:
diff --git a/Editor/Mono/BuildTargetGroup.cs b/Editor/Mono/BuildTargetGroup.cs
index ccd4e6699c..6466bd45f0 100644
--- a/Editor/Mono/BuildTargetGroup.cs
+++ b/Editor/Mono/BuildTargetGroup.cs
@@ -98,6 +98,7 @@ public enum BuildTargetGroup
[Obsolete("Lumin has been removed in 2022.2")]
Lumin = 28,
+ [Obsolete("Stadia has been removed in 2023.1")]
Stadia = 29,
[System.Obsolete("CloudRendering is deprecated, please use LinuxHeadlessSimulation (UnityUpgradable) -> LinuxHeadlessSimulation", false)]
diff --git a/Editor/Mono/Clipboard/Clipboard.cs b/Editor/Mono/Clipboard/Clipboard.cs
index 85cd6d777a..7d9a17970f 100644
--- a/Editor/Mono/Clipboard/Clipboard.cs
+++ b/Editor/Mono/Clipboard/Clipboard.cs
@@ -18,6 +18,72 @@ internal static class Clipboard
{
static ClipboardState m_State = new ClipboardState();
+ public static bool hasLong
+ {
+ get
+ {
+ FetchState();
+ m_State.FetchLong();
+ return m_State.m_HasLong.Value;
+ }
+ }
+
+ public static long longValue
+ {
+ get
+ {
+ FetchState();
+ m_State.FetchLong();
+ return m_State.m_ValueLong;
+ }
+
+ set => EditorGUIUtility.systemCopyBuffer = value.ToString();
+ }
+
+ public static bool hasUlong
+ {
+ get
+ {
+ FetchState();
+ m_State.FetchUlong();
+ return m_State.m_HasUlong.Value;
+ }
+ }
+
+ public static ulong uLongValue
+ {
+ get
+ {
+ FetchState();
+ m_State.FetchUlong();
+ return m_State.m_ValueUlong;
+ }
+
+ set => EditorGUIUtility.systemCopyBuffer = value.ToString();
+ }
+
+ public static bool hasUint
+ {
+ get
+ {
+ FetchState();
+ m_State.FetchUint();
+ return m_State.m_HasUint.Value;
+ }
+ }
+
+ public static uint uIntValue
+ {
+ get
+ {
+ FetchState();
+ m_State.FetchUint();
+ return m_State.m_ValueUint;
+ }
+
+ set => EditorGUIUtility.systemCopyBuffer = value.ToString();
+ }
+
public static bool hasInteger
{
get
diff --git a/Editor/Mono/Clipboard/ClipboardContextMenu.cs b/Editor/Mono/Clipboard/ClipboardContextMenu.cs
index b0d30b69e5..649a46d0cb 100644
--- a/Editor/Mono/Clipboard/ClipboardContextMenu.cs
+++ b/Editor/Mono/Clipboard/ClipboardContextMenu.cs
@@ -164,10 +164,64 @@ internal static void SetupPropertyCopyPaste(SerializedProperty property, Generic
}
break;
case SerializedPropertyType.Integer:
- SetupAction(property, menu, evt,
- p => Clipboard.integerValue = p.intValue,
- p => Clipboard.hasInteger,
- p => p.intValue = Clipboard.integerValue);
+ {
+ switch (property.numericType)
+ {
+ case SerializedPropertyNumericType.Int64:
+ SetupAction(property, menu, evt,
+ p => Clipboard.longValue = p.longValue,
+ p => Clipboard.hasLong,
+ p => p.longValue = Clipboard.longValue);
+ break;
+
+ case SerializedPropertyNumericType.UInt64:
+ SetupAction(property, menu, evt,
+ p => Clipboard.uLongValue = p.ulongValue,
+ p => Clipboard.hasUlong,
+ p => p.ulongValue = Clipboard.uLongValue);
+ break;
+
+ case SerializedPropertyNumericType.UInt32:
+ SetupAction(property, menu, evt,
+ p => Clipboard.uIntValue = p.uintValue,
+ p => Clipboard.hasUint,
+ p => p.uintValue = Clipboard.uIntValue);
+ break;
+
+ case SerializedPropertyNumericType.UInt16:
+ SetupAction(property, menu, evt,
+ p => Clipboard.uIntValue = (System.UInt16)p.uintValue,
+ p => Clipboard.hasUint,
+ p => p.uintValue = (System.UInt16)Clipboard.uIntValue);
+ break;
+
+ case SerializedPropertyNumericType.Int16:
+ SetupAction(property, menu, evt,
+ p => Clipboard.integerValue = (System.Int16)p.intValue,
+ p => Clipboard.hasInteger,
+ p => p.intValue = (System.UInt16)Clipboard.integerValue);
+ break;
+ case SerializedPropertyNumericType.UInt8:
+ SetupAction(property, menu, evt,
+ p => Clipboard.uIntValue = (System.Byte)p.uintValue,
+ p => Clipboard.hasUint,
+ p => p.uintValue = (System.Byte)Clipboard.uIntValue);
+ break;
+ case SerializedPropertyNumericType.Int8:
+ SetupAction(property, menu, evt,
+ p => Clipboard.integerValue = (System.Byte)p.intValue,
+ p => Clipboard.hasInteger,
+ p => p.intValue = (System.Byte)Clipboard.integerValue);
+ break;
+
+ default:
+ SetupAction(property, menu, evt,
+ p => Clipboard.integerValue = p.intValue,
+ p => Clipboard.hasInteger,
+ p => p.intValue = Clipboard.integerValue);
+ break;
+ }
+ }
break;
case SerializedPropertyType.Float:
SetupAction(property, menu, evt,
diff --git a/Editor/Mono/Clipboard/ClipboardParser.cs b/Editor/Mono/Clipboard/ClipboardParser.cs
index e3c9134e83..56ca046e64 100644
--- a/Editor/Mono/Clipboard/ClipboardParser.cs
+++ b/Editor/Mono/Clipboard/ClipboardParser.cs
@@ -187,6 +187,30 @@ public static bool ParseQuaternion(string text, out Quaternion res)
return int.TryParse(text, out res);
}
+ internal static bool? ParseLong(string text, out long res)
+ {
+ res = 0;
+ if (string.IsNullOrEmpty(text))
+ return false;
+ return long.TryParse(text, out res);
+ }
+
+ internal static bool? ParseUlong(string text, out ulong res)
+ {
+ res = 0;
+ if (string.IsNullOrEmpty(text))
+ return false;
+ return ulong.TryParse(text, out res);
+ }
+
+ internal static bool? ParseUint(string text, out uint res)
+ {
+ res = 0;
+ if(string.IsNullOrEmpty(text))
+ return false;
+ return uint.TryParse(text, out res);
+ }
+
internal static bool? ParseFloat(string text, out float res)
{
res = 0;
diff --git a/Editor/Mono/Clipboard/ClipboardState.cs b/Editor/Mono/Clipboard/ClipboardState.cs
index b55d4cd7a0..45d13f5463 100644
--- a/Editor/Mono/Clipboard/ClipboardState.cs
+++ b/Editor/Mono/Clipboard/ClipboardState.cs
@@ -167,6 +167,33 @@ internal void FetchInteger()
m_HasInteger = ClipboardParser.ParseInteger(m_RawContents, out m_ValueInteger);
}
+ internal bool? m_HasLong;
+ internal long m_ValueLong;
+
+ internal void FetchLong()
+ {
+ if (!m_HasLong.HasValue)
+ m_HasLong = ClipboardParser.ParseLong(m_RawContents, out m_ValueLong);
+ }
+
+ internal bool? m_HasUlong;
+ internal ulong m_ValueUlong;
+
+ internal void FetchUlong()
+ {
+ if (!m_HasUlong.HasValue)
+ m_HasUlong = ClipboardParser.ParseUlong(m_RawContents, out m_ValueUlong);
+ }
+
+ internal bool? m_HasUint;
+ internal uint m_ValueUint;
+
+ internal void FetchUint()
+ {
+ if (!m_HasUint.HasValue)
+ m_HasUint = ClipboardParser.ParseUint(m_RawContents, out m_ValueUint);
+ }
+
internal bool? m_HasFloat;
internal float m_ValueFloat;
internal void FetchFloat()
diff --git a/Editor/Mono/Collab/CloudBuildStatus.cs b/Editor/Mono/Collab/CloudBuildStatus.cs
deleted file mode 100644
index 6a88be7158..0000000000
--- a/Editor/Mono/Collab/CloudBuildStatus.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System;
-using System.Runtime.InteropServices;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- // Keep internal and undocumented until we expose more functionality
- //*undocumented
- [StructLayout(LayoutKind.Sequential)]
- [UsedByNativeCode]
- internal struct CloudBuildStatus
- {
- private string m_Platform;
- private bool m_Complete;
- private bool m_Successful;
-
- internal CloudBuildStatus(string platform = "", bool complete = false, bool success = false)
- {
- m_Platform = platform;
- m_Complete = complete;
- m_Successful = success;
- }
-
- public string platform { get { return m_Platform; } }
- public bool complete { get { return m_Complete; } }
- public bool success { get { return m_Successful; } }
- }
-}
diff --git a/Editor/Mono/Collab/Collab.bindings.cs b/Editor/Mono/Collab/Collab.bindings.cs
deleted file mode 100644
index be25871f3b..0000000000
--- a/Editor/Mono/Collab/Collab.bindings.cs
+++ /dev/null
@@ -1,290 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using UnityEditor.Connect;
-using UnityEngine;
-using UnityEngine.Bindings;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- [NativeHeader("Editor/Src/Collab/CollabInfo.h")]
- [StructLayout(LayoutKind.Sequential)]
- internal struct CollabInfo
- {
- public bool ready { get { return m_Ready; } }
- public bool update { get { return m_Update; } }
- public bool publish { get { return m_Publish; } }
- public bool inProgress { get { return m_InProgress; } }
- public bool maintenance { get { return m_Maintenance; } }
- public bool conflict { get { return m_Conflict; } }
- public bool refresh { get { return m_Refresh; } }
- public bool seat { get { return m_HasSeat; } }
- public string tip { get { return m_Tip; } }
-
- public bool Equals(CollabInfo other)
- {
- return m_Update == other.m_Update &&
- m_Publish == other.m_Publish &&
- m_InProgress == other.m_InProgress &&
- m_Maintenance == other.m_Maintenance &&
- m_Conflict == other.m_Conflict &&
- m_Refresh == other.m_Refresh &&
- m_HasSeat == other.m_HasSeat &&
- m_Ready == other.m_Ready &&
- string.Equals(m_Tip, other.m_Tip);
- }
-
- bool m_Update;
- bool m_Publish;
- bool m_InProgress;
- bool m_Maintenance;
- bool m_Conflict;
- bool m_Refresh;
- bool m_HasSeat;
- bool m_Ready;
- string m_Tip;
- }
-
- [NativeHeader("Editor/Src/Collab/Collab.h")]
- [NativeHeader("Editor/Src/Collab/Collab.bindings.h")]
- [StructLayout(LayoutKind.Sequential)]
- [StaticAccessor("Collab::Get()", StaticAccessorType.Arrow)]
- partial class Collab
- {
- [NativeMethod("Get")]
- static extern IntPtr GetNativeCollab();
-
- public extern CollabInfo collabInfo { get; }
-
- public static extern int GetRevisionsData(
- bool withChanges, int startIndex, int numRevisions);
-
- public static extern int GetSingleRevisionData(bool withChanges, string id);
-
- public static extern RevisionsData PopulateRevisionsData(IntPtr nativeData);
- public static extern Revision PopulateSingleRevisionData(IntPtr nativeData);
-
- public extern void SetSeat(bool value);
-
- public extern void RefreshSeatAvailabilityAsync();
-
- public extern string GetProjectGUID();
-
- public extern bool ShouldDoInitialCommit();
-
- [NativeMethod("DiffFileWithBaseAsync")]
- public extern void ShowDifferences(string path);
-
- public extern void SendNotification();
-
- public extern void SetError(int errorCode);
-
- public extern void ClearError(int errorCode);
-
- public extern void ClearErrors();
-
- public extern void ForceRefresh(bool refreshAssetDatabase);
-
- public extern void SetCollabEnabledForCurrentProject(bool enabled);
-
- public extern bool IsCollabEnabledForCurrentProject();
-
- public extern bool IsAssetIgnored(string path);
-
- public extern bool ShouldTrackAsset(string path);
-
- [ThreadAndSerializationSafe]
- public extern string GetProjectPath();
-
- [ThreadAndSerializationSafe]
- public extern bool IsConnected();
-
- [ThreadAndSerializationSafe]
- public extern bool AnyJobRunning();
-
- [ThreadAndSerializationSafe]
- public extern bool JobRunning(int a_jobID);
-
- public extern CollabStates GetAssetState(string guid);
- public extern CollabStates GetSelectedAssetState();
- public extern CollabStateID GetCollabState();
-
- [FreeFunction(HasExplicitThis = true)]
- public extern bool ValidateSelectiveCommit();
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void Disconnect();
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void CancelJobByType(int jobType, bool forceCancel);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void DoInitialCommit();
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void Update(string revisionID, bool updateToRevision);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void RevertFile(string path, bool forceOverwrite);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void RevertFiles(ChangeItem[] changeItems, bool forceOverwrite);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void LaunchConflictExternalMerge(string path);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void ShowConflictDifferences(string path);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void ResyncSnapshot();
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void GoBackToRevision(string revisionID, bool updateToRevision);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void ResyncToRevision(string revisionID);
-
- [NativeMethod("GetConflictsManager().GetAllConflicts")]
- public extern Change[] GetCollabConflicts();
-
- // Conflict Management
- [NativeMethod("GetConflictsManager().CheckConflictsResolvedExternal")]
- public extern void CheckConflictsResolvedExternal();
-
- [NativeMethod("GetTestHelper().AreTestsRunning")]
- public extern bool AreTestsRunning();
-
- [NativeMethod("GetTestHelper().SetTestsRunning")]
- public extern void SetTestsRunning(bool running);
-
- [NativeMethod("GetTestHelper().ClearOperationsFailure")]
- public extern void ClearAllFailures();
-
- [NativeMethod("GetTestHelper().UnmarkOperationFailure")]
- public extern void ClearNextOperationFailure();
-
- [NativeMethod("GetTestHelper().UnmarkOperationFailureForFile")]
- public extern void ClearNextOperationFailureForFile(string path);
-
- [NativeMethod("GetTestHelper().GetGUIDForTests")]
- public extern string GetGUIDForTests();
-
- [NativeMethod("GetTestHelper().NewGUIDForTests")]
- public extern void NewGUIDForTests();
-
- [NativeMethod("GetTestHelper().MarkOperationFailure")]
- public extern void FailNextOperation(Collab.Operation operation, int code);
-
- [NativeMethod("GetTestHelper().MarkOperationTimeOut")]
- public extern void TimeOutNextOperation(Collab.Operation operation, int timeOutSec);
-
- [NativeMethod("GetTestHelper().MarkOperationFailureForFile")]
- public extern void FailNextOperationForFile(string path, Collab.Operation operation, int code);
-
- [NativeMethod("GetTestHelper().MarkOperationTimeOutForFile")]
- public extern void TimeOutNextOperationForFile(string path, Collab.Operation operation, int timeOutSec);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void TestPostSoftLockAsCollaborator(string projectGuid, string projectPath, string machineGuid,
- string assetGuid);
-
- [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
- public extern void TestClearSoftLockAsCollaborator(string projectGuid, string projectPath, string machineGuid,
- string softLockHash);
-
- // Private helper methods for bindings
- [NativeMethod("GetConflictsManager().SetConflictsState")]
- extern bool SetConflictsResolved(string[] paths, CollabStates state);
-
- [NativeMethod("OnAssetBundleNameChanged")]
- extern void OnPostprocessAssetbundleNameChanged(string assetPath, string previousAssetBundleName, string newAssetBundleName);
-
- [NativeMethod("GetError")]
- internal extern bool GetErrorInternal(int errorFilter, out UnityErrorInfo info);
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true)]
- extern Change[] GetChangesToPublishInternal();
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true)]
- extern ChangeItem[] GetChangeItemsToPublishInternal_V2();
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true, IsThreadSafe = true)]
- extern void SetChangesToPublishInternal(ChangeItem[] changes);
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true, IsThreadSafe = true)]
- extern Change[] GetSelectedChangesInternal();
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true, IsThreadSafe = true)]
- extern ChangeItem[] GetSelectedChangeItemsInternal_V2();
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true, IsThreadSafe = true)]
- extern void UpdateChangesToPublish();
-
- [NativeMethod(Name = "GetJobProgress", HasExplicitThis = true, ThrowsException = true)]
- extern bool GetJobProgressInternal([Out] ProgressInfo info, int jobId);
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true)]
- public extern void Publish(string comment, bool useSelectedAssets, bool confirmMatchesPrevious);
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true)]
- public extern void PublishAssetsAsync(string comment, ChangeItem[] changes);
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true, IsThreadSafe = true)]
- public extern void ClearSelectedChangesToPublish();
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true, IsThreadSafe = true)]
- public extern void SendCollabInfoNotification();
-
- [NativeMethod(HasExplicitThis = true, ThrowsException = true)]
- public extern SoftLock[] GetSoftLocks(string assetGuid);
- }
-
- // keep in sync with CollabSettingType in C++
- internal enum CollabSettingType
- {
- InProgressEnabled = 0,
- InProgressProjectEnabled = 1,
- InProgressGlobalEnabled = 2
- }
-
- // keep in sync with CollabSettingStatus in C++
- internal enum CollabSettingStatus
- {
- None = 0,
- Available = 1
- }
-
- [NativeHeader("Editor/Src/Collab/CollabSettingsManager.h")]
- [StaticAccessor("GetCollabSettingsManager()", StaticAccessorType.Dot)]
- internal class CollabSettingsManager
- {
- [RequiredByNativeCode]
- static void NotifyStatusListeners(CollabSettingType type, CollabSettingStatus status)
- {
- if (statusNotifier[type] != null)
- statusNotifier[type](type, status);
- }
-
- public delegate void SettingStatusChanged(CollabSettingType type, CollabSettingStatus status);
- public static Dictionary statusNotifier = new Dictionary();
-
- static CollabSettingsManager()
- {
- foreach (CollabSettingType type in Enum.GetValues(typeof(CollabSettingType)))
- statusNotifier[type] = null;
- }
-
- public static extern bool IsAvailable(CollabSettingType type);
-
- public static extern bool inProgressEnabled
- {
- get;
- }
- }
-}
diff --git a/Editor/Mono/Collab/Collab.cs b/Editor/Mono/Collab/Collab.cs
deleted file mode 100644
index 0056fbac88..0000000000
--- a/Editor/Mono/Collab/Collab.cs
+++ /dev/null
@@ -1,620 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.Scripting;
-using UnityEditor.Web;
-using UnityEditorInternal;
-using UnityEditor.Connect;
-using UnityEditor.SceneManagement;
-
-namespace UnityEditor.Collaboration
-{
- internal delegate void StateChangedDelegate(CollabInfo info);
- internal delegate void RevisionChangedDelegate(CollabInfo info, string rev, string action);
- internal delegate void SetErrorDelegate(UnityErrorInfo error);
- internal delegate void ErrorDelegate();
- internal delegate bool ShowToolbarAtPositionDelegate(Rect screenRect);
- internal delegate bool IsToolbarVisibleDelegate();
- internal delegate void ShowHistoryWindowDelegate();
- internal delegate void ShowChangesWindowDelegate();
- internal delegate void CloseToolbarDelegate();
- internal delegate void ChangesChangedDelegate(Change[] changes, bool isFiltered);
- internal delegate void ChangeItemsChangedDelegate(ChangeItem[] changes, bool isFiltered);
-
- //*undocumented
- // We want to raise this exception from Cpp code but it fails
- //public class CollabException: Exception
- //{
- // public CollabException(string message) : base(message)
- // {
- // }
- //}
-
- [InitializeOnLoad]
- internal partial class Collab
- {
- // Pointer to native Collab object used by automatic bindings system.
-#pragma warning disable 414 // The private field is assigned but its value is never used
- IntPtr m_nativeCollab = IntPtr.Zero;
-
- public event StateChangedDelegate StateChanged;
-
- public event StateChangedDelegate RevisionUpdated;
- public event RevisionChangedDelegate RevisionUpdated_V2;
-
- public event StateChangedDelegate JobsCompleted;
-
- public event ErrorDelegate ErrorOccurred;
- public event SetErrorDelegate ErrorOccurred_V2;
-
- public event ErrorDelegate ErrorCleared;
-
- public event ChangeItemsChangedDelegate ChangeItemsChanged;
- public event ChangeItemsChangedDelegate SelectedChangeItemsChanged;
- public event StateChangedDelegate CollabInfoChanged;
-
- // Toolbar delegates
- public static ShowToolbarAtPositionDelegate ShowToolbarAtPosition = null;
- public static IsToolbarVisibleDelegate IsToolbarVisible = null;
- public static CloseToolbarDelegate CloseToolbar = null;
-
- // Preferences link delegates
- public static ShowHistoryWindowDelegate ShowHistoryWindow = null;
- public static ShowChangesWindowDelegate ShowChangesWindow = null;
-
- private static Collab s_Instance;
- private static bool s_IsFirstStateChange = true;
-
- [SerializeField]
- public CollabFilters collabFilters = new CollabFilters();
-
- public String projectBrowserSingleSelectionPath { get; set; }
-
- public String projectBrowserSingleMetaSelectionPath { get; set; }
-
- public string[] currentProjectBrowserSelection;
-
- // Must keep in sync with C++ in CollabCommon.h
- [Flags]
- public enum Operation
- {
- Noop = 0,
- Publish = 1 << 0,
- Update = 1 << 1,
- Revert = 1 << 2,
- GoBack = 1 << 3,
- Restore = 1 << 4,
- Diff = 1 << 5,
- ConflictDiff = 1 << 6,
- Exclude = 1 << 7,
- Include = 1 << 8,
- ChooseMine = 1 << 9,
- ChooseTheirs = 1 << 10,
- ExternalMerge = 1 << 11,
- }
-
- // Must keep in sync with C++ in CollabCommon.h
- // Explicit uint so "Any" state works with C++
- [Flags]
- public enum CollabStates : uint
- {
- kCollabNone = 0,
- kCollabLocal = 1,
-
- kCollabSynced = 1 << 1,
- kCollabOutOfSync = 1 << 2,
- kCollabIgnored = 1 << 3,
- kCollabCheckedOutLocal = 1 << 4,
- kCollabCheckedOutRemote = 1 << 5,
- kCollabDeletedLocal = 1 << 6,
- kCollabDeletedRemote = 1 << 7,
- kCollabAddedLocal = 1 << 8,
- kCollabAddedRemote = 1 << 9,
- kCollabConflicted = 1 << 10,
- kCollabMovedLocal = 1 << 11,
- kCollabMovedRemote = 1 << 12,
- kCollabUpdating = 1 << 13,
- kCollabReadOnly = 1 << 14,
- kCollabMetaFile = 1 << 15,
- kCollabUseMine = 1 << 16,
- kCollabUseTheir = 1 << 17,
- kCollabMerged = 1 << 18,
- kCollabPendingMerge = 1 << 19,
- kCollabFolderMetaFile = 1 << 20,
- KCollabContentChanged = 1 << 21,
- KCollabContentConflicted = 1 << 22,
- KCollabContentDeleted = 1 << 23,
-
- // always keep most significant
- kCollabInvalidState = 1 << 30,
-
- kAnyLocalChanged = (kCollabAddedLocal | kCollabCheckedOutLocal | kCollabDeletedLocal | kCollabMovedLocal),
- kAnyLocalEdited = (kCollabAddedLocal | kCollabCheckedOutLocal | kCollabMovedLocal),
- kCollabAny = 0xFFFFFFFF
- }
-
- internal enum CollabStateID { None, Uninitialized, Initialized }
-
- public static string[] clientType =
- {
- "Cloud Server",
- "Mock Server"
- };
-
- internal static string editorPrefCollabClientType = "CollabConfig_Client";
-
- public static string GetProjectClientType()
- {
- var cvalue = EditorUserSettings.GetConfigValue(editorPrefCollabClientType);
- return string.IsNullOrEmpty(cvalue) ? clientType[0] : cvalue;
- }
-
- public static Collab instance
- {
- get
- {
- return s_Instance;
- }
- }
-
- // Instance of VersionControl interface implementation
- private static IVersionControl s_VersionControlInstance;
-
- public static void SetVersionControl(IVersionControl instance)
- {
- s_VersionControlInstance = instance;
- // Initialize version control based on whether collab is enabled
- if (s_Instance != null)
- {
- if (s_Instance.IsCollabEnabledForCurrentProject())
- {
- instance.OnEnableVersionControl();
- }
- else
- {
- instance.OnDisableVersionControl();
- }
- }
- }
-
- [UsedByNativeCode]
- internal static bool HasVersionControl()
- {
- return s_VersionControlInstance != null;
- }
-
- [UsedByNativeCode]
- internal static void ShowChangesWindowView()
- {
- if (ShowChangesWindow != null)
- {
- ShowChangesWindow();
- }
- }
-
- [UsedByNativeCode]
- static bool SupportsDownloads()
- {
- if (s_VersionControlInstance != null)
- {
- return s_VersionControlInstance.SupportsDownloads();
- }
- else
- {
- return false;
- }
- }
-
- [UsedByNativeCode]
- static bool OnEnableVersionControl()
- {
- if (s_VersionControlInstance != null)
- {
- return s_VersionControlInstance.OnEnableVersionControl();
- }
- else
- {
- return true;
- }
- }
-
- [UsedByNativeCode]
- static void OnDisableVersionControl()
- {
- if (s_VersionControlInstance != null)
- {
- s_VersionControlInstance.OnDisableVersionControl();
- }
- }
-
- [UsedByNativeCode]
- static ChangeItem[] GetChanges()
- {
- if (s_VersionControlInstance != null)
- {
- return s_VersionControlInstance.GetChanges();
- }
- else
- {
- return null;
- }
- }
-
- [UsedByNativeCode]
- static void MergeDownloadedFiles(bool isFullDownload)
- {
- if (s_VersionControlInstance != null)
- {
- s_VersionControlInstance.MergeDownloadedFiles(isFullDownload);
- }
- }
-
- [UsedByNativeCode]
- static bool SupportsAsyncChanges()
- {
- if (s_VersionControlInstance != null)
- {
- return s_VersionControlInstance.SupportsAsyncChanges();
- }
- else
- {
- return false;
- }
- }
-
- internal static CollabStates GetAssetState(string assetGuid, string assetPath)
- {
- if (s_VersionControlInstance != null)
- {
- return s_VersionControlInstance.GetAssetState(assetGuid, assetPath);
- }
- else
- {
- return instance.GetAssetState(assetGuid);
- }
- }
-
- public void RefreshAvailableLocalChangesSynchronous()
- {
- IVersionControl_V2 vc_v2 = s_VersionControlInstance as IVersionControl_V2;
-
- // If our VersionControlInstance isn't v2, this whole method is a no-op
- if (vc_v2 != null)
- {
- vc_v2.RefreshAvailableLocalChangesSynchronous();
- UpdateChangesToPublish();
- }
- }
-
- // Static constructor for Collab
- static Collab()
- {
- s_Instance = new Collab();
- s_Instance.projectBrowserSingleSelectionPath = string.Empty;
- s_Instance.projectBrowserSingleMetaSelectionPath = string.Empty;
- s_Instance.m_nativeCollab = GetNativeCollab();
- ObjectListArea.postAssetIconDrawCallback += CollabProjectHook.OnProjectWindowIconOverlay;
- AssetsTreeViewGUI.postAssetIconDrawCallback += CollabProjectHook.OnProjectBrowserNavPanelIconOverlay;
- InitializeSoftlocksViewController();
- CollabSettingsManager.statusNotifier[CollabSettingType.InProgressEnabled] += OnSettingStatusChanged;
- CollabSettingsManager.statusNotifier[CollabSettingType.InProgressEnabled] += SoftlockViewController.Instance.softLockFilters.OnSettingStatusChanged;
- }
-
- public static void OnSettingStatusChanged(CollabSettingType type, CollabSettingStatus status)
- {
- InitializeSoftlocksViewController();
- }
-
- public static bool InitializeSoftlocksViewController()
- {
- if (!CollabSettingsManager.IsAvailable(CollabSettingType.InProgressEnabled))
- return false;
-
- if (CollabSettingsManager.inProgressEnabled)
- SoftlockViewController.Instance.TurnOn();
- else
- SoftlockViewController.Instance.TurnOff();
- return true;
- }
-
-
- public bool GetError(UnityConnect.UnityErrorFilter errorFilter, out UnityErrorInfo info)
- {
- return GetErrorInternal((int)errorFilter, out info) && info.code > 0;
- }
-
- public void CancelJob(int jobType)
- {
- try
- {
- CancelJobByType(jobType, false);
- }
- catch (Exception ex)
- {
- UnityEngine.Debug.Log("Cannot cancel job, reason:" + ex.Message);
- }
- }
-
- public void UpdateEditorSelectionCache()
- {
- var result = new List();
-
- foreach (var elem in Selection.assetGUIDsDeepSelection)
- {
- var path = AssetDatabase.GUIDToAssetPath(elem);
- result.Add(path);
-
- var meta = path + ".meta";
- if (File.Exists(meta))
- {
- result.Add(meta);
- }
- }
- currentProjectBrowserSelection = result.ToArray();
- }
-
- public CollabInfo GetCollabInfo()
- {
- return collabInfo;
- }
-
- public static bool IsDiffToolsAvailable()
- {
- return InternalEditorUtility.GetAvailableDiffTools().Length > 0;
- }
-
- public void SaveAssets()
- {
- AssetDatabase.SaveAssets();
- }
-
- public static void SwitchToDefaultMode()
- {
- bool in2D = EditorSettings.defaultBehaviorMode == EditorBehaviorMode.Mode2D;
- var sv = SceneView.lastActiveSceneView;
- if (sv != null && sv.in2DMode != in2D)
- {
- sv.in2DMode = in2D;
- }
- }
-
- public void ShowInProjectBrowser(string filterString)
- {
- collabFilters.ShowInProjectBrowser(filterString);
- }
-
- public bool SetConflictsResolvedMine(string[] paths)
- {
- return SetConflictsResolved(paths, CollabStates.kCollabUseMine);
- }
-
- public bool SetConflictsResolvedTheirs(string[] paths)
- {
- return SetConflictsResolved(paths, CollabStates.kCollabUseTheir);
- }
-
- public PublishInfo GetChangesToPublish()
- {
- Change[] changes = GetChangesToPublishInternal();
- bool isFiltered = false;
-
- if (SupportsAsyncChanges())
- {
- changes = GetSelectedChangesInternal();
- if (Toolbar.isLastShowRequestPartial)
- {
- isFiltered = true;
- }
- }
-
- return new PublishInfo()
- {
- changes = changes,
- filter = isFiltered
- };
- }
-
- public PublishInfo_V2 GetChangesToPublish_V2()
- {
- ChangeItem[] changes = GetChangeItemsToPublishInternal_V2();
-
- return new PublishInfo_V2()
- {
- changes = changes,
- filter = false
- };
- }
-
- public void SetChangesToPublish(ChangeItem[] changes)
- {
- SetChangesToPublishInternal(changes);
- }
-
- public ProgressInfo GetJobProgress(int jobId)
- {
- ProgressInfo info = new ProgressInfo();
- if (GetJobProgressInternal(info, jobId))
- return info;
-
- return null;
- }
-
- private static void OnStateChanged()
- {
- // register only once
- if (s_IsFirstStateChange)
- {
- s_IsFirstStateChange = false;
- UnityConnect.instance.StateChanged += OnUnityConnectStateChanged;
- }
- var handler = instance.StateChanged;
- if (handler != null)
- {
- handler(instance.collabInfo);
- }
- }
-
- [RequiredByNativeCode]
- private static void OnRevisionUpdated(string revisionId, string action)
- {
- var handler = instance.RevisionUpdated;
- if (handler != null)
- {
- handler(instance.collabInfo);
- }
-
- var handler_v2 = instance.RevisionUpdated_V2;
- if (handler_v2 != null)
- {
- handler_v2(instance.collabInfo, revisionId, action);
- }
- }
-
- [RequiredByNativeCode]
- private static void OnChangeItemsChanged(ChangeItem[] changes, bool isFiltered)
- {
- var handler = instance.ChangeItemsChanged;
- if (handler != null)
- {
- handler(changes, isFiltered);
- }
- }
-
- [RequiredByNativeCode]
- private static void OnSelectedChangeItemsChanged(ChangeItem[] changeItems, bool isFiltered)
- {
- var handler = instance.SelectedChangeItemsChanged;
- if (handler != null)
- {
- handler(changeItems, isFiltered);
- }
- }
-
- [RequiredByNativeCode]
- private static void OnCollabInfoChanged()
- {
- var handler = instance.CollabInfoChanged;
- if (handler != null)
- {
- handler(instance.collabInfo);
- }
- }
-
- [RequiredByNativeCode]
- private static void SetCollabError(int code, int priority, int behavior, string msg, string shortmsg, string codeStr)
- {
- var handler = instance.ErrorOccurred;
-
- if (handler != null)
- {
- handler();
- }
- var handler_v2 = instance.ErrorOccurred_V2;
-
- if (handler_v2 != null)
- {
- handler_v2(new UnityErrorInfo() { code = code, priority = priority, behaviour = behavior, msg = msg, shortMsg = shortmsg, codeStr = codeStr });
- }
- }
-
- [RequiredByNativeCode]
- private static void ClearCollabError()
- {
- var handler = instance.ErrorCleared;
- if (handler != null)
- handler();
- }
-
- private static void OnJobsCompleted()
- {
- var handler = instance.JobsCompleted;
- if (handler != null)
- {
- handler(instance.collabInfo);
- }
- CollabTesting.OnJobsCompleted();
- }
-
- private static void PublishDialog(string changelist)
- {
- if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
- {
- return;
- }
-
- var dialog = CollabPublishDialog.ShowCollabWindow(changelist);
-
- if (dialog.Options.DoPublish)
- Collab.instance.Publish(dialog.Options.Comments, true, false);
- }
-
- private static void CannotPublishDialog(string infoMessage)
- {
- CollabCannotPublishDialog.ShowCollabWindow(infoMessage);
- }
-
- private static void OnUnityConnectStateChanged(ConnectInfo state)
- {
- instance.SendNotification();
- }
-
- public static void OnProgressEnabledSettingStatusChanged(CollabSettingType type, CollabSettingStatus status)
- {
- if (type == CollabSettingType.InProgressEnabled && status == CollabSettingStatus.Available)
- {
- if (CollabSettingsManager.inProgressEnabled)
- {
- SoftlockViewController.Instance.softLockFilters.ShowInFavoriteSearchFilters();
- }
-
- CollabSettingsManager.statusNotifier[CollabSettingType.InProgressEnabled] -= OnProgressEnabledSettingStatusChanged;
- }
- }
-
-
- [RequiredByNativeCode]
- static void OnCollabEnabledForCurrentProject(bool enabled)
- {
- if (enabled)
- {
- instance.StateChanged += instance.collabFilters.OnCollabStateChanged;
- instance.collabFilters.ShowInFavoriteSearchFilters();
- if (CollabSettingsManager.IsAvailable(CollabSettingType.InProgressEnabled))
- {
- if (CollabSettingsManager.inProgressEnabled)
- {
- SoftlockViewController.Instance.softLockFilters.ShowInFavoriteSearchFilters();
- }
- }
- else
- {
- CollabSettingsManager.statusNotifier[CollabSettingType.InProgressEnabled] -= OnProgressEnabledSettingStatusChanged;
- CollabSettingsManager.statusNotifier[CollabSettingType.InProgressEnabled] += OnProgressEnabledSettingStatusChanged;
- }
- }
- else
- {
- instance.StateChanged -= instance.collabFilters.OnCollabStateChanged;
- instance.collabFilters.HideFromFavoriteSearchFilters();
- SoftlockViewController.Instance.softLockFilters.HideFromFavoriteSearchFilters();
- CollabSettingsManager.statusNotifier[CollabSettingType.InProgressEnabled] -= OnProgressEnabledSettingStatusChanged;
-
- if (ProjectBrowser.s_LastInteractedProjectBrowser != null)
- {
- if (ProjectBrowser.s_LastInteractedProjectBrowser.Initialized() && ProjectBrowser.s_LastInteractedProjectBrowser.IsTwoColumns())
- {
- int instanceID = AssetDatabase.GetMainAssetInstanceID("assets");
- ProjectBrowser.s_LastInteractedProjectBrowser.SetFolderSelection(new int[] { instanceID }, true);
- }
- ProjectBrowser.s_LastInteractedProjectBrowser.SetSearch("");
- ProjectBrowser.s_LastInteractedProjectBrowser.Repaint();
- }
- }
- }
- }
-}
diff --git a/Editor/Mono/Collab/CollabChange.cs b/Editor/Mono/Collab/CollabChange.cs
deleted file mode 100644
index 1297fdb044..0000000000
--- a/Editor/Mono/Collab/CollabChange.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System;
-using System.Runtime.InteropServices;
-using UnityEngine.Bindings;
-
-namespace UnityEditor.Collaboration
-{
- // Keep internal and undocumented until we expose more functionality
- //*undocumented
- [StructLayout(LayoutKind.Sequential)]
- [NativeType(CodegenOptions = CodegenOptions.Custom, Header = "Editor/Src/Collab/CollabChange.h",
- IntermediateScriptingStructName = "ScriptingCollabChange")]
- [NativeHeader("Editor/Src/Collab/Collab.bindings.h")]
- [NativeAsStruct]
- internal class Change
- {
- [Flags]
- public enum RevertableStates : uint
- {
- Revertable = 1 << 0,
- NotRevertable = 1 << 1,
-
- Revertable_File = 1 << 2,
- Revertable_Folder = 1 << 3,
- Revertable_EmptyFolder = 1 << 4,
-
- NotRevertable_File = 1 << 5,
- NotRevertable_Folder = 1 << 6,
- NotRevertable_FileAdded = 1 << 7,
- NotRevertable_FolderAdded = 1 << 8,
- NotRevertable_FolderContainsAdd = 1 << 9,
-
- // do not exceed Javascript Number range
- InvalidRevertableState = (uint)1 << 31
- }
-
- string m_Path;
- Collab.CollabStates m_State;
- RevertableStates m_RevertableState;
- string m_RelatedTo;
- string m_LocalStatus;
- string m_RemoteStatus;
- string m_ResolveStatus;
-
- Change() {}
-
- public string path { get { return m_Path; } }
- public Collab.CollabStates state { get { return m_State; } }
- public bool isRevertable { get { return HasRevertableState(RevertableStates.Revertable); } }
- public RevertableStates revertableState { get { return m_RevertableState; } }
- public string relatedTo { get { return m_RelatedTo; } }
-
- public bool isMeta { get { return HasState(Collab.CollabStates.kCollabMetaFile); } }
- public bool isConflict { get { return HasState(Collab.CollabStates.kCollabConflicted) || HasState(Collab.CollabStates.kCollabPendingMerge); } }
- public bool isFolderMeta { get { return HasState(Collab.CollabStates.kCollabFolderMetaFile); } }
- public bool isResolved { get { return HasState(Collab.CollabStates.kCollabUseMine) || HasState(Collab.CollabStates.kCollabUseTheir) || HasState(Collab.CollabStates.kCollabMerged); } }
-
- public string localStatus { get { return m_LocalStatus; } }
- public string remoteStatus { get { return m_RemoteStatus; } }
- public string resolveStatus { get { return m_ResolveStatus; } }
-
- internal bool HasState(Collab.CollabStates states)
- {
- return (m_State & states) != 0;
- }
-
- internal bool HasRevertableState(RevertableStates revertableStates)
- {
- return (m_RevertableState & revertableStates) != 0;
- }
- }
-
- internal class PublishInfo
- {
- public Change[] changes;
- public bool filter;
- }
-}
diff --git a/Editor/Mono/Collab/CollabChangeAction.cs b/Editor/Mono/Collab/CollabChangeAction.cs
deleted file mode 100644
index 8d65911b51..0000000000
--- a/Editor/Mono/Collab/CollabChangeAction.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System;
-using System.Runtime.InteropServices;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- // Keep internal and undocumented until we expose more functionality
- //*undocumented
- [StructLayout(LayoutKind.Sequential)]
- [UsedByNativeCode]
- internal struct ChangeAction
- {
- private string m_Path;
- private string m_Action;
-
- public ChangeAction(string path = "", string action = "")
- {
- m_Path = path;
- m_Action = action;
- }
-
- public string path { get { return m_Path; } }
- public string action { get { return m_Action; } }
- }
-}
diff --git a/Editor/Mono/Collab/CollabChangeItem.cs b/Editor/Mono/Collab/CollabChangeItem.cs
index cfca4a5ab9..ad380552c0 100644
--- a/Editor/Mono/Collab/CollabChangeItem.cs
+++ b/Editor/Mono/Collab/CollabChangeItem.cs
@@ -6,29 +6,3 @@
using System.Runtime.InteropServices;
using UnityEngine.Bindings;
-namespace UnityEditor.Collaboration
-{
- [StructLayout(LayoutKind.Sequential)]
- [NativeType(CodegenOptions = CodegenOptions.Custom, Header = "Editor/Src/Collab/CollabClient.h",
- IntermediateScriptingStructName = "ScriptingCollabChangeItem")]
- [NativeHeader("Editor/Src/Collab/Collab.bindings.h")]
- [NativeAsStruct]
- internal class ChangeItem
- {
- public string Path { get; set; }
- public Change.RevertableStates RevertableState { get; set; }
- public string RelatedTo { get; set; }
- public string RevisionId { get; set; }
- public string Hash { get; set; }
- public Collab.CollabStates State { get; set; }
- public long Size { get; set; }
- public string DownloadPath { get; set; }
- public string FromPath { get; set; }
- }
-
- internal class PublishInfo_V2
- {
- public ChangeItem[] changes;
- public bool filter;
- }
-}
diff --git a/Editor/Mono/Collab/CollabDialogs.cs b/Editor/Mono/Collab/CollabDialogs.cs
deleted file mode 100644
index 155f8766e1..0000000000
--- a/Editor/Mono/Collab/CollabDialogs.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEditor;
-using UnityEditor.Web;
-using UnityEditorInternal;
-using UnityEditor.Connect;
-
-namespace UnityEditor.Collaboration
-{
- internal struct PublishDialogOptions
- {
- public string Comments;
- public bool DoPublish;
- }
-
- internal class CollabPublishDialog : EditorWindow
- {
- public static CollabPublishDialog ShowCollabWindow(string changelist)
- {
- CollabPublishDialog dialog = ScriptableObject.CreateInstance();
- dialog.Changelist = changelist;
-
- var rect = new Rect(100, 100, 600, 225);
- dialog.minSize = new Vector2(rect.width, rect.height);
- dialog.maxSize = new Vector2(rect.width, rect.height);
- dialog.position = rect;
- dialog.ShowModal();
-
- dialog.m_Parent.window.m_DontSaveToLayout = true;
-
- return dialog;
- }
-
- static GUIContent DescribeChangesText = EditorGUIUtility.TrTextContent("Describe your changes here");
- static GUIContent ChangeAssetsText = EditorGUIUtility.TrTextContent("Changed assets:");
- static GUIContent PublishText = EditorGUIUtility.TrTextContent("Publish");
- static GUIContent CancelText = EditorGUIUtility.TrTextContent("Cancel");
-
- public Vector2 scrollView;
- public string Changelist;
-
- public CollabPublishDialog()
- {
- Options.Comments = "";
- }
-
- public void OnGUI()
- {
- GUILayout.BeginVertical();
- GUILayout.Label(DescribeChangesText);
- Options.Comments = GUILayout.TextArea(Options.Comments, 1000, GUILayout.MinHeight(80));
-
-
- GUILayout.Label(ChangeAssetsText);
- scrollView = EditorGUILayout.BeginScrollView(scrollView, false, false);
- GUIStyle style = new GUIStyle();
- Vector2 textSize = style.CalcSize(new GUIContent(Changelist));
- EditorGUILayout.SelectableLabel(Changelist, EditorStyles.textField, GUILayout.ExpandHeight(true), GUILayout.MinHeight(textSize.y));
- EditorGUILayout.EndScrollView();
-
- GUILayout.FlexibleSpace();
-
- GUILayout.BeginHorizontal();
- GUILayout.FlexibleSpace();
-
- if (GUILayout.Button(CancelText))
- {
- Options.DoPublish = false;
- Close();
- }
-
- if (GUILayout.Button(PublishText))
- {
- Options.DoPublish = true;
- Close();
- }
-
- GUILayout.EndHorizontal();
- GUILayout.EndVertical();
- }
-
- public PublishDialogOptions Options;
- }
-
- internal class CollabCannotPublishDialog : EditorWindow
- {
- public static CollabCannotPublishDialog ShowCollabWindow(string infoMessage)
- {
- CollabCannotPublishDialog dialog = ScriptableObject.CreateInstance();
- dialog.InfoMessage = infoMessage;
-
- var rect = new Rect(100, 100, 600, 150);
- dialog.minSize = new Vector2(rect.width, rect.height);
- dialog.maxSize = new Vector2(rect.width, rect.height);
- dialog.position = rect;
- dialog.ShowModal();
-
- dialog.m_Parent.window.m_DontSaveToLayout = true;
-
- return dialog;
- }
-
- static GUIContent WarningText = EditorGUIUtility.TextContent(string.Format(
- "Files that have been moved or in a changed folder cannot be selectively published, " +
- "please use the Publish option in the collab window to publish all your changes."));
- static GUIContent IssuesText = EditorGUIUtility.TrTextContent("Issues:");
- static GUIContent AcceptText = EditorGUIUtility.TrTextContent("Accept");
-
- public Vector2 scrollPosition;
- public string InfoMessage;
-
- public void OnGUI()
- {
- GUILayout.BeginVertical();
- GUI.skin.label.wordWrap = true;
-
- GUILayout.BeginVertical();
- GUILayout.Label(WarningText);
-
- GUILayout.Label(IssuesText);
-
- scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
- GUIStyle warnStyle = new GUIStyle();
- warnStyle.normal.textColor = new Color(1f, 0.28f, 0f);
- GUILayout.Label(string.Format(InfoMessage), warnStyle);
- GUILayout.EndScrollView();
-
- GUILayout.EndVertical();
-
- GUILayout.BeginHorizontal();
- GUILayout.FlexibleSpace();
-
- if (GUILayout.Button(AcceptText))
- Close();
- GUILayout.EndHorizontal();
-
- GUILayout.EndVertical();
- }
- }
-}
diff --git a/Editor/Mono/Collab/CollabEditorHooks.cs b/Editor/Mono/Collab/CollabEditorHooks.cs
deleted file mode 100644
index 89965e7b3f..0000000000
--- a/Editor/Mono/Collab/CollabEditorHooks.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using UnityEngine;
-using UnityEditor.Web;
-using UnityEditor.Connect;
-
-namespace UnityEditor.Collaboration
-{
- // Display hooks for the main project window. Icons are overlayed to show the version control state.
- internal class CollabProjectHook
- {
- // GUI callback for each item visible in the project window/object list area
- public static void OnProjectWindowIconOverlay(Rect iconRect, string guid, bool isListMode)
- {
- DrawProjectBrowserIconOverlay(iconRect, guid, isListMode);
- }
-
- // Draw icons in the Favorites/Asset Folder area of the project browser
- public static void OnProjectBrowserNavPanelIconOverlay(Rect iconRect, string guid)
- {
- DrawProjectBrowserIconOverlay(iconRect, guid, true);
- }
-
- private static void DrawProjectBrowserIconOverlay(Rect iconRect, string guid, bool isListMode)
- {
- if (Collab.instance.IsCollabEnabledForCurrentProject())
- {
- Collab.CollabStates assetState = GetAssetState(guid);
- Overlay.DrawOverlays(assetState, iconRect, isListMode);
- }
- }
-
- public static Collab.CollabStates GetAssetState(String assetGuid)
- {
- if (!Collab.instance.IsCollabEnabledForCurrentProject())
- {
- return Collab.CollabStates.kCollabNone;
- }
-
- Collab.CollabStates assetState = Collab.GetAssetState(assetGuid, AssetDatabase.GUIDToAssetPath(assetGuid));
- return assetState;
- }
- }
-
- internal class Overlay
- {
- public const double k_OverlaySizeOnSmallIcon = 0.6;
- public const double k_OverlaySizeOnLargeIcon = 0.35;
-
- private static readonly Dictionary s_Overlays = new Dictionary();
-
- protected static void LoadOverlays()
- {
- // Order of priority must match GetLocalStatus (CollabClient.h)
- s_Overlays.Clear();
- s_Overlays.Add(Collab.CollabStates.kCollabIgnored, EditorGUIUtility.IconContent("CollabExclude Icon"));
- s_Overlays.Add(Collab.CollabStates.kCollabConflicted, EditorGUIUtility.IconContent("CollabConflict Icon"));
- s_Overlays.Add(Collab.CollabStates.kCollabPendingMerge, EditorGUIUtility.IconContent("CollabConflict Icon"));
- s_Overlays.Add(Collab.CollabStates.kCollabMovedLocal, EditorGUIUtility.IconContent("CollabMoved Icon"));
- s_Overlays.Add(Collab.CollabStates.kCollabCheckedOutLocal | Collab.CollabStates.kCollabMovedLocal, EditorGUIUtility.IconContent("CollabMoved Icon"));
- s_Overlays.Add(Collab.CollabStates.kCollabCheckedOutLocal, EditorGUIUtility.IconContent("CollabEdit Icon"));
- s_Overlays.Add(Collab.CollabStates.kCollabAddedLocal, EditorGUIUtility.IconContent("CollabCreate Icon"));
- s_Overlays.Add(Collab.CollabStates.kCollabDeletedLocal, EditorGUIUtility.IconContent("CollabDeleted Icon"));
-
- // The folder overlay should take precedence on the folder content's status.
- s_Overlays.Add(Collab.CollabStates.KCollabContentConflicted, EditorGUIUtility.IconContent("CollabChangesConflict Icon"));
- s_Overlays.Add(Collab.CollabStates.KCollabContentChanged, EditorGUIUtility.IconContent("CollabChanges Icon"));
- s_Overlays.Add(Collab.CollabStates.KCollabContentDeleted, EditorGUIUtility.IconContent("CollabChangesDeleted Icon"));
- }
-
- protected static bool AreOverlaysLoaded()
- {
- if (s_Overlays.Count == 0)
- return false;
-
- foreach (var icon in s_Overlays.Values)
- {
- if (icon == null)
- return false;
- }
-
- return true;
- }
-
- protected static Collab.CollabStates GetOverlayStateForAsset(Collab.CollabStates assetStates)
- {
- foreach (var state in s_Overlays.Keys)
- {
- if (HasState(assetStates, state))
- return state;
- }
-
- return Collab.CollabStates.kCollabNone;
- }
-
- protected static void DrawOverlayElement(Collab.CollabStates singleState, Rect itemRect)
- {
- GUIContent content;
- if (s_Overlays.TryGetValue(singleState, out content))
- {
- Texture overlay = content.image;
- if (overlay != null)
- {
- GUI.DrawTexture(itemRect, overlay, ScaleMode.ScaleToFit);
- }
- }
- }
-
- protected static bool HasState(Collab.CollabStates assetStates, Collab.CollabStates includesState)
- {
- return ((assetStates & includesState) == includesState);
- }
-
- public static void DrawOverlays(Collab.CollabStates assetState, Rect itemRect, bool isListMode)
- {
- if (assetState == Collab.CollabStates.kCollabInvalidState || assetState == Collab.CollabStates.kCollabNone)
- return;
-
- if (Event.current.type != EventType.Repaint)
- return;
-
- if (!AreOverlaysLoaded())
- LoadOverlays();
-
- var state = GetOverlayStateForAsset(assetState);
- DrawOverlayElement(state, GetRectForTopRight(itemRect, GetScale(itemRect, isListMode)));
- }
-
- // Return a new Rect with its width and height scaled, and converted to the ceiling.
- public static Rect ScaleRect(Rect rect, double scale)
- {
- Rect scaledRect = new Rect(rect);
- scaledRect.width = Convert.ToInt32(Math.Ceiling(rect.width * scale));
- scaledRect.height = Convert.ToInt32(Math.Ceiling(rect.height * scale));
- return scaledRect;
- }
-
- public static double GetScale(Rect rect, bool isListMode)
- {
- double scale = k_OverlaySizeOnLargeIcon;
- if (isListMode)
- {
- scale = k_OverlaySizeOnSmallIcon;
- }
- return scale;
- }
-
- public static Rect GetRectForTopRight(Rect projectBrowserDrawRect, double scale)
- {
- Rect scaledRect = ScaleRect(projectBrowserDrawRect, scale);
- scaledRect.x += (projectBrowserDrawRect.width - scaledRect.width);
- return scaledRect;
- }
-
- public static Rect GetRectForBottomRight(Rect projectBrowserDrawRect, double scale)
- {
- Rect scaledRect = ScaleRect(projectBrowserDrawRect, scale);
- scaledRect.x += (projectBrowserDrawRect.width - scaledRect.width);
- scaledRect.y += (projectBrowserDrawRect.height - scaledRect.height);
- return scaledRect;
- }
- }
-
- internal static class TextureUtility
- {
- public static Texture2D LoadTextureFromApplicationContents(string path)
- {
- var tex = new Texture2D(2, 2);
-
- string resourcesPath = Path.Combine(Path.Combine(Path.Combine(EditorApplication.applicationContentsPath, "Resources"), "Collab"), "overlays");
- path = Path.Combine(resourcesPath, path);
-
- try
- {
- using (var fs = File.OpenRead(path))
- {
- var bytes = new byte[fs.Length];
- fs.Read(bytes, 0, (int)fs.Length);
- if (!tex.LoadImage(bytes)) return null;
- }
- }
- catch (Exception)
- {
- Debug.LogWarning("Collab Overlay Texture load fail, path: " + path);
- return null;
- }
-
- return tex;
- }
- }
-}
diff --git a/Editor/Mono/Collab/CollabFilters.cs b/Editor/Mono/Collab/CollabFilters.cs
deleted file mode 100644
index 9a2373fc4a..0000000000
--- a/Editor/Mono/Collab/CollabFilters.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using UnityEditor;
-using UnityEngine;
-
-namespace UnityEditor.Collaboration
-{
- internal abstract class AbstractFilters
- {
- [SerializeField]
- private List m_Filters;
-
- public List filters { get { return m_Filters; } set { m_Filters = value; } }
-
- public abstract void InitializeFilters();
-
- public bool ContainsSearchFilter(string name, string searchString)
- {
- foreach (var filter in filters)
- {
- if (filter[0] == name && filter[1] == searchString)
- return true;
- }
- return false;
- }
-
- public void ShowInFavoriteSearchFilters()
- {
- if (SavedSearchFilters.GetRootInstanceID() == 0)
- {
- SavedSearchFilters.AddInitializedListener(ShowInFavoriteSearchFilters);
- return;
- }
-
- SavedSearchFilters.RemoveInitializedListener(ShowInFavoriteSearchFilters);
- int prevInstanceID = 0;
- foreach (var filter in filters)
- {
- int instanceID = SavedSearchFilters.GetFilterInstanceID(filter[0], filter[1]);
- if (instanceID == 0)
- {
- SearchFilter searchFilter = SearchFilter.CreateSearchFilterFromString(filter[1]);
- if (prevInstanceID == 0)
- prevInstanceID = SavedSearchFilters.AddSavedFilter(filter[0], searchFilter, 64);
- else
- prevInstanceID = SavedSearchFilters.AddSavedFilterAfterInstanceID(filter[0], searchFilter, 64, prevInstanceID, false);
- }
- }
-
- SavedSearchFilters.RefreshSavedFilters();
-
- foreach (ProjectBrowser pb in ProjectBrowser.GetAllProjectBrowsers())
- {
- pb.Repaint();
- }
- }
-
- public void HideFromFavoriteSearchFilters()
- {
- SavedSearchFilters.RefreshSavedFilters();
-
- foreach (ProjectBrowser pb in ProjectBrowser.GetAllProjectBrowsers())
- {
- pb.Repaint();
- }
- }
- }
-
- internal class CollabFilters : AbstractFilters
- {
- [SerializeField]
- private bool m_SearchFilterWasSet = false;
-
- public override void InitializeFilters()
- {
- filters = new List()
- {
- new string[] { "All Modified", "v:any" },
- new string[] { "All Conflicts", "v:conflicted" },
- new string[] { "All Excluded" , "v:ignored"},
- };
- }
-
- public CollabFilters()
- {
- InitializeFilters();
- }
-
- public void ShowInProjectBrowser(string filterString)
- {
- ProjectBrowser browser = ProjectBrowser.s_LastInteractedProjectBrowser;
- if (browser == null)
- {
- List browsers = ProjectBrowser.GetAllProjectBrowsers();
- if (browsers != null && browsers.Count > 0)
- {
- browser = browsers.First();
- }
- }
-
- if (!string.IsNullOrEmpty(filterString))
- {
- if (browser == null)
- {
- browser = EditorWindow.GetWindow();
- ShowInFavoriteSearchFilters();
- browser.RepaintImmediately();
- }
-
- m_SearchFilterWasSet = true;
-
- string filterSearchString = "v:" + filterString;
- if (browser.IsTwoColumns())
- {
- foreach (var filter in filters)
- {
- if (filterSearchString == filter[1])
- {
- int instanceID = SavedSearchFilters.GetFilterInstanceID(filter[0], filterSearchString);
- if (instanceID > ProjectWindowUtil.k_FavoritesStartInstanceID)
- {
- browser.SetFolderSelection(new int[] { instanceID }, true);
- break;
- }
- }
- }
- }
-
- browser.SetSearch(filterSearchString);
- browser.Repaint();
- browser.Focus();
- }
- else
- {
- if (m_SearchFilterWasSet)
- {
- if (browser != null)
- {
- if (browser.IsTwoColumns())
- {
- int instanceID = AssetDatabase.GetMainAssetInstanceID("assets");
- browser.SetFolderSelection(new int[] { instanceID }, true);
- }
- browser.SetSearch("");
- browser.Repaint();
- }
- }
- m_SearchFilterWasSet = false;
- }
- }
-
- public void OnCollabStateChanged(CollabInfo info)
- {
- if (!info.ready || info.inProgress || info.maintenance)
- return;
-
- foreach (ProjectBrowser pb in ProjectBrowser.GetAllProjectBrowsers())
- {
- pb.RefreshSearchIfFilterContains("v:");
- }
- }
- }
-}
diff --git a/Editor/Mono/Collab/CollabProgressInfo.cs b/Editor/Mono/Collab/CollabProgressInfo.cs
deleted file mode 100644
index 5727a41a7d..0000000000
--- a/Editor/Mono/Collab/CollabProgressInfo.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System.Runtime.InteropServices;
-using UnityEngine.Bindings;
-
-namespace UnityEditor.Collaboration
-{
- // Keep internal and undocumented until we expose more functionality
- //*undocumented
- [StructLayout(LayoutKind.Sequential)]
- [NativeType(CodegenOptions = CodegenOptions.Custom, Header = "Editor/Src/Collab/CollabProgressInfo.h",
- IntermediateScriptingStructName = "ScriptingCollabProgressInfo")]
- [NativeHeader("Editor/Src/Collab/Collab.bindings.h")]
- [NativeAsStruct]
- internal class ProgressInfo
- {
- public enum ProgressType : uint
- {
- None = 0,
- Count = 1,
- Percent = 2,
- Both = 3
- }
-
- int m_JobId;
- string m_Title;
- string m_ExtraInfo;
- ProgressType m_ProgressType;
- int m_Percentage;
- int m_CurrentCount;
- int m_TotalCount;
- bool m_Completed;
- bool m_Cancelled;
- bool m_CanCancel;
- string m_LastErrorString;
- ulong m_LastError;
-
- public int jobId { get { return m_JobId; } }
- public string title { get { return m_Title; } }
- public string extraInfo { get { return m_ExtraInfo; } }
- public int currentCount { get { return m_CurrentCount; } }
- public int totalCount { get { return m_TotalCount; } }
- public bool completed { get { return m_Completed; } }
- public bool cancelled { get { return m_Cancelled; } }
- public bool canCancel { get { return m_CanCancel; } }
- public string lastErrorString { get { return m_LastErrorString; } }
- public ulong lastError { get { return m_LastError; } }
-
- public int percentComplete
- {
- get
- {
- if (m_ProgressType == ProgressType.Percent || m_ProgressType == ProgressType.Both)
- {
- return m_Percentage;
- }
-
- if (m_ProgressType == ProgressType.Count)
- {
- if (m_TotalCount == 0) return 0;
- return (m_CurrentCount * 100) / m_TotalCount;
- }
- return 0;
- }
- }
-
- public bool isProgressTypeCount { get { return (m_ProgressType == ProgressType.Count || m_ProgressType == ProgressType.Both); } }
- public bool isProgressTypePercent { get { return (m_ProgressType == ProgressType.Percent || m_ProgressType == ProgressType.Both); } }
- public bool errorOccured { get { return (m_LastError != 0); } }
- }
-}
diff --git a/Editor/Mono/Collab/CollabRevision.cs b/Editor/Mono/Collab/CollabRevision.cs
deleted file mode 100644
index d00b479d95..0000000000
--- a/Editor/Mono/Collab/CollabRevision.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System.Runtime.InteropServices;
-using UnityEngine.Bindings;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- // Keep internal and undocumented until we expose more functionality
- //*undocumented
- [StructLayout(LayoutKind.Sequential)]
- [UsedByNativeCode]
- internal struct Revision
- {
- [NativeName("m_CommitterName")]
- private string m_AuthorName;
- [NativeName("m_CommitterEmail")]
- private string m_Author;
- private string m_Comment;
- private string m_RevisionID;
- private string m_Reference;
- private ulong m_TimeStamp;
- // Whether this revision has been obtained by the client
- private bool m_IsObtained;
- private ChangeAction[] m_Entries;
- private CloudBuildStatus[] m_BuildStatuses;
-
- internal Revision(string revisionID = "", string authorName = "", string author = "",
- string comment = "", string reference = "", ulong timeStamp = 0,
- bool isObtained = false, ChangeAction[] entries = null,
- CloudBuildStatus[] buildStatuses = null)
- {
- m_AuthorName = authorName;
- m_Author = author;
- m_Comment = comment;
- m_RevisionID = revisionID;
- m_Reference = reference;
- m_TimeStamp = timeStamp;
- m_IsObtained = isObtained;
- m_Entries = entries ?? new ChangeAction[0];
- m_BuildStatuses = buildStatuses ?? new CloudBuildStatus[0];
- }
-
- public string authorName { get { return m_AuthorName; } }
- public string author { get { return m_Author; } }
- public string comment { get { return m_Comment; } }
- public string revisionID { get { return m_RevisionID; } }
- public string reference { get { return m_Reference; } }
- public ulong timeStamp { get { return m_TimeStamp; } }
- public bool isObtained { get { return m_IsObtained; } }
- public ChangeAction[] entries { get { return m_Entries; } }
- public CloudBuildStatus[] buildStatuses { get { return m_BuildStatuses; } }
- }
-}
diff --git a/Editor/Mono/Collab/CollabRevisionsData.cs b/Editor/Mono/Collab/CollabRevisionsData.cs
deleted file mode 100644
index 0c13f70010..0000000000
--- a/Editor/Mono/Collab/CollabRevisionsData.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System.Runtime.InteropServices;
-using UnityEngine.Bindings;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- // Keep internal and undocumented until we expose more functionality
- //*undocumented
- [StructLayout(LayoutKind.Sequential)]
- [UsedByNativeCode]
- internal struct RevisionsData
- {
- private int m_RevisionsInRepo;
- private int m_RevisionOffset;
- private int m_ReturnedRevisions;
- private Revision[] m_Revisions;
-
- public int RevisionsInRepo {get { return m_RevisionsInRepo; }}
- public int RevisionOffset {get { return m_RevisionOffset; }}
- public int ReturnedRevisions {get { return m_ReturnedRevisions; }}
- public Revision[] Revisions {get { return m_Revisions; }}
- }
-}
diff --git a/Editor/Mono/Collab/CollabTesting.cs b/Editor/Mono/Collab/CollabTesting.cs
index 38b0e268a3..06c451a530 100644
--- a/Editor/Mono/Collab/CollabTesting.cs
+++ b/Editor/Mono/Collab/CollabTesting.cs
@@ -64,8 +64,6 @@ public static void Execute()
if (_enumerator == null)
return;
- if (Collab.instance.AnyJobRunning())
- return;
try
{
diff --git a/Editor/Mono/Collab/CollabToUVCSBridge.cs b/Editor/Mono/Collab/CollabToUVCSBridge.cs
new file mode 100644
index 0000000000..2291d35ca6
--- /dev/null
+++ b/Editor/Mono/Collab/CollabToUVCSBridge.cs
@@ -0,0 +1,530 @@
+// Unity C# reference source
+// Copyright (c) Unity Technologies. For terms of use, see
+// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
+
+// This file was introduced as part of the collab removal, it supports any versions of com.unity.collab-proxy under 1.17.7
+// It allows for an error free upgrade by provinding mock classes for the removed ones.
+
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+
+using UnityEditor.Connect;
+using UnityEditor.PackageManager;
+using UnityEngine;
+
+#pragma warning disable 0067
+#pragma warning disable 0618
+namespace UnityEditor.Collaboration
+{
+ internal static class LogObsolete
+ {
+ static bool s_Initialized;
+ static bool s_NeedsLogging;
+ static Stopwatch s_Stopwatch = Stopwatch.StartNew();
+
+ internal static void Log()
+ {
+ if (!s_Initialized)
+ s_NeedsLogging = IsObsolete("com.unity.collab-proxy", "1.1");
+
+ s_Initialized = true;
+
+ if (!s_NeedsLogging)
+ return;
+
+ if (s_Stopwatch.ElapsedMilliseconds < 1000)
+ return;
+
+ UnityEngine.Debug.unityLogger.LogWarning(
+ "com.unity.collab-proxy",
+ "This version of the package is not supported, please upgrade to the latest version. https://unity.com/solutions/version-control");
+
+ s_Stopwatch.Restart();
+ }
+
+ internal static bool IsObsolete(string packageName, string version)
+ {
+ UnityEditor.PackageManager.PackageInfo package = null;
+ try
+ {
+ package = UnityEditor.PackageManager.PackageInfo.FindForPackageName(packageName);
+ }
+ catch
+ {
+ return false;
+ }
+
+ if (package == null)
+ return false;
+
+ if (package.version == null)
+ return false;
+
+ return package.version.StartsWith(version);
+ }
+ }
+
+ internal class Collab
+ {
+ static Collab s_instance = null;
+ public static Collab instance {
+ get
+ {
+ if (s_instance == null)
+ s_instance = new Collab();
+
+ LogObsolete.Log();
+ return s_instance;
+ }
+ }
+
+ Collab()
+ {
+ }
+
+ [Flags]
+ public enum Operation
+ {
+ Noop = 0,
+ Publish = 1 << 0,
+ Update = 1 << 1,
+ Revert = 1 << 2,
+ GoBack = 1 << 3,
+ Restore = 1 << 4,
+ Diff = 1 << 5,
+ ConflictDiff = 1 << 6,
+ Exclude = 1 << 7,
+ Include = 1 << 8,
+ ChooseMine = 1 << 9,
+ ChooseTheirs = 1 << 10,
+ ExternalMerge = 1 << 11,
+ }
+
+ [Flags]
+ public enum CollabStates : uint
+ {
+ kCollabNone = 0,
+ kCollabLocal = 1,
+ kCollabSynced = 1 << 1,
+ kCollabOutOfSync = 1 << 2,
+ kCollabIgnored = 1 << 3,
+ kCollabCheckedOutLocal = 1 << 4,
+ kCollabCheckedOutRemote = 1 << 5,
+ kCollabDeletedLocal = 1 << 6,
+ kCollabDeletedRemote = 1 << 7,
+ kCollabAddedLocal = 1 << 8,
+ kCollabAddedRemote = 1 << 9,
+ kCollabConflicted = 1 << 10,
+ kCollabMovedLocal = 1 << 11,
+ kCollabMovedRemote = 1 << 12,
+ kCollabUpdating = 1 << 13,
+ kCollabReadOnly = 1 << 14,
+ kCollabMetaFile = 1 << 15,
+ kCollabUseMine = 1 << 16,
+ kCollabUseTheir = 1 << 17,
+ kCollabMerged = 1 << 18,
+ kCollabPendingMerge = 1 << 19,
+ kCollabFolderMetaFile = 1 << 20,
+ KCollabContentChanged = 1 << 21,
+ KCollabContentConflicted = 1 << 22,
+ KCollabContentDeleted = 1 << 23,
+ kCollabInvalidState = 1 << 30,
+ kAnyLocalChanged = (kCollabAddedLocal | kCollabCheckedOutLocal | kCollabDeletedLocal | kCollabMovedLocal),
+ kAnyLocalEdited = (kCollabAddedLocal | kCollabCheckedOutLocal | kCollabMovedLocal),
+ kCollabAny = 0xFFFFFFFF
+ }
+
+ internal enum CollabStateID { None, Uninitialized, Initialized }
+
+ internal static class BindingsMarshaller
+ {
+ public static IntPtr ConvertToNative(Collab collab){ return IntPtr.Zero; }
+ }
+
+ public event StateChangedDelegate StateChanged;
+ public event StateChangedDelegate RevisionUpdated;
+ public event RevisionChangedDelegate RevisionUpdated_V2;
+ public event StateChangedDelegate JobsCompleted;
+ public event ErrorDelegate ErrorOccurred;
+ public event SetErrorDelegate ErrorOccurred_V2;
+ public event ErrorDelegate ErrorCleared;
+ public event ChangeItemsChangedDelegate ChangeItemsChanged;
+ public event ChangeItemsChangedDelegate SelectedChangeItemsChanged;
+ public event StateChangedDelegate CollabInfoChanged;
+ public static int GetRevisionsData(bool withChanges, int startIndex, int numRevisions){ return 0; }
+ public static int GetSingleRevisionData(bool withChanges, string id){ return 0; }
+ public static RevisionsData PopulateRevisionsData(IntPtr nativeData){ return new RevisionsData(); }
+ public static Revision PopulateSingleRevisionData(IntPtr nativeData){ return new Revision(); }
+ public static ShowToolbarAtPositionDelegate ShowToolbarAtPosition = null;
+ public static IsToolbarVisibleDelegate IsToolbarVisible = null;
+ public static CloseToolbarDelegate CloseToolbar = null;
+ public static ShowHistoryWindowDelegate ShowHistoryWindow = null;
+ public static ShowChangesWindowDelegate ShowChangesWindow = null;
+ public static string[] clientType = Array.Empty();
+ internal static string editorPrefCollabClientType = string.Empty;
+ public static string GetProjectClientType() { return string.Empty; }
+ public static void SetVersionControl(IVersionControl instance){}
+ internal static bool HasVersionControl(){ return false; }
+ internal static void ShowChangesWindowView(){}
+ internal static CollabStates GetAssetState(string assetGuid, string assetPath){ return (CollabStates)0; }
+ public static void OnSettingStatusChanged(CollabSettingType type, CollabSettingStatus status){}
+ public static bool InitializeSoftlocksViewController(){ return false; }
+ public static bool IsDiffToolsAvailable(){ return false; }
+ public static void SwitchToDefaultMode(){}
+ public static void OnProgressEnabledSettingStatusChanged(CollabSettingType type, CollabSettingStatus status){}
+
+ public CollabInfo collabInfo { get; }
+ public void SetSeat(bool value){}
+ public void RefreshSeatAvailabilityAsync(){}
+ public string GetProjectGUID(){ return string.Empty; }
+ public bool ShouldDoInitialCommit(){ return false; }
+ public void ShowDifferences(string path){}
+ public void SendNotification(){}
+ public void SetError(int errorCode){}
+ public void ClearError(int errorCode){}
+ public void ClearErrors(){}
+ public void ForceRefresh(bool refreshAssetDatabase){}
+ public void SetCollabEnabledForCurrentProject(bool enabled){}
+ public bool IsCollabEnabledForCurrentProject(){ return false; }
+ public bool IsAssetIgnored(string path){ return false; }
+ public bool ShouldTrackAsset(string path){ return false; }
+ public string GetProjectPath(){ return string.Empty; }
+ public bool IsConnected(){ return false; }
+ public bool AnyJobRunning(){ return false; }
+ public bool JobRunning(int a_jobID){ return false; }
+ public CollabStates GetAssetState(string guid){ return (CollabStates)0; }
+ public CollabStates GetSelectedAssetState(){ return (CollabStates)0; }
+ public CollabStateID GetCollabState(){ return (CollabStateID)0; }
+ public bool ValidateSelectiveCommit(){ return false; }
+ public void Disconnect(){}
+ public void CancelJobByType(int jobType, bool forceCancel){}
+ public void DoInitialCommit(){}
+ public void Update(string revisionID, bool updateToRevision){}
+ public void RevertFile(string path, bool forceOverwrite){}
+ public void RevertFiles(ChangeItem[] changeItems, bool forceOverwrite){}
+ public void LaunchConflictExternalMerge(string path){}
+ public void ShowConflictDifferences(string path){}
+ public void ResyncSnapshot(){}
+ public void GoBackToRevision(string revisionID, bool updateToRevision){}
+ public void ResyncToRevision(string revisionID){}
+ public Change[] GetCollabConflicts(){ return Array.Empty(); }
+ public void CheckConflictsResolvedExternal(){}
+ public bool AreTestsRunning(){ return false; }
+ public void SetTestsRunning(bool running){}
+ public void ClearAllFailures(){}
+ public void ClearNextOperationFailure(){}
+ public void ClearNextOperationFailureForFile(string path){}
+ public string GetGUIDForTests(){ return string.Empty; }
+ public void NewGUIDForTests(){}
+ public void FailNextOperation(Collab.Operation operation, int code){}
+ public void TimeOutNextOperation(Collab.Operation operation, int timeOutSec){}
+ public void FailNextOperationForFile(string path, Collab.Operation operation, int code){}
+ public void TimeOutNextOperationForFile(string path, Collab.Operation operation, int timeOutSec){}
+ public void TestPostSoftLockAsCollaborator(string projectGuid, string projectPath, string machineGuid, string assetGuid){}
+ public void TestClearSoftLockAsCollaborator(string projectGuid, string projectPath, string machineGuid, string softLockHash){}
+ internal bool GetErrorInternal(int errorFilter, out UnityErrorInfo info){ info = new UnityErrorInfo(); return false; }
+ public void Publish(string comment, bool useSelectedAssets, bool confirmMatchesPrevious){}
+ public void PublishAssetsAsync(string comment, ChangeItem[] changes){}
+ public void ClearSelectedChangesToPublish(){}
+ public void SendCollabInfoNotification(){}
+ public CollabFilters collabFilters = new CollabFilters();
+ public String projectBrowserSingleSelectionPath { get; set; }
+ public String projectBrowserSingleMetaSelectionPath { get; set; }
+ public string[] currentProjectBrowserSelection;
+ public void RefreshAvailableLocalChangesSynchronous(){}
+ public bool GetError(UnityConnect.UnityErrorFilter errorFilter, out UnityErrorInfo info){ info = new UnityErrorInfo(); return false; }
+ public void CancelJob(int jobType){}
+ public void UpdateEditorSelectionCache(){}
+ public CollabInfo GetCollabInfo(){ return new CollabInfo(); }
+ public void SaveAssets(){}
+ public void ShowInProjectBrowser(string filterString){}
+ public bool SetConflictsResolvedMine(string[] paths){ return false; }
+ public bool SetConflictsResolvedTheirs(string[] paths){ return false; }
+ public PublishInfo GetChangesToPublish() { return new PublishInfo(); }
+ public PublishInfo_V2 GetChangesToPublish_V2() { return new PublishInfo_V2(); }
+ public void SetChangesToPublish(ChangeItem[] changes){}
+ public ProgressInfo GetJobProgress(int jobId){ return new ProgressInfo(); }
+ }
+
+ internal enum CollabSettingType
+ {
+ InProgressEnabled = 0,
+ InProgressProjectEnabled = 1,
+ InProgressGlobalEnabled = 2
+ }
+
+ internal enum CollabSettingStatus
+ {
+ None = 0,
+ Available = 1
+ }
+
+ internal class CollabSettingsManager
+ {
+ public delegate void SettingStatusChanged(CollabSettingType type, CollabSettingStatus status);
+ public static Dictionary statusNotifier = new Dictionary();
+
+ static CollabSettingsManager(){}
+
+ public static bool IsAvailable(CollabSettingType type)
+ {
+ return false;
+ }
+
+ public static bool inProgressEnabled { get; }
+ }
+
+ internal class ProgressInfo
+ {
+ public enum ProgressType : uint
+ {
+ None = 0,
+ Count = 1,
+ Percent = 2,
+ Both = 3
+ }
+
+ public int jobId { get { return 0; } }
+ public string title { get { return string.Empty; } }
+ public string extraInfo { get { return string.Empty; } }
+ public int currentCount { get { return 0; } }
+ public int totalCount { get { return 0; } }
+ public bool completed { get { return true; } }
+ public bool cancelled { get { return false; } }
+ public bool canCancel { get { return false; } }
+ public string lastErrorString { get { return string.Empty; } }
+ public ulong lastError { get { return 0; } }
+ public int percentComplete { get{ return 0; } }
+ public bool isProgressTypeCount { get { return false; } }
+ public bool isProgressTypePercent { get { return false; } }
+ public bool errorOccured { get { return false; } }
+ }
+
+ internal class ChangeItem
+ {
+ public string Path { get; set; }
+ public Change.RevertableStates RevertableState { get; set; }
+ public string RelatedTo { get; set; }
+ public string RevisionId { get; set; }
+ public string Hash { get; set; }
+ public Collab.CollabStates State { get; set; }
+ public long Size { get; set; }
+ public string DownloadPath { get; set; }
+ public string FromPath { get; set; }
+ }
+
+ internal class PublishInfo
+ {
+ public Change[] changes;
+ public bool filter;
+ }
+
+ internal class PublishInfo_V2
+ {
+ public ChangeItem[] changes;
+ public bool filter;
+ }
+
+ internal class RevisionsResult
+ {
+ public List Revisions = new List();
+ public int RevisionsInRepo = -1;
+ public int Count { get { return 0; } }
+
+ public void Clear(){}
+ }
+
+ internal interface IRevisionsService
+ {
+ event RevisionsDelegate FetchRevisionsCallback;
+ void GetRevisions(int offset, int count);
+ string tipRevision { get; }
+ string currentUser { get; }
+ }
+
+ internal class RevisionsService : IRevisionsService
+ {
+ public event RevisionsDelegate FetchRevisionsCallback;
+ public event SingleRevisionDelegate FetchSingleRevisionCallback;
+
+ public string tipRevision { get { return string.Empty; } }
+ public string currentUser { get { return string.Empty; } }
+
+ public RevisionsService(Collab collabInstance, UnityConnect connectInstance)
+ {
+ }
+
+ public void GetRevisions(int offset, int count){}
+
+ public void GetRevision(string revId){}
+ }
+
+ internal class Change
+ {
+ public enum RevertableStates : uint
+ {
+ Revertable = 1 << 0,
+ NotRevertable = 1 << 1,
+ Revertable_File = 1 << 2,
+ Revertable_Folder = 1 << 3,
+ Revertable_EmptyFolder = 1 << 4,
+ NotRevertable_File = 1 << 5,
+ NotRevertable_Folder = 1 << 6,
+ NotRevertable_FileAdded = 1 << 7,
+ NotRevertable_FolderAdded = 1 << 8,
+ NotRevertable_FolderContainsAdd = 1 << 9,
+ InvalidRevertableState = (uint)1 << 31
+ }
+
+ public string path { get { return string.Empty; } }
+ public Collab.CollabStates state { get { return (Collab.CollabStates)0; } }
+ public bool isRevertable { get { return false; } }
+ public RevertableStates revertableState { get { return (RevertableStates)0; } }
+ public string relatedTo { get { return string.Empty; } }
+ public bool isMeta { get { return false; } }
+ public bool isConflict { get { return false; } }
+ public bool isFolderMeta { get { return false; } }
+ public bool isResolved { get { return false; } }
+ public string localStatus { get { return string.Empty; } }
+ public string remoteStatus { get { return string.Empty; } }
+ public string resolveStatus { get { return string.Empty; } }
+
+ internal bool HasState(Collab.CollabStates states)
+ {
+ return false;
+ }
+
+ internal bool HasRevertableState(RevertableStates revertableStates)
+ {
+ return false;
+ }
+ }
+
+ internal abstract class AbstractFilters
+ {
+ public List filters { get; set;}
+ public abstract void InitializeFilters();
+ public bool ContainsSearchFilter(string name, string searchString){ return false; }
+ public void ShowInFavoriteSearchFilters(){}
+ public void HideFromFavoriteSearchFilters(){}
+ }
+
+ internal class CollabFilters : AbstractFilters
+ {
+ public override void InitializeFilters(){}
+ public void ShowInProjectBrowser(string filterString){}
+ public void OnCollabStateChanged(CollabInfo info){}
+ }
+
+
+ internal delegate void StateChangedDelegate(CollabInfo info);
+ internal delegate void RevisionChangedDelegate(CollabInfo info, string rev, string action);
+ internal delegate void SetErrorDelegate(UnityErrorInfo error);
+ internal delegate void ErrorDelegate();
+ internal delegate bool ShowToolbarAtPositionDelegate(Rect screenRect);
+ internal delegate bool IsToolbarVisibleDelegate();
+ internal delegate void ShowHistoryWindowDelegate();
+ internal delegate void ShowChangesWindowDelegate();
+ internal delegate void CloseToolbarDelegate();
+ internal delegate void ChangesChangedDelegate(Change[] changes, bool isFiltered);
+ internal delegate void ChangeItemsChangedDelegate(ChangeItem[] changes, bool isFiltered);
+ delegate void RevisionsDelegate(RevisionsResult revisionsResult);
+ delegate void SingleRevisionDelegate(Revision? revision);
+
+ internal struct CollabInfo
+ {
+ public bool ready { get { return true; } }
+ public bool update { get { return false; } }
+ public bool publish { get { return false; } }
+ public bool inProgress { get { return false; } }
+ public bool maintenance { get { return false; } }
+ public bool conflict { get { return false; } }
+ public bool refresh { get { return false; } }
+ public bool seat { get { return false; } }
+ public string tip { get { return string.Empty; } }
+ public bool Equals(CollabInfo other){ return false; }
+ }
+
+ internal struct ChangeAction
+ {
+ public ChangeAction(string path = "", string action = ""){}
+ public string path { get { return string.Empty; } }
+ public string action { get { return string.Empty; } }
+ }
+
+ internal struct Revision
+ {
+ internal Revision(string revisionID = "", string authorName = "", string author = "", string comment = "", string reference = "", ulong timeStamp = 0, bool isObtained = false, ChangeAction[] entries = null, CloudBuildStatus[] buildStatuses = null){}
+ public string authorName { get { return string.Empty; } }
+ public string author { get { return string.Empty; } }
+ public string comment { get { return string.Empty; } }
+ public string revisionID { get { return string.Empty; } }
+ public string reference { get { return string.Empty; } }
+ public ulong timeStamp { get { return 0; } }
+ public bool isObtained { get { return false; } }
+ public ChangeAction[] entries { get { return Array.Empty(); } }
+ public CloudBuildStatus[] buildStatuses { get { return Array.Empty(); } }
+ }
+
+ internal struct CloudBuildStatus
+ {
+ internal CloudBuildStatus(string platform = "", bool complete = false, bool success = false){}
+ public string platform { get { return string.Empty; } }
+ public bool complete { get { return false; } }
+ public bool success { get { return false; } }
+ }
+
+ internal struct RevisionData
+ {
+ public string id;
+ public int index;
+ public DateTime timeStamp;
+ public string authorName;
+ public string comment;
+ public bool obtained;
+ public bool current;
+ public bool inProgress;
+ public bool enabled;
+ public BuildState buildState;
+ public int buildFailures;
+ public ICollection changes;
+ public int changesTotal;
+ public bool changesTruncated;
+ }
+
+ internal struct RevisionsData
+ {
+ public int RevisionsInRepo {get { return 0; }}
+ public int RevisionOffset {get { return 0; }}
+ public int ReturnedRevisions {get { return 0; }}
+ public Revision[] Revisions {get { return Array.Empty(); }}
+ }
+
+ internal enum HistoryState
+ {
+ Error,
+ Offline,
+ Maintenance,
+ LoggedOut,
+ NoSeat,
+ Disabled,
+ Waiting,
+ Ready,
+ }
+
+ internal enum BuildState
+ {
+ None,
+ Configure,
+ Success,
+ Failed,
+ InProgress,
+ }
+
+ internal struct ChangeData
+ {
+ public string path;
+ public string action;
+ }
+}
diff --git a/Editor/Mono/Collab/IVersionControl.cs b/Editor/Mono/Collab/IVersionControl.cs
index e636800498..14a9ad00bd 100644
--- a/Editor/Mono/Collab/IVersionControl.cs
+++ b/Editor/Mono/Collab/IVersionControl.cs
@@ -10,9 +10,7 @@ internal interface IVersionControl
bool SupportsAsyncChanges();
bool OnEnableVersionControl();
void OnDisableVersionControl();
- ChangeItem[] GetChanges();
void MergeDownloadedFiles(bool isFullDownload);
- Collab.CollabStates GetAssetState(string assetGuid, string assetPath);
}
internal interface IVersionControl_V2 : IVersionControl
diff --git a/Editor/Mono/Collab/RevisionsService.cs b/Editor/Mono/Collab/RevisionsService.cs
deleted file mode 100644
index 56bea66492..0000000000
--- a/Editor/Mono/Collab/RevisionsService.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System;
-using System.Collections.Generic;
-using UnityEditor.Collaboration;
-using UnityEditor.Connect;
-using UnityEngine;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- delegate void RevisionsDelegate(RevisionsResult revisionsResult);
- delegate void SingleRevisionDelegate(Revision? revision);
- internal class RevisionsResult
- {
- public List Revisions = new List();
- public int RevisionsInRepo = -1;
-
- public int Count { get { return Revisions.Count; } }
-
- public void Clear()
- {
- Revisions.Clear();
- RevisionsInRepo = -1;
- }
- }
-
- internal interface IRevisionsService
- {
- event RevisionsDelegate FetchRevisionsCallback;
- void GetRevisions(int offset, int count);
- string tipRevision { get; }
- string currentUser { get; }
- }
-
- internal class RevisionsService : IRevisionsService
- {
- public event RevisionsDelegate FetchRevisionsCallback;
- public event SingleRevisionDelegate FetchSingleRevisionCallback;
-
- protected Collab collab;
- protected UnityConnect connect;
- private static RevisionsService instance;
-
- public string tipRevision { get { return collab.collabInfo.tip; } }
- public string currentUser { get { return connect.GetUserInfo().userName; } }
-
- public RevisionsService(Collab collabInstance, UnityConnect connectInstance)
- {
- collab = collabInstance;
- connect = connectInstance;
- instance = this;
- }
-
- public void GetRevisions(int offset, int count)
- {
- // Only send down request for the desired data.
- Collab.GetRevisionsData(true, offset, count);
- }
-
- public void GetRevision(string revId)
- {
- Collab.GetSingleRevisionData(true, revId);
- }
-
- [RequiredByNativeCode]
- private static void onFetchSingleRevision(IntPtr ptr)
- {
- Revision? ret = null;
- if (instance.FetchSingleRevisionCallback != null && ptr != IntPtr.Zero)
- {
- Revision nativeStruct = Collab.PopulateSingleRevisionData(ptr);
- // this copies the content as it's a struct not a class.
- ret = nativeStruct;
- }
-
- instance.FetchSingleRevisionCallback(ret);
- }
-
- [RequiredByNativeCode]
- private static void OnFetchRevisions(IntPtr nativeData)
- {
- RevisionsService service = instance;
- if (service == null || service.FetchRevisionsCallback == null)
- return;
-
- RevisionsResult history = null;
- if (nativeData != IntPtr.Zero)
- {
- RevisionsData data = Collab.PopulateRevisionsData(nativeData);
- history = new RevisionsResult();
- history.Revisions.AddRange(data.Revisions);
- history.RevisionsInRepo = data.RevisionsInRepo;
- }
-
- service.FetchRevisionsCallback(history);
- }
- }
-}
diff --git a/Editor/Mono/Collab/Softlocks/CollabSoftLocks.cs b/Editor/Mono/Collab/Softlocks/CollabSoftLocks.cs
deleted file mode 100644
index 44574720dc..0000000000
--- a/Editor/Mono/Collab/Softlocks/CollabSoftLocks.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System.Runtime.InteropServices;
-using UnityEngine.Bindings;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- // Keep internal and undocumented until we expose more functionality
- //*undocumented
- [StructLayout(LayoutKind.Sequential)]
- [NativeType(CodegenOptions = CodegenOptions.Custom, Header = "Editor/Src/Collab/Softlocks/CollabSoftLock.h",
- IntermediateScriptingStructName = "ScriptingSoftLock")]
- [NativeHeader("Editor/Src/Collab/Collab.bindings.h")]
- [NativeAsStruct]
- internal class SoftLock
- {
- string m_UserID;
- string m_MachineID;
- string m_DisplayName;
- ulong m_TimeStamp;
- string m_Hash;
-
- SoftLock() {}
-
- public string userID { get { return m_UserID; } }
- public string machineID { get { return m_MachineID; } }
- public string displayName { get { return m_DisplayName; } }
- public ulong timeStamp { get { return m_TimeStamp; } }
- public string hash { get { return m_Hash; } }
- }
-}
-
diff --git a/Editor/Mono/Collab/Softlocks/SoftlockData.cs b/Editor/Mono/Collab/Softlocks/SoftlockData.cs
deleted file mode 100644
index 759a931cd0..0000000000
--- a/Editor/Mono/Collab/Softlocks/SoftlockData.cs
+++ /dev/null
@@ -1,166 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System;
-using System.Collections.Generic;
-using UnityEngine.SceneManagement;
-using UnityEngine.Scripting;
-
-namespace UnityEditor.Collaboration
-{
- // Access and query the current set of softlock data.
- internal static class SoftLockData
- {
- internal delegate void OnSoftlockUpdate(string[] assetGUIDs);
- internal static OnSoftlockUpdate SoftlockSubscriber = null;
-
- // Invoked from C++
- [RequiredByNativeCode]
- public static void SetSoftlockChanges(string[] assetGUIDs)
- {
- if (null != SoftlockSubscriber)
- {
- SoftlockSubscriber(assetGUIDs);
- }
- }
-
- // Returns whether the given object has soft lock support
- // (i.e. is tracked in the back-end for simultaneous changes).
- // Note: Scene is supported, but isn't a Unity Object.
- public static bool AllowsSoftLocks(UnityEngine.Object unityObject)
- {
- if (unityObject == null)
- {
- throw new ArgumentNullException("unityObject");
- }
-
- bool supportsSoftLocks = false;
- if (unityObject.GetType().Equals(typeof(SceneAsset)))
- {
- supportsSoftLocks = true;
- }
- else
- {
- supportsSoftLocks = IsPrefab(unityObject);
- }
- return supportsSoftLocks;
- }
-
- public static bool IsPrefab(UnityEngine.Object unityObject)
- {
- return PrefabUtility.IsPartOfAnyPrefab(unityObject);
- }
-
- public static bool IsPrefab(string assetGUID)
- {
- bool isPrefab = false;
- UnityEngine.Object unityObject;
- if (AssetAccess.TryGetAssetFromGUID(assetGUID, out unityObject))
- {
- isPrefab = IsPrefab(unityObject);
- }
- return isPrefab;
- }
-
- // Soft locks are present when collab is enabled and other users are
- // editing the given object.
- // Failure: assigns false to 'hasSoftLocks', returns false.
- // Success: assigns true or false to 'hasSoftLocks', returns true.
- public static bool TryHasSoftLocks(UnityEngine.Object objectWithGUID, out bool hasSoftLocks)
- {
- string assetGuid = null;
- AssetAccess.TryGetAssetGUIDFromObject(objectWithGUID, out assetGuid);
- bool success = TryHasSoftLocks(assetGuid, out hasSoftLocks);
- return success;
- }
-
- public static bool TryHasSoftLocks(string assetGuid, out bool hasSoftLocks)
- {
- hasSoftLocks = false;
- bool success = false;
- int count = 0;
-
- if (TryGetSoftlockCount(assetGuid, out count))
- {
- success = true;
- hasSoftLocks = (count > 0);
- }
- return success;
- }
-
- // Provides the number of additional users editing the given scene.
- // Failure: assigns 0 to count, return false.
- // Success: assigns a value in [0, n] to count, returns true.
- public static bool TryGetSoftlockCount(Scene scene, out int count)
- {
- bool success = false;
- count = 0;
-
- if (!scene.IsValid())
- {
- return false;
- }
- string assetGUID = AssetDatabase.AssetPathToGUID(scene.path);
- success = TryGetSoftlockCount(assetGUID, out count);
- return success;
- }
-
- // Provides the number of additional users editing the given object.
- // Failure: assigns 0 to count, return false.
- // Success: assigns a value in [0, n] to count, returns true.
- public static bool TryGetSoftlockCount(UnityEngine.Object objectWithGUID, out int count)
- {
- string assetGUID = null;
- AssetAccess.TryGetAssetGUIDFromObject(objectWithGUID, out assetGUID);
- bool success = TryGetSoftlockCount(assetGUID, out count);
- return success;
- }
-
- // Provides the number of additional users editing the given 'assetGUID'.
- // Failure: assigns 0 to count, return false.
- // Success: assigns a value in [0, n] to count, returns true.
- public static bool TryGetSoftlockCount(string assetGuid, out int count)
- {
- bool success = false;
- count = 0;
- List softLocks = null;
-
- if (TryGetLocksOnAssetGUID(assetGuid, out softLocks))
- {
- count = softLocks.Count;
- success = true;
- }
- return success;
- }
-
- // Provides a list of 'SoftLock' items, representing
- // the additional users editing the given assetGUID.
- // Failure: assigns empty list to 'softLocks', return false.
- // Success: assigns the retrieved list to 'softLocks', return true. (May be empty).
- public static bool TryGetLocksOnAssetGUID(string assetGuid, out List softLocks)
- {
- if (assetGuid == null)
- {
- throw new ArgumentNullException("assetGuid");
- }
-
- if (!Collab.instance.IsCollabEnabledForCurrentProject() || assetGuid.Length == 0)
- {
- softLocks = new List();
- return false;
- }
-
- SoftLock[] _softlocks = Collab.instance.GetSoftLocks(assetGuid);
- softLocks = new List();
-
- for (int index = 0; index < _softlocks.Length; index++)
- {
- softLocks.Add(_softlocks[index]);
- }
- return true;
- }
- }
-}
-
diff --git a/Editor/Mono/Collab/Softlocks/SoftlockFilter.cs b/Editor/Mono/Collab/Softlocks/SoftlockFilter.cs
deleted file mode 100644
index a1a56d4571..0000000000
--- a/Editor/Mono/Collab/Softlocks/SoftlockFilter.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using UnityEditor;
-
-namespace UnityEditor.Collaboration
-{
- internal class SoftLockFilters : AbstractFilters
- {
- public override void InitializeFilters()
- {
- filters = new List()
- {
- new string[] { "All In Progress" , "s:inprogress"},
- };
- }
-
- public SoftLockFilters()
- {
- InitializeFilters();
- }
-
- public void OnSettingStatusChanged(CollabSettingType type, CollabSettingStatus status)
- {
- if (type == CollabSettingType.InProgressEnabled && (status == CollabSettingStatus.Available))
- {
- if (Collab.instance.IsCollabEnabledForCurrentProject() && CollabSettingsManager.inProgressEnabled)
- ShowInFavoriteSearchFilters();
- else
- HideFromFavoriteSearchFilters();
- }
- }
- }
-}
diff --git a/Editor/Mono/Collab/Softlocks/SoftlockUIData.cs b/Editor/Mono/Collab/Softlocks/SoftlockUIData.cs
deleted file mode 100644
index e0d8c1df20..0000000000
--- a/Editor/Mono/Collab/Softlocks/SoftlockUIData.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using System;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.SceneManagement;
-using UnityEditor.SceneManagement;
-using UnityEditor.Web;
-
-namespace UnityEditor.Collaboration
-{
- // Composes Softlock data into structures used by the UI.
- internal static class SoftLockUIData
- {
- private static Dictionary s_ImageCache = new Dictionary();
- private static Dictionary s_ImageNameCache = new Dictionary();
- private const string kIconMipSuffix = " Icon";
-
- public enum SectionEnum
- {
- None,
- Inspector,
- Scene,
- ProjectBrowser
- }
-
- #region General
-
- // Provides the names of all additional users editing the asset
- // with the given 'assetGuid'.
- // Defaults to an empty list.
- public static List GetLocksNamesOnAsset(string assetGuid)
- {
- List softLocks = null;
- List names = new List();
-
- if (SoftLockData.TryGetLocksOnAssetGUID(assetGuid, out softLocks))
- {
- foreach (SoftLock softLock in softLocks)
- {
- names.Add(softLock.displayName);
- }
- }
- return names;
- }
-
- #endregion
- #region Scene
-
- // Provides the names of all additional users editing the scene.
- // Defaults to an empty list.
- public static List GetLocksNamesOnScene(Scene scene)
- {
- List names = GetLockNamesOnScenePath(scene.path);
- return names;
- }
-
- public static List GetLockNamesOnScenePath(string scenePath)
- {
- string assetGuid = AssetDatabase.AssetPathToGUID(scenePath);
- List names = GetLocksNamesOnAsset(assetGuid);
- return names;
- }
-
- public static string GetSceneNameFromPath(string scenePath)
- {
- string name = "";
- if (null != scenePath)
- {
- name = scenePath;
- }
- return name;
- }
-
- // Provides the names of all additional users editing each scene.
- // Defaults to an empty list, and may contain empty sub-lists.
- public static List> GetLockNamesOnScenes(List scenes)
- {
- List> namesByScene = new List>();
-
- if (scenes == null)
- {
- return namesByScene;
- }
-
- foreach (Scene scene in scenes)
- {
- List names = GetLocksNamesOnScene(scene);
- namesByScene.Add(names);
- }
- return namesByScene;
- }
-
- // For each iteration, returns the pair (scene name : list of other users' names).
- public static IEnumerable>> GetLockNamesOnOpenScenes()
- {
- if (Collab.instance.IsCollabEnabledForCurrentProject())
- {
- for (int sceneIndex = 0; sceneIndex < EditorSceneManager.sceneCount; sceneIndex++)
- {
- Scene scene = SceneManager.GetSceneAt(sceneIndex);
- List names = GetLocksNamesOnScene(scene);
- string sceneName = scene.name;
- if (String.IsNullOrEmpty(sceneName))
- {
- // Default for unnamed scenes.
- sceneName = "Untitled";
- }
- KeyValuePair> sceneData = new KeyValuePair>(sceneName, names);
- yield return sceneData;
- }
- }
- }
-
- public static int CountOfLocksOnOpenScenes()
- {
- int count = 0;
-
- foreach (KeyValuePair> sceneData in GetLockNamesOnOpenScenes())
- {
- count += sceneData.Value.Count;
- }
- return count;
- }
-
- #endregion
- #region Game Object
-
- // The usernames of additional people editing the given 'objectWithGUID'.
- // Defaults to an empty list.
- public static List GetLockNamesOnObject(UnityEngine.Object objectWithGUID)
- {
- string assetGUID = null;
- AssetAccess.TryGetAssetGUIDFromObject(objectWithGUID, out assetGUID);
- List names = GetLocksNamesOnAsset(assetGUID);
- return names;
- }
-
- #endregion
- #region Icons
-
- // The icon for the particular section in the editor.
- // Defaults to null.
- public static Texture GetIconForSection(SectionEnum section)
- {
- string iconName = IconNameForSection(section);
- Texture texture = GetIconForName(iconName);
- return texture;
- }
-
- private static string IconNameForSection(SectionEnum section)
- {
- string iconName;
- if (!s_ImageNameCache.TryGetValue(section, out iconName))
- {
- switch (section)
- {
- case SectionEnum.Inspector:
- case SectionEnum.Scene:
- iconName = "SoftlockInline.png";
- break;
-
- case SectionEnum.ProjectBrowser:
- iconName = String.Format("SoftlockProjectBrowser{0}", kIconMipSuffix);
- break;
-
- default:
- return null;
- }
- s_ImageNameCache.Add(section, iconName);
- }
- return iconName;
- }
-
- private static Texture GetIconForName(string fileName)
- {
- if (String.IsNullOrEmpty(fileName))
- {
- return null;
- }
-
- Texture texture;
- // Note: a previous texture may have been destroyed
- // by the system on the c++ side.
- if (!s_ImageCache.TryGetValue(fileName, out texture) || texture == null)
- {
- if (fileName.EndsWith(kIconMipSuffix))
- {
- texture = EditorGUIUtility.FindTexture(fileName) as Texture;
- }
- else
- {
- texture = EditorGUIUtility.LoadIconRequired(fileName) as Texture;
- }
- s_ImageCache.Remove(fileName);
- s_ImageCache.Add(fileName, texture);
- }
- return texture;
- }
-
- #endregion
- }
-}
-
diff --git a/Editor/Mono/Collab/Softlocks/SoftlockViewController.cs b/Editor/Mono/Collab/Softlocks/SoftlockViewController.cs
deleted file mode 100644
index e4de3221f8..0000000000
--- a/Editor/Mono/Collab/Softlocks/SoftlockViewController.cs
+++ /dev/null
@@ -1,533 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-
-using UnityEngine;
-using System.Collections.Generic;
-using UnityEditor.Collaboration;
-using UnityEngine.SceneManagement;
-using UnityEditor.SceneManagement;
-using System;
-using UnityEditor.Web;
-
-namespace UnityEditor
-{
- // Displays the Softlocks UI in the various areas of the Editor.
- internal class SoftlockViewController
- {
- private static SoftlockViewController s_Instance;
- public GUIStyle k_Style = null;
- public GUIStyle k_StyleEmpty = GUIStyle.none; // For tooltips only.
- public GUIContent k_Content = null;
-
- // Stores UI strings for reuse and Editor (inspector) references to trigger
- // a repaint when softlock data changes.
- private SoftlockViewController.Cache m_Cache = null;
-
- private const string k_TooltipHeader = "Unpublished changes by:";
- private const string k_TooltipPrefabHeader = "Unpublished Prefab changes by:";
- private const string k_TooltipNamePrefix = " \n \u2022 "; // u2022 displays a • (bullet point)
-
- private SoftlockViewController() {}
- ~SoftlockViewController() {}
-
- [SerializeField]
- private SoftLockFilters m_SoftLockFilters = new SoftLockFilters();
-
- public SoftLockFilters softLockFilters { get { return m_SoftLockFilters; } }
-
- public static SoftlockViewController Instance
- {
- get
- {
- if (s_Instance == null)
- {
- s_Instance = new SoftlockViewController();
- s_Instance.m_Cache = new Cache();
- }
- return s_Instance;
- }
- }
-
- // Initialises dependencies.
- public void TurnOn()
- {
- RegisterDataDelegate();
- RegisterDrawDelegates();
- Repaint();
- }
-
- public void TurnOff()
- {
- UnregisterDataDelegate();
- UnregisterDrawDelegates();
- }
-
- private void UnregisterDataDelegate()
- {
- SoftLockData.SoftlockSubscriber -= Instance.OnSoftlockUpdate;
- }
-
- private void RegisterDataDelegate()
- {
- UnregisterDataDelegate();
- SoftLockData.SoftlockSubscriber += Instance.OnSoftlockUpdate;
- }
-
- private void UnregisterDrawDelegates()
- {
- ObjectListArea.postAssetIconDrawCallback -= Instance.DrawProjectBrowserGridUI;
- ObjectListArea.postAssetLabelDrawCallback -= Instance.DrawProjectBrowserListUI;
- Editor.OnPostIconGUI -= Instance.DrawInspectorUI;
- GameObjectTreeViewGUI.OnPostHeaderGUI -= Instance.DrawSceneUI;
- }
-
- // Connects to the areas of the Editor that display softlocks.
- private void RegisterDrawDelegates()
- {
- UnregisterDrawDelegates();
- ObjectListArea.postAssetIconDrawCallback += Instance.DrawProjectBrowserGridUI;
- ObjectListArea.postAssetLabelDrawCallback += Instance.DrawProjectBrowserListUI;
- AssetsTreeViewGUI.postAssetLabelDrawCallback += Instance.DrawSingleColumnProjectBrowserUI;
- Editor.OnPostIconGUI += Instance.DrawInspectorUI;
- GameObjectTreeViewGUI.OnPostHeaderGUI += Instance.DrawSceneUI;
- }
-
- // Returns true when the 'editor' supports Softlock UI and the
- // user has Collaborate permissions.
- private bool HasSoftlockSupport(Editor editor)
- {
- if (!Collab.instance.IsCollabEnabledForCurrentProject() || editor == null || editor.targets.Length > 1)
- {
- return false;
- }
-
- if (editor.target == null || !SoftLockData.AllowsSoftLocks(editor.target))
- {
- return false;
- }
-
- // Support Scene and Game object Inspector headers, not others like MaterialEditor.
- bool hasSupport = true;
- Type editorType = editor.GetType();
-
- if (editorType != typeof(GameObjectInspector) && editorType != typeof(GenericInspector))
- {
- hasSupport = false;
- }
-
- return hasSupport;
- }
-
- private bool HasSoftlocks(string assetGUID)
- {
- if (!Collab.instance.IsCollabEnabledForCurrentProject())
- {
- return false;
- }
-
- bool hasSoftLocks;
- bool isValid = (SoftLockData.TryHasSoftLocks(assetGUID, out hasSoftLocks) && hasSoftLocks);
- return isValid;
- }
-
- // Redraws softlock UI associated with the given list of 'assetGUIDs'.
- public void OnSoftlockUpdate(string[] assetGUIDs)
- {
- // Remove cached UI for the assetGUIDs before triggered a redraw.
- m_Cache.InvalidateAssetGUIDs(assetGUIDs);
- Repaint();
- }
-
- // Repaints all the areas where softlocks are displayed.
- public void Repaint()
- {
- RepaintInspectors();
- RepaintSceneHierarchy();
- RepaintProjectBrowsers();
- }
-
- private void RepaintSceneHierarchy()
- {
- List sceneUIs = SceneHierarchyWindow.GetAllSceneHierarchyWindows();
- foreach (SceneHierarchyWindow sceneUI in sceneUIs)
- {
- sceneUI.Repaint();
- }
- }
-
- private void RepaintInspectors()
- {
- foreach (Editor editor in m_Cache.GetEditors())
- {
- // Does not repaint when editor is not visible, but the editor's
- // "DockArea" tab will redraw either way.
- editor.Repaint();
- }
- }
-
- private void RepaintProjectBrowsers()
- {
- foreach (ProjectBrowser pb in ProjectBrowser.GetAllProjectBrowsers())
- {
- pb.RefreshSearchIfFilterContains("s:");
- pb.Repaint();
- }
- }
-
- // Draws in the Hierarchy header, left of the context menu.
- public float DrawSceneUI(Rect availableRect, string scenePath)
- {
- string assetGUID = AssetDatabase.AssetPathToGUID(scenePath);
- if (!HasSoftlocks(assetGUID))
- {
- return availableRect.xMax;
- }
-
- int lockCount;
- SoftLockData.TryGetSoftlockCount(assetGUID, out lockCount);
-
- GUIContent content = GetGUIContent();
- content.image = SoftLockUIData.GetIconForSection(SoftLockUIData.SectionEnum.Scene);
- content.text = GetDisplayCount(lockCount);
- content.tooltip = Instance.GetTooltip(assetGUID);
-
- Vector2 contentSize = GetStyle().CalcSize(content);
- Rect drawRect = new Rect(availableRect.position, contentSize);
- const int kRightMargin = 4;
- drawRect.x = (availableRect.width - drawRect.width) - kRightMargin;
- EditorGUI.LabelField(drawRect, content);
-
- return drawRect.xMin;
- }
-
- // Assigned as a callback to Editor.OnPostHeaderGUI
- // Draws the Scene Inspector (Editor.cs) as well as the Game Object Inspector (GameObjectInspector.cs)
- private void DrawInspectorUI(Editor editor, Rect drawRect)
- {
- if (!HasSoftlockSupport(editor))
- {
- return;
- }
-
- m_Cache.StoreEditor(editor);
- string assetGUID = null;
- AssetAccess.TryGetAssetGUIDFromObject(editor.target, out assetGUID);
-
- if (!HasSoftlocks(assetGUID))
- {
- return;
- }
-
- Texture icon = SoftLockUIData.GetIconForSection(SoftLockUIData.SectionEnum.ProjectBrowser);
- if (icon != null)
- {
- DrawIconWithTooltips(drawRect, icon, assetGUID);
- }
- }
-
- // Assigned callback to ObjectListArea.OnPostAssetDrawDelegate.
- // Draws either overtop of the project browser asset (when in grid view).
- private void DrawProjectBrowserGridUI(Rect iconRect, string assetGUID, bool isListMode)
- {
- if (isListMode || !HasSoftlocks(assetGUID))
- {
- return;
- }
-
- Rect drawRect = Rect.zero;
- Texture icon = SoftLockUIData.GetIconForSection(SoftLockUIData.SectionEnum.ProjectBrowser);
- if (icon != null)
- {
- drawRect = Overlay.GetRectForBottomRight(iconRect, Overlay.k_OverlaySizeOnLargeIcon);
- DrawIconWithTooltips(drawRect, icon, assetGUID);
- }
- }
-
- // Should draw only in listMode and expects 'drawRect' to be the designed space for the icon,
- // and not the entire row.
- private bool DrawProjectBrowserListUI(Rect drawRect, string assetGUID, bool isListMode)
- {
- if (!isListMode || !HasSoftlocks(assetGUID))
- {
- return false;
- }
-
- // center icon.
- Rect iconRect = drawRect;
- iconRect.width = drawRect.height;
- iconRect.x = (float)Math.Round(drawRect.center.x - (iconRect.width / 2F));
- return DrawInProjectBrowserListMode(iconRect, assetGUID);
- }
-
- // Expects 'drawRect' to be the available width of the row.
- private bool DrawSingleColumnProjectBrowserUI(Rect drawRect, string assetGUID)
- {
- if (ProjectBrowser.s_LastInteractedProjectBrowser.IsTwoColumns() || !HasSoftlocks(assetGUID))
- {
- return false;
- }
-
- Rect iconRect = drawRect;
- iconRect.width = drawRect.height;
- float spacingFromEnd = (iconRect.width / 2F);
- iconRect.x = (float)Math.Round(drawRect.xMax - iconRect.width - spacingFromEnd);
- return DrawInProjectBrowserListMode(iconRect, assetGUID);
- }
-
- private bool DrawInProjectBrowserListMode(Rect iconRect, string assetGUID)
- {
- Texture icon = SoftLockUIData.GetIconForSection(SoftLockUIData.SectionEnum.ProjectBrowser);
- bool didDraw = false;
- if (icon != null)
- {
- DrawIconWithTooltips(iconRect, icon, assetGUID);
- didDraw = true;
- }
- return didDraw;
- }
-
- private void DrawIconWithTooltips(Rect iconRect, Texture icon, string assetGUID)
- {
- GUI.DrawTexture(iconRect, icon, ScaleMode.ScaleToFit);
- DrawTooltip(iconRect, GetTooltip(assetGUID));
- }
-
- private void DrawTooltip(Rect frame, string tooltip)
- {
- GUIContent content = GetGUIContent();
- content.tooltip = tooltip;
- GUI.Label(frame, content, k_StyleEmpty);
- }
-
- #region String Helpers
-
- // Returns a string formatted as a vertical list of names with a heading.
- private string GetTooltip(string assetGUID)
- {
- string formattedText;
- if (!m_Cache.TryGetTooltipForGUID(assetGUID, out formattedText))
- {
- List softLockNames = SoftLockUIData.GetLocksNamesOnAsset(assetGUID);
- string tooltipHeaderText = (SoftLockData.IsPrefab(assetGUID) ? k_TooltipPrefabHeader : k_TooltipHeader);
- formattedText = tooltipHeaderText;
-
- foreach (string name in softLockNames)
- {
- formattedText += k_TooltipNamePrefix + name + " ";
- }
- m_Cache.StoreTooltipForGUID(assetGUID, formattedText);
- }
- return formattedText;
- }
-
- // Retrieves a previously generated string from cache
- // or creates a string displaying the given 'count' surrounded by brackets.
- // e.g. "(0)"
- private static string GetDisplayCount(int count)
- {
- string totalLocksText;
- if (!Instance.m_Cache.TryGetDisplayCount(count, out totalLocksText))
- {
- totalLocksText = count.ToString();
- Instance.m_Cache.StoreDisplayCount(count, totalLocksText);
- }
- return totalLocksText;
- }
-
- // When the given 'text' exceeds the given 'width', out-of-bound characters
- // are removed as well as a few more to display a trailing ellipsis.
- // If 'text' does not exceed width, text is returned.
- private string FitTextToWidth(string text, float width, GUIStyle style)
- {
- int characterCountVisible = style.GetNumCharactersThatFitWithinWidth(text, width);
- if (characterCountVisible > 1 && characterCountVisible != text.Length)
- {
- string ellipsedText;
- int characterLength = (characterCountVisible - 1);
- if (!Instance.m_Cache.TryGetEllipsedNames(text, characterLength, out ellipsedText))
- {
- ellipsedText = text.Substring(0, characterLength) + (" \u2026"); // 'horizontal ellipsis' (U+2026) is: ...
- Instance.m_Cache.StoreEllipsedNames(text, ellipsedText, characterLength);
- }
- return ellipsedText;
- }
- return text;
- }
-
- #endregion
- #region GUI Content
-
- public GUIContent GetGUIContent()
- {
- if (k_Content == null)
- {
- k_Content = new GUIContent();
- }
-
- k_Content.tooltip = string.Empty;
- k_Content.text = null;
- k_Content.image = null;
-
- return k_Content;
- }
-
- public GUIStyle GetStyle()
- {
- if (k_Style == null)
- {
- k_Style = new GUIStyle(EditorStyles.label);
- k_Style.normal.background = null;
- }
- return k_Style;
- }
-
- #endregion
-
- // Stores UI strings for reuse and Editors as WeakReferences.
- private class Cache
- {
- private List m_EditorReferences = new List();
- private List m_CachedWeakReferences = new List();
- private static Dictionary s_CachedStringCount = new Dictionary();
- private Dictionary m_AssetGUIDToTooltip = new Dictionary();
- private Dictionary> m_NamesListToEllipsedNames = new Dictionary>();
-
- public Cache() {}
-
- // Removes cached strings references by the given 'assetGUIDs'.
- public void InvalidateAssetGUIDs(string[] assetGUIDs)
- {
- for (int index = 0; index < assetGUIDs.Length; index++)
- {
- string assetGUID = assetGUIDs[index];
- m_AssetGUIDToTooltip.Remove(assetGUID);
- }
- }
-
- // Failure: assigns empty string ("") to 'ellipsedNames', returns false.
- // Success: assigns the cached string to 'ellipsedNames', returns true.
- public bool TryGetEllipsedNames(string allNames, int characterLength, out string ellipsedNames)
- {
- Dictionary ellipsedVersions;
- if (m_NamesListToEllipsedNames.TryGetValue(allNames, out ellipsedVersions))
- {
- return ellipsedVersions.TryGetValue(characterLength, out ellipsedNames);
- }
- ellipsedNames = "";
- return false;
- }
-
- // 'allNames' and 'characterLength' will be the keys to access the cached 'ellipsedNames'
- // see TryGetEllipsedNames() for retrieval.
- public void StoreEllipsedNames(string allNames, string ellipsedNames, int characterLength)
- {
- Dictionary ellipsedVersions;
- if (!m_NamesListToEllipsedNames.TryGetValue(allNames, out ellipsedVersions))
- {
- ellipsedVersions = new Dictionary();
- }
- ellipsedVersions[characterLength] = ellipsedNames;
- m_NamesListToEllipsedNames[allNames] = ellipsedVersions;
- }
-
- // Failure: assigns empty string ("") to 'tooltipText', returns false.
- // Success: assigns the cached string to 'tooltipText', returns true.
- public bool TryGetTooltipForGUID(string assetGUID, out string tooltipText)
- {
- return m_AssetGUIDToTooltip.TryGetValue(assetGUID, out tooltipText);
- }
-
- // 'assetGUID' will be the key to access the cached 'tooltipText'
- // see TryGetTooltipForGUID() for retrieval.
- public void StoreTooltipForGUID(string assetGUID, string tooltipText)
- {
- m_AssetGUIDToTooltip[assetGUID] = tooltipText;
- }
-
- // Failure: assigns empty string ("") to 'displayText', returns false.
- // Success: assigns the cached string to 'displayText', returns true.
- public bool TryGetDisplayCount(int count, out string displayText)
- {
- return s_CachedStringCount.TryGetValue(count, out displayText);
- }
-
- // 'count' will be the key to access the cached 'displayText'
- // see TryGetDisplayCount() for retrieval.
- public void StoreDisplayCount(int count, string displayText)
- {
- s_CachedStringCount.Add(count, displayText);
- }
-
- // Contains at most the list of all previously given Editors
- // via StoreEditor(). Garbage collected Editor(s) will be missing.
- public List GetEditors()
- {
- List editors = new List();
-
- for (int index = 0; index < m_EditorReferences.Count; index++)
- {
- WeakReference reference = m_EditorReferences[index];
- Editor editor = reference.Target as Editor;
-
- if (editor == null)
- {
- m_EditorReferences.RemoveAt(index);
- m_CachedWeakReferences.Add(reference);
- index--;
- }
- else
- {
- editors.Add(editor);
- }
- }
- return editors;
- }
-
- // Stores the Editor in a WeakReference.
- public void StoreEditor(Editor editor)
- {
- bool canAdd = true;
-
- // Check for duplicates and purge any null targets.
- for (int index = 0; canAdd && (index < m_EditorReferences.Count); index++)
- {
- WeakReference reference = m_EditorReferences[index];
- Editor storedEditor = reference.Target as Editor;
-
- if (storedEditor == null)
- {
- m_EditorReferences.RemoveAt(index);
- m_CachedWeakReferences.Add(reference);
- index--;
- }
- else if (storedEditor == editor)
- {
- canAdd = false;
- break;
- }
- }
-
- if (canAdd)
- {
- WeakReference editorReference;
-
- // Reuse any old WeakReference if available.
- if (m_CachedWeakReferences.Count > 0)
- {
- editorReference = m_CachedWeakReferences[0];
- m_CachedWeakReferences.RemoveAt(0);
- }
- else
- {
- editorReference = new WeakReference(null);
- }
- editorReference.Target = editor;
- m_EditorReferences.Add(editorReference);
- }
- }
- }
- }
-}
-
diff --git a/Editor/Mono/Collab/Views/ICollabHistoryWindow.cs b/Editor/Mono/Collab/Views/ICollabHistoryWindow.cs
deleted file mode 100644
index ab312c85a4..0000000000
--- a/Editor/Mono/Collab/Views/ICollabHistoryWindow.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-// Unity C# reference source
-// Copyright (c) Unity Technologies. For terms of use, see
-// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
-
-using System;
-using System.Collections.Generic;
-
-namespace UnityEditor.Collaboration
-{
- internal delegate void PageChangeAction(int page);
- internal delegate void RevisionAction(string revisionId, bool updateToRevision);
- internal delegate void ShowBuildAction(string revisionId);
-
- internal enum HistoryState
- {
- Error,
- Offline,
- Maintenance,
- LoggedOut,
- NoSeat,
- Disabled,
- Waiting,
- Ready,
- }
-
- internal enum BuildState
- {
- None,
- Configure,
- Success,
- Failed,
- InProgress,
- }
-
- internal struct RevisionData
- {
- public string id;
- public int index;
- public DateTime timeStamp;
- public string authorName;
- public string comment;
-
- // Whether this revision is on the client
- public bool obtained;
- public bool current;
- public bool inProgress;
- public bool enabled;
-
- public BuildState buildState;
- public int buildFailures;
-
- public ICollection changes;
- public int changesTotal;
- public bool changesTruncated;
- }
-
- internal struct ChangeData
- {
- public string path;
- public string action;
- }
-
- internal interface ICollabHistoryWindow
- {
- void UpdateState(HistoryState state, bool force);
- void UpdateRevisions(IEnumerable items, string tip, int totalRevisions, int currentPage);
-
- bool revisionActionsEnabled { get; set; }
- int itemsPerPage { set; }
- string inProgressRevision { get; set; }
- PageChangeAction OnPageChangeAction { set; }
- RevisionAction OnGoBackAction { set; }
- RevisionAction OnUpdateAction { set; }
- RevisionAction OnRestoreAction { set; }
- ShowBuildAction OnShowBuildAction { set; }
- Action OnShowServicesAction { set; }
- }
-}
diff --git a/Editor/Mono/Commands/CommandService.cs b/Editor/Mono/Commands/CommandService.cs
index a78ca32515..10f56233d8 100644
--- a/Editor/Mono/Commands/CommandService.cs
+++ b/Editor/Mono/Commands/CommandService.cs
@@ -152,8 +152,16 @@ private static IEnumerable ScanAttributes()
var commands = new List();
foreach (var mi in TypeCache.GetMethodsWithAttribute())
{
- if (!(Delegate.CreateDelegate(typeof(CommandHandler), mi) is CommandHandler callback))
+ CommandHandler callback = null;
+ try
+ {
+ callback = (CommandHandler)Delegate.CreateDelegate(typeof(CommandHandler), mi);
+ }
+ catch(Exception e)
+ {
+ Debug.LogError($"Cannot create CommandHandler from Attribute: {mi.Name} {e.Message}");
continue;
+ }
foreach (var attr in mi.GetCustomAttributes())
{
diff --git a/Editor/Mono/Commands/GOCreationCommands.cs b/Editor/Mono/Commands/GOCreationCommands.cs
index 6caef996d3..4f7aed86df 100644
--- a/Editor/Mono/Commands/GOCreationCommands.cs
+++ b/Editor/Mono/Commands/GOCreationCommands.cs
@@ -196,6 +196,12 @@ internal static void CreateEmptyParent()
}
SceneHierarchyWindow.lastInteractedHierarchyWindow.SetExpanded(go.GetInstanceID(), true);
+
+ // Ensure empty parent after reparenting jumps into rename mode if needed UUM-15042
+ if (SceneHierarchyWindow.s_EnterRenameModeForNewGO)
+ {
+ SceneHierarchyWindow.FrameAndRenameNewGameObject();
+ }
}
// Set back default parent object if we have one
diff --git a/Editor/Mono/ConsoleWindow.cs b/Editor/Mono/ConsoleWindow.cs
index 2c3bc2ad0b..b151101d0a 100644
--- a/Editor/Mono/ConsoleWindow.cs
+++ b/Editor/Mono/ConsoleWindow.cs
@@ -156,7 +156,7 @@ internal static void UpdateLogStyleFixedHeights()
ListViewState m_ListView;
string m_ActiveText = "";
StringBuilder m_CopyString;
- private int m_LastPingedEntry = -1;
+ private int m_LastPingedEntryRow = -1;
bool m_DevBuild;
int m_CallstackTextStart = 0;
private Mode m_ActiveMode = Mode.None;
@@ -453,18 +453,19 @@ void SetActiveEntry(LogEntry entry)
m_ActiveMode = (Mode)entry.mode;
entry.callstackTextStartUTF8 = entry.message.Length;
m_CallstackTextStart = entry.callstackTextStartUTF16;
+ var entryRow = LogEntries.GetEntryRowIndex(entry.globalLineIndex);
// ping object referred by the log entry
- if (entry.instanceID != 0 && m_LastPingedEntry != entry.globalLineIndex)
+ if (entry.instanceID != 0 && m_LastPingedEntryRow != entryRow)
{
EditorGUIUtility.PingObject(entry.instanceID);
- m_LastPingedEntry = entry.globalLineIndex;
+ m_LastPingedEntryRow = entryRow;
}
}
else
{
m_CallstackTextStart = 0;
m_ActiveText = string.Empty;
- m_LastPingedEntry = -1;
+ m_LastPingedEntryRow = -1;
m_ListView.row = -1;
m_CopyString.Clear();
m_ActiveMode = Mode.None;
@@ -882,10 +883,7 @@ internal static string StacktraceWithHyperlinks(string stacktraceText, int calls
filePathPart.Substring(lineIndex + 1, (endLineIndex) - (lineIndex + 1));
string filePath = filePathPart.Substring(0, lineIndex);
- textWithHyperlinks.Append(lines[i].Substring(0, filePathIndex));
- textWithHyperlinks.Append("");
- textWithHyperlinks.Append(filePath + ":" + lineString);
- textWithHyperlinks.Append(")\n");
+ textWithHyperlinks.Append($"{lines[i].Substring(0, filePathIndex)}{filePath}:{lineString})\n");
continue; // continue to evade the default case
}
diff --git a/Editor/Mono/ContainerWindow.bindings.cs b/Editor/Mono/ContainerWindow.bindings.cs
index 43c3163335..86e3df08c1 100644
--- a/Editor/Mono/ContainerWindow.bindings.cs
+++ b/Editor/Mono/ContainerWindow.bindings.cs
@@ -26,8 +26,6 @@ internal enum ShowMode
Tooltip = 6,
// Modal Utility window
ModalUtility = 7,
- // Show as fullscreen window
- Fullscreen = 8
}
//[StaticAccessor("ContainerWindowBindings", StaticAccessorType.DoubleColon)]
@@ -44,6 +42,8 @@ public extern Rect position
[FreeFunction(k_ScriptingPrefix + "SetPosition", HasExplicitThis = true)] set;
}
+ [FreeFunction(k_ScriptingPrefix + "SetFreeze", HasExplicitThis = true)]
+ public extern void SetFreeze(bool freeze);
public extern bool maximized {[FreeFunction(k_ScriptingPrefix + "IsWindowMaximized", HasExplicitThis = true)] get; }
[FreeFunction(k_ScriptingPrefix + "SetAlpha", HasExplicitThis = true)]
@@ -65,12 +65,6 @@ public extern Rect position
[FreeFunction(k_ScriptingPrefix + "ToggleMaximize", HasExplicitThis = true)]
public extern void ToggleMaximize();
- [FreeFunction(k_ScriptingPrefix + "ToggleFullscreen", HasExplicitThis = true)]
- internal extern void ToggleFullscreen(int displayIndex = 0);
-
- [FreeFunction(k_ScriptingPrefix + "IsFullscreen", HasExplicitThis = true)]
- internal extern bool IsFullscreen();
-
[FreeFunction(k_ScriptingPrefix + "MoveInFrontOf", HasExplicitThis = true)]
public extern void MoveInFrontOf(ContainerWindow other);
@@ -84,9 +78,6 @@ public extern Rect position
[FreeFunction(k_ScriptingPrefix + "SendCaptionEvent", HasExplicitThis = true)]
public extern void SendCaptionEvent(bool mouseDown);
- [FreeFunction(k_ScriptingPrefix + "GetDisplayId", HasExplicitThis = true)]
- internal extern int GetDisplayId();
-
// Close the editor window.
[FreeFunction(k_ScriptingPrefix + "InternalClose", HasExplicitThis = true)]
public extern void InternalClose();
@@ -95,7 +86,7 @@ public extern Rect position
private extern void Internal_SetMinMaxSizes(Vector2 minSize, Vector2 maxSize);
[FreeFunction(k_ScriptingPrefix + "Internal_Show", HasExplicitThis = true, ThrowsException = true)]
- private extern void Internal_Show(Rect r, int showMode, Vector2 minSize, Vector2 maxSize, int displayIndex = 0);
+ private extern void Internal_Show(Rect r, int showMode, Vector2 minSize, Vector2 maxSize);
[FreeFunction(k_ScriptingPrefix + "Internal_BringLiveAfterCreation", HasExplicitThis = true)]
private extern void Internal_BringLiveAfterCreation(bool displayImmediately, bool setFocus, bool showMaximized);
diff --git a/Editor/Mono/ContainerWindow.cs b/Editor/Mono/ContainerWindow.cs
index f35f18db94..5aa556b559 100644
--- a/Editor/Mono/ContainerWindow.cs
+++ b/Editor/Mono/ContainerWindow.cs
@@ -8,6 +8,7 @@
using System.Collections.Generic;
using System;
using System.Linq;
+using UnityEngine.Scripting;
namespace UnityEditor
{
@@ -24,9 +25,7 @@ internal partial class ContainerWindow : ScriptableObject
[SerializeField] Vector2 m_MaxSize = new Vector2(8192, 8192);
[SerializeField] bool m_Maximized;
- internal int m_DisplayIndex;
- internal bool m_IsFullscreenContainer;
- internal bool m_IsForceTitleBar;
+ internal bool m_IsMppmCloneWindow;
internal bool m_DontSaveToLayout = false;
private bool m_HasUnsavedChanges = false;
@@ -39,7 +38,6 @@ internal partial class ContainerWindow : ScriptableObject
internal const float kButtonWidth = 16f, kButtonHeight = 16f;
static internal bool macEditor => Application.platform == RuntimePlatform.OSXEditor;
- static internal bool linuxEditor => Application.platform == RuntimePlatform.LinuxEditor;
static internal bool s_Modal = false;
private static ContainerWindow s_MainWindow;
@@ -47,28 +45,16 @@ internal partial class ContainerWindow : ScriptableObject
private static class Styles
{
- // Title Bar Buttons (Non)
- public static GUIStyle buttonMin = "WinBtnMinMac";
- public static GUIStyle buttonClose = macEditor ? "WinBtnCloseMac" : "WinBtnClose";
- public static GUIStyle buttonMax = macEditor ? "WinBtnMaxMac" : "WinBtnMax";
- public static GUIStyle buttonRestore = macEditor ? "WinBtnRestoreMac" : "WinBtnRestore";
-
public static float borderSize => macEditor ? osxBorderSize : winBorderSize;
public static float buttonMargin => macEditor ? osxBorderMargin : winBorderMargin;
- public static SVC buttonTop = new SVC("--container-window-button-top-margin");
-
private static SVC winBorderSize = new SVC("--container-window-buttons-right-margin-win");
private static SVC osxBorderSize = new SVC("--container-window-buttons-right-margin-osx");
private static SVC winBorderMargin = new SVC("--container-window-button-left-right-margin-win");
private static SVC osxBorderMargin = new SVC("--container-window-button-left-right-margin-osx");
}
-
- private const float kButtonCountOSX = 0;
- private const float kButtonCountWin = 2;
static internal float buttonHorizontalSpace => (kButtonWidth + Styles.buttonMargin * 2f);
- static internal float buttonStackWidth => buttonHorizontalSpace * (macEditor || linuxEditor ? kButtonCountOSX : kButtonCountWin) + Styles.borderSize;
-
+ static internal float buttonStackWidth => Styles.borderSize;
public ContainerWindow()
{
m_PixelRect = new Rect(0, 0, 400, 300);
@@ -148,21 +134,20 @@ internal void ShowPopupWithMode(ShowMode mode, bool giveFocus)
static Color skinBackgroundColor => EditorGUIUtility.isProSkin ? darkSkinColor : lightSkinColor;
// Show the editor window.
- public void Show(ShowMode showMode, bool loadPosition, bool displayImmediately, bool setFocus, int displayIndex = 0)
+ public void Show(ShowMode showMode, bool loadPosition, bool displayImmediately, bool setFocus)
{
try
{
if (showMode == ShowMode.MainWindow && s_MainWindow && s_MainWindow != this)
throw new InvalidOperationException("Trying to create a second main window from layout when one already exists.");
- bool useMousePos = showMode == ShowMode.AuxWindow || showMode == ShowMode.Fullscreen;
+ bool useMousePos = showMode == ShowMode.AuxWindow;
if (showMode == ShowMode.AuxWindow)
showMode = ShowMode.Utility;
if (showMode == ShowMode.Utility
|| showMode == ShowMode.ModalUtility
|| showMode == ShowMode.AuxWindow
- || showMode == ShowMode.Fullscreen
|| IsPopup(showMode))
m_DontSaveToLayout = true;
@@ -176,7 +161,7 @@ public void Show(ShowMode showMode, bool loadPosition, bool displayImmediately,
var initialMaximizedState = m_Maximized;
- Internal_Show(m_PixelRect, m_ShowMode, m_MinSize, m_MaxSize, displayIndex);
+ Internal_Show(m_PixelRect, m_ShowMode, m_MinSize, m_MaxSize);
// Tell the main view its now in this window (quick hack to get platform-specific code to move its views to the right window)
if (m_RootView)
@@ -371,11 +356,13 @@ internal void InternalCloseWindow()
}
DestroyImmediate(this, true);
+ EditorWindow.UpdateWindowMenuListing();
}
- internal bool InternalIsForceTitleBar()
+ [RequiredByNativeCode]
+ internal bool IsMultiplayerClone()
{
- return m_IsForceTitleBar;
+ return m_IsMppmCloneWindow;
}
private static List FindUnsavedChanges(View view)
@@ -657,142 +644,5 @@ internal Rect GetDropDownRect(Rect buttonRect, Vector2 minSize, Vector2 maxSize)
return PopupLocationHelper.GetDropDownRect(buttonRect, minSize, maxSize, this);
}
- public void HandleWindowDecorationEnd(Rect windowPosition)
- {
- // No Op
- }
-
- public void HandleWindowDecorationStart(Rect windowPosition)
- {
- if (!macEditor && !linuxEditor)
- {
- bool hasTitleBar = (windowPosition.y == 0 && (showMode != ShowMode.Utility && showMode != ShowMode.MainWindow) && !isPopup);
-
- if (!hasTitleBar)
- return;
-
- bool hasWindowButtons = Mathf.Abs(windowPosition.xMax - position.width) < 2;
- if (hasWindowButtons)
- {
- GUIStyle min = Styles.buttonMin;
- GUIStyle close = Styles.buttonClose;
- GUIStyle maxOrRestore = maximized ? Styles.buttonRestore : Styles.buttonMax;
-
- BeginTitleBarButtons(windowPosition);
- if (TitleBarButton(close))
- {
- if (InternalRequestClose())
- {
- Close();
- GUIUtility.ExitGUI();
- }
- }
-
- var canMaximize = m_MaxSize.x == 0 || m_MaxSize.y == 0 || m_MaxSize.x >= Screen.currentResolution.width || m_MaxSize.y >= Screen.currentResolution.height;
- EditorGUI.BeginDisabled(!canMaximize);
- if (TitleBarButton(maxOrRestore))
- ToggleMaximize();
- EditorGUI.EndDisabled();
- }
-
- DragTitleBar(new Rect(0, 0, position.width, kTitleHeight));
- }
- }
-
- private void BeginTitleBarButtons(Rect windowPosition)
- {
- m_ButtonCount = 0;
- m_TitleBarWidth = windowPosition.width;
- }
-
- private bool TitleBarButton(GUIStyle style)
- {
- var buttonRect = new Rect(m_TitleBarWidth - Styles.borderSize - (buttonHorizontalSpace * ++m_ButtonCount), Styles.buttonTop, kButtonWidth, kButtonHeight);
- var guiView = rootView as GUIView;
- if (guiView == null)
- {
- var splitView = rootView as SplitView;
- if (splitView != null)
- guiView = splitView.children.Length > 0 ? splitView.children[0] as GUIView : null;
- }
- if (guiView != null)
- guiView.MarkHotRegion(GUIClip.UnclipToWindow(buttonRect));
-
- return GUI.Button(buttonRect, GUIContent.none, style);
- }
-
- // Snapping windows
- private static Vector2 s_LastDragMousePos;
- private float startDragDpi;
-
- // Indicates that we are using the native title bar caption dragging.
- private bool m_DraggingNativeTitleBarCaption = false;
-
- private void DragTitleBar(Rect titleBarRect)
- {
- int id = GUIUtility.GetControlID(FocusType.Passive);
- Event evt = Event.current;
-
- switch (evt.GetTypeForControl(id))
- {
- case EventType.Repaint:
- if (m_DraggingNativeTitleBarCaption)
- m_DraggingNativeTitleBarCaption = false;
- EditorGUIUtility.AddCursorRect(titleBarRect, MouseCursor.Arrow);
- break;
- case EventType.MouseDown:
- // If the mouse is inside the title bar rect, we say that we're the hot control
- if (titleBarRect.Contains(evt.mousePosition) && GUIUtility.hotControl == 0 && evt.button == 0)
- {
- Event.current.Use();
- m_DraggingNativeTitleBarCaption = true;
- SendCaptionEvent(m_DraggingNativeTitleBarCaption);
- }
- break;
- case EventType.MouseUp:
- if (m_DraggingNativeTitleBarCaption)
- break;
-
- if (GUIUtility.hotControl == id)
- {
- GUIUtility.hotControl = 0;
- Event.current.Use();
- Unsupported.SetAllowCursorLock(true, Unsupported.DisallowCursorLockReasons.SizeMove);
- }
- break;
- case EventType.MouseDrag:
- if (m_DraggingNativeTitleBarCaption)
- break;
-
- if (GUIUtility.hotControl == id)
- {
- Vector2 mousePos = evt.mousePosition;
- if (startDragDpi != GUIUtility.pixelsPerPoint)
- {
- // We ignore this mouse event when changing screens in multi monitor setups with
- // different dpi scalings as funky things might/will happen
- startDragDpi = GUIUtility.pixelsPerPoint;
- s_LastDragMousePos = mousePos;
- }
- else
- {
- Vector2 movement = mousePos - s_LastDragMousePos;
-
- float minimumDelta = 1.0f / GUIUtility.pixelsPerPoint;
-
- if (Mathf.Abs(movement.x) >= minimumDelta || Mathf.Abs(movement.y) >= minimumDelta)
- {
- Rect dragPosition = position;
- dragPosition.x += movement.x;
- dragPosition.y += movement.y;
- position = dragPosition;
-
- GUI.changed = true;
- }
- }
- }
- break;
- }
- }
}
} //namespace
diff --git a/Editor/Mono/CustomEditorAttributes.bindings.cs b/Editor/Mono/CustomEditorAttributes.bindings.cs
index 7dfb49fbf6..7387e02d03 100644
--- a/Editor/Mono/CustomEditorAttributes.bindings.cs
+++ b/Editor/Mono/CustomEditorAttributes.bindings.cs
@@ -10,9 +10,9 @@ namespace UnityEditor;
internal partial class CustomEditorAttributes
{
[RequiredByNativeCode]
- internal static Type FindCustomEditorType(Object o, bool multiEdit)
+ internal static Type FindCustomEditorType(Object obj, bool multiEdit)
{
- return FindCustomEditorTypeByType(o.GetType(), multiEdit);
+ return obj == null ? null : FindCustomEditorTypeByType(obj.GetType(), multiEdit);
}
[RequiredByNativeCode]
diff --git a/Editor/Mono/CustomEditorAttributes.cs b/Editor/Mono/CustomEditorAttributes.cs
index b866edb95d..73e46af47e 100644
--- a/Editor/Mono/CustomEditorAttributes.cs
+++ b/Editor/Mono/CustomEditorAttributes.cs
@@ -212,11 +212,13 @@ static bool TryGatherRenderPipelineTypes([DisallowNull] Type type, [DisallowNull
}
}
+#pragma warning disable CS0618
if (inspectAttr is CustomEditorForRenderPipelineAttribute attr)
{
results = new[] { attr.renderPipelineType };
return true;
}
+#pragma warning restore CS0618
results = null;
return true;
diff --git a/Editor/Mono/CustomInspectorStubs.cs b/Editor/Mono/CustomInspectorStubs.cs
index 0793e52640..0a54fe5bed 100644
--- a/Editor/Mono/CustomInspectorStubs.cs
+++ b/Editor/Mono/CustomInspectorStubs.cs
@@ -68,10 +68,18 @@ private InputManager() {}
[SettingsProvider]
internal static SettingsProvider CreateProjectSettingsProvider()
{
- var provider = AssetSettingsProvider.CreateProviderFromAssetPath(
- "Project/Input Manager", "ProjectSettings/InputManager.asset",
- SettingsProvider.GetSearchKeywordsFromPath("ProjectSettings/InputManager.asset"));
- return provider;
+ // The new input system adds objects to InputManager.asset. This means we can't use AssetSettingsProvider.CreateProviderFromAssetPath
+ // as it will load *all* objects at that path and try to create an editor for it.
+ // NOTE: When the input system package is uninstalled, InputManager.asset will contain serialized MonoBehaviour objects for which
+ // the C# classes are no longer available. They will thus not load correctly and appear as null entries.
+ var obj = AssetDatabase.LoadAssetAtPath("ProjectSettings/InputManager.asset");
+ if (obj != null && obj.name == "InputManager")
+ {
+ var provider = AssetSettingsProvider.CreateProviderFromObject("Project/Input Manager", obj,
+ SettingsProvider.GetSearchKeywordsFromPath("ProjectSettings/InputManager.asset"));
+ return provider;
+ }
+ return null;
}
}
diff --git a/Editor/Mono/DataMode.cs b/Editor/Mono/DataMode.cs
index fb934d692c..4ce5f777c4 100644
--- a/Editor/Mono/DataMode.cs
+++ b/Editor/Mono/DataMode.cs
@@ -4,15 +4,15 @@
using System;
using System.Collections.Generic;
-
+using System.Linq;
+using UnityEngine;
using UnityObject = UnityEngine.Object;
using DataModeSupportHandler = UnityEditor.DeclareDataModeSupportAttribute.DataModeSupportHandler;
namespace UnityEditor
{
///
- /// Options for the different modes of an that implements
- /// or .
+ /// Options for the different modes of an .
///
//
// Dev note:
@@ -26,150 +26,260 @@ namespace UnityEditor
// Sincerely,
// The #dots-editor team
//
+ [Serializable]
public enum DataMode // Values must be kept in sync with `DataMode.h`
{
///
- /// Represents a situation or context in which the usage of data modes is not applicable.
+ /// Represents a situation or context in which the usage of is not applicable.
///
///
- /// This mode informs the docking area that the data modes switch should now be displayed.
+ /// This mode disables the DataMode switch in the docking area.
///
Disabled = 0,
///
- /// Uses a mode where only authoring data is available.
+ /// Uses this mode where only authoring data is available.
///
///
/// In this mode, only authoring data is available. When exiting Play mode, Unity retains authoring data.
///
Authoring = 1,
///
- /// Uses a mode where a mix of authoring and runtime data is available.
+ /// Uses this mode where a mix of authoring and runtime data is available.
///
///
- /// In this mode, a mixture of authoring and runtime data is available. **Important:** When exiting Play mode,
- /// Unity loses runtime data. However, it retains any authoring data.
+ /// In this mode, a mixture of authoring and runtime data is available.
+ /// When exiting Play mode, Unity loses runtime data. However, it retains any authoring data.
///
Mixed = 2,
///
- /// Uses a mode where only runtime data is available.
+ /// Uses this mode where only runtime data is available.
///
///
- /// In this mode, only runtime data is available. **Important:** When exiting Play mode, Unity loses runtime
- /// data.
+ /// In this mode, only runtime data is available. When exiting Play mode, Unity loses runtime data.
///
Runtime = 3
}
///
- /// Implement this interface to allow an to handle changes.
+ /// Container for the different parameters of the event.
+ ///
+ /// DataMode to which the should change.
+ /// Whether the change was initiated by the DataMode switcher UI
+ /// at the top-right of the Editor window.
+ public readonly struct DataModeChangeEventArgs
+ {
+ public readonly DataMode nextDataMode;
+ public readonly bool changedThroughUI;
+
+ public DataModeChangeEventArgs(DataMode nextDataMode, bool changedThroughUI)
+ {
+ this.nextDataMode = nextDataMode;
+ this.changedThroughUI = changedThroughUI;
+ }
+ }
+
+ ///
+ /// Interface with which any can interact with functionalities.
+ /// To obtain an instance, use >
///
///
- /// This interface displays a switch in the docking area when the window is visible and lists the supported modes in
- /// the contextual menu for that window. Use this interface if your window only needs to react to direct user
- /// interactions with the data mode switch or the contextual menu. If your window needs to change its state based on
- /// other factors, like entering or exiting play mode, you should implement
- /// instead.
+ /// This interface displays a switch in the docking area when the window is visible and has
+ /// more than one supported DataModes.
///
- public interface IDataModeHandler
+ public interface IDataModeController
{
///
- /// Returns the currently active for the implementor .
+ /// Returns the currently active for the that
+ /// owns this instance of IDataModeController.
+ ///
+ DataMode dataMode { get; }
+
+ ///
+ /// Event for subscribing to changes.
///
///
- /// Unity does not serialize or store this value. It is the window's responsibility to do so.
+ /// This method accepts >.
+ /// For example, you can register to this method to update the contents of the window for the given data mode.
///
- DataMode dataMode { get; }
+ event Action dataModeChanged;
///
- ///
- /// A list of the s the supports.
- ///
- ///
- /// That list of the s the supports varies based
- /// on a number of factors, so it should only contain the modes available to the current context.
+ /// Updates the list of s that the supports,
+ /// and sets the preferred DataMode to be used when the DataMode switcher UI is set to Automatic.
+ ///
+ ///
+ /// That list of the DataModes the Editor window supports varies based on a number of factors,
+ /// so it should only contain the DataModes available to the current context.
/// For example, a window might support the and
/// modes when in Edit mode, and the and modes when
/// in Play mode. A common pattern for that case is to store two lists internally and use
/// to select which one to return.
- ///
- ///
- IReadOnlyList supportedDataModes { get; }
-
- ///
- /// Unity calls this method automatically before any call to is made. If the
- /// method returns false, is called instead.
- ///
- ///
- /// The for which support is being tested.
+ /// A list of the supported DataModes.
+ ///
+ /// Preferred DataMode to use given the current context when the DataMode switcher UI is set to Automatic.
///
- ///
- /// Whether the currently supports the specified .
- ///
- bool IsDataModeSupported(DataMode mode);
-
- ///
- /// Unity calls this method automatically when a user clicks the switch in the docking
- /// area tied to the implementing .
- ///
- ///
- /// This method informs the window to change its to whatever mode should come after
- /// the current. In most cases, a window only supports two data modes at a time, but it is possible to support
- /// all three. Also, a window that supports all three modes might want the switch to only toggle between two
- /// specific modes and rely on the contextual menu to change to the third mode.
///
- void SwitchToNextDataMode();
+ void UpdateSupportedDataModes(IList supportedDataMode, DataMode preferredDataMode);
///
- /// Unity calls this method automatically whenever the Editor wants an to be in a
- /// specific .
+ /// Requests a change for the .
///
///
- /// By convention, Unity always calls before calling this method. If the
- /// data mode is not supported, is called instead.
+ /// If the DataMode switcher UI is currently set to Automatic, the Editor window also
+ /// changes to that preferred DataMode.
+ /// >
///
- ///
- /// The explicit data mode to which the Editor window should change.
+ ///
+ /// The DataMode to which the Editor window should change.
///
- void SwitchToDataMode(DataMode mode);
+ ///
+ /// Whether the Editor window has accepted the requested DataMode change.
+ /// >
+ bool TryChangeDataMode(DataMode newDataMode);
+ }
- ///
- /// Unity calls this method automatically whenever going to a requested is impossible
- /// because of the result of .
- ///
- ///
- /// This method is a fallback to make sure the is always in a valid state.
- ///
- ///
+ // DataModeController handles DataMode related actions internally.
+ // Each Editor window has a DataModeController instance.
+ [Serializable]
+ internal sealed class DataModeController : IDataModeController
+ {
+ static readonly DataMode[] k_DefaultModes = Array.Empty();
+
+ public event Action dataModeChanged;
+
+ [SerializeField] DataMode m_DataMode = DataMode.Disabled;
+ public DataMode dataMode
+ {
+ get => m_DataMode;
+ private set => m_DataMode = value;
+ }
+
+ [SerializeField] DataMode m_PreferredDataMode = DataMode.Disabled;
+ public DataMode preferredDataMode
+ {
+ get => m_PreferredDataMode;
+ private set => m_PreferredDataMode = value;
+ }
+
+ [SerializeField] DataMode[] m_SupportedDataModes = k_DefaultModes;
+ public IList supportedDataModes
+ {
+ get => m_SupportedDataModes;
+ private set => m_SupportedDataModes = value.ToArray();
+ }
+
+ [SerializeField] internal bool isAutomatic = true;
+
+ readonly List m_DataModeSanitizationCache = new List(3); // Number of modes, minus `Disabled`
+
+ public void UpdateSupportedDataModes(IList supported, DataMode preferred)
+ {
+ SanitizeSupportedDataModesList(supported.ToList(), m_DataModeSanitizationCache);
+
+ supportedDataModes = m_DataModeSanitizationCache.Count != 0 ? m_DataModeSanitizationCache : k_DefaultModes;
+
+ preferredDataMode = supportedDataModes.Count switch
+ {
+ 0 => DataMode.Disabled,
+ 1 => supportedDataModes[0],
+ _ => supportedDataModes.Contains(preferred) ? preferred : supportedDataModes[0]
+ };
+
+ if (!isAutomatic || dataMode == preferredDataMode)
+ return;
+
+ // Recover if automatic
+ dataMode = preferredDataMode;
+ dataModeChanged?.Invoke(new DataModeChangeEventArgs(dataMode, false));
+ }
+
+ static void SanitizeSupportedDataModesList(IReadOnlyList originalList, List sanitizedList)
+ {
+ sanitizedList.Clear();
+
+ foreach (var mode in originalList)
+ {
+ if (mode == DataMode.Disabled)
+ continue; // Never list `DataMode.Disabled`
+
+ if (sanitizedList.Contains(mode))
+ continue; // Prevent duplicate entries
+
+ sanitizedList.Add(mode);
+ }
+
+ // Ensure we are displaying the data modes in a predefined order, regardless of
+ // the order in which the user defined their list.
+ sanitizedList.Sort();
+ }
+
+ public bool ShouldDrawDataModesSwitch()
+ {
+ return dataMode != DataMode.Disabled
+ // We don't want to show DataMode switch if there are not
+ // at least 2 modes supported at the current moment.
+ && supportedDataModes.Count > 1;
+ }
+
+ public bool TryChangeDataMode(DataMode newDataMode)
+ {
+ // Only change if currently in automatic mode
+ if (!isAutomatic || dataMode == newDataMode || !supportedDataModes.Contains(newDataMode))
+ return false;
+
+ dataMode = newDataMode;
+ dataModeChanged?.Invoke(new DataModeChangeEventArgs(newDataMode, false));
+ return true;
+ }
+
+ // Invoked when user interacts with the DataMode dropdown menu, for internal use only.
+ internal void SwitchToAutomatic()
+ {
+ if (isAutomatic)
+ return;
+
+ isAutomatic = true;
+
+ if (dataMode == preferredDataMode)
+ return;
+
+ // If the DataMode is not supported in current context, we fall back to default one.
+ dataMode = preferredDataMode;
+ dataModeChanged?.Invoke(new DataModeChangeEventArgs(dataMode, true));
+ }
+
+ // Invoked when user interacts with the DataMode dropdown men, for internal use only.
+ internal void SwitchToStickyDataMode(DataMode stickyDataMode)
+ {
+ isAutomatic = false;
+
+ if (dataMode == stickyDataMode)
+ return;
+
+ dataMode = supportedDataModes.Contains(stickyDataMode)
+ ? stickyDataMode
+ : preferredDataMode;
+
+ dataModeChanged?.Invoke(new DataModeChangeEventArgs(dataMode, true));
+ }
+ }
+
+ [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ [Obsolete("IDataModeHandler has been deprecated, please use EditorWindow.dataModeController instead.", false)]
+ public interface IDataModeHandler
+ {
+ DataMode dataMode { get; }
+ IReadOnlyList supportedDataModes { get; }
+ bool IsDataModeSupported(DataMode mode);
+ void SwitchToNextDataMode();
+ void SwitchToDataMode(DataMode mode);
void SwitchToDefaultDataMode();
}
- ///
- /// Implement this interface to allow an to handle changes and
- /// alter its internally.
- ///
- ///
- /// This interface displays a switch in the docking area when the window is visible and lists the supported modes in
- /// the contextual menu for that window. Use this interface if your window needs to control its mode internally
- /// based on factors other than the user directly interacting with the data mode switch or the contextual menu, for
- /// example, entering or exiting Play mode. If your window does not need to control its own mode, use
- /// instead.
- ///
+ [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ [Obsolete("IDataModeHandlerAndDispatcher has been deprecated, please use EditorWindow.dataModeController instead.", false)]
public interface IDataModeHandlerAndDispatcher : IDataModeHandler
{
- ///
- ///
- /// Calls the methods in its invocation list when the changes due to an external factor
- /// and passes the new data mode as an argument.
- ///
- ///
- /// An external factor refers to any action which results in a data mode change that Unity did not initiate
- /// directly through calling either ,
- /// , or .
- ///
- ///
- /// For example, when entering or exiting Play mode, some windows might want to force a data mode switch.
- ///
- ///
event Action dataModeChanged;
}
diff --git a/Editor/Mono/Delayer.cs b/Editor/Mono/Delayer.cs
index df2fd4910d..342d242cd4 100644
--- a/Editor/Mono/Delayer.cs
+++ b/Editor/Mono/Delayer.cs
@@ -10,7 +10,7 @@ class Delayer
{
private long m_LastExecutionTime;
private Action