diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a43becf3..4f96a2cf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,22 @@ # Changelog - VR Builder -**v4.0.0 (2024/04/18 - Current)** +**v4.1.0 (2024/05/17 - Current)** + +*[Added]* +- Significantly improved runtime performance for processes with many steps. Now the number of steps in a process has no impact on the performance. +- New multiline text drawer contributed by LEFX - thank you! The drawer is currently used in the Text To Speech behavior but can be manually set for fields in other behaviors/conditions. +- Added `ForceLockControllerState` and `UnlockControllerState` public methods to `ActionBasedControllerManager`. These can be used to externally lock the controllers e.g. in UI mode or teleport mode, which can be useful if the user is required to perform a specific action. + +*[Changed]* +- The `UserSceneObject` component does not inherit from `ProcessSceneObject` anymore. This allows you to use the rig in a scene without scene object registry without getting errors - for example when loading additively scenes with processes in them. As a result, `BaseRuntimeConfiguration.User` does not work anymore. You can still use `BaseRuntimeConfiguration.LocalUser` which provides the same functionality while returning a `UserSceneObject` component. Note that nothing stops you from manually adding `ProcessSceneObject` components to parts of the rig you want to interact with the process. + +*[Fixed]* +- A `link.xml` file is now automatically created before Android builds in order to prevent managed stripping from removing behavior/condition code which is actually in use, and thus resulting in a non-functional process in a standalone headset. +- Fixed tags on game objects not being converted to groups when upgrading from version 3 to 4. +- Fixed bug in the automatic updater of the Enable/Disable Object by Tag behaviors. Now these should be replaced by a correctly configured non-obsolete behavior. +- Scene property extensions will not be added multiple times when selecting the `Add Scene Property Extension` menu entry in a scene where they have already been added. + +**v4.0.0 (2024/04/18)** *[Added]* - Added upgrade tool for updating processes to the new referencing system (see below). If you open an old process in VR Builder 4.0.0, all object references will be null because the system has changed. You can attempt to update the process by opening its scene, then selecting Tools > VR Builder > Developer > Update Process in Scene. Note it's important that the correct scene is loaded, as the updater will have to search for the correct game objects in order to update the references. diff --git a/Source/Basic-Conditions-And-Behaviors/Editor/UI/Drawers/Component List Drawer/SetComponentEnabledBehaviorDrawer.cs b/Source/Basic-Conditions-And-Behaviors/Editor/UI/Drawers/Component List Drawer/SetComponentEnabledBehaviorDrawer.cs index baef704b5..3abd4fc20 100644 --- a/Source/Basic-Conditions-And-Behaviors/Editor/UI/Drawers/Component List Drawer/SetComponentEnabledBehaviorDrawer.cs +++ b/Source/Basic-Conditions-And-Behaviors/Editor/UI/Drawers/Component List Drawer/SetComponentEnabledBehaviorDrawer.cs @@ -31,6 +31,7 @@ public override Rect Draw(Rect rect, object currentValue, Action changeV height += nextPosition.height; height += EditorDrawingHelper.VerticalSpacing; nextPosition.y = rect.y + height; + nextPosition.height = EditorDrawingHelper.SingleLineHeight; List components = new List(); diff --git a/Source/Basic-Conditions-And-Behaviors/Runtime/Behaviors/BehaviorSequence.cs b/Source/Basic-Conditions-And-Behaviors/Runtime/Behaviors/BehaviorSequence.cs index 504ded30e..98256deac 100644 --- a/Source/Basic-Conditions-And-Behaviors/Runtime/Behaviors/BehaviorSequence.cs +++ b/Source/Basic-Conditions-And-Behaviors/Runtime/Behaviors/BehaviorSequence.cs @@ -57,7 +57,7 @@ public string Name { string behaviors = ""; - if(Behaviors.Count == 0) + if (Behaviors.Count == 0) { behaviors = "no behavior"; } @@ -82,6 +82,9 @@ public string Name /// public bool IsBlocking { get; set; } + + /// + IEntity IEntitySequenceData.Current => Current; } private class IteratingProcess : EntityIteratingProcess, IBehavior> diff --git a/Source/Core/Editor/BuilderProjectSettings.cs b/Source/Core/Editor/BuilderProjectSettings.cs index 94bfeb5e3..df09eee6c 100644 --- a/Source/Core/Editor/BuilderProjectSettings.cs +++ b/Source/Core/Editor/BuilderProjectSettings.cs @@ -2,75 +2,77 @@ // Licensed under the Apache License, Version 2.0 // Modifications copyright (c) 2021-2024 MindPort GmbH +using System.Collections.Generic; using System.IO; -using VRBuilder.Editor; using UnityEditor; using UnityEngine; -using System.Collections.Generic; using VRBuilder.Editor.XRUtils; -/// -/// Settings for a VR Builder Unity project. -/// -public partial class BuilderProjectSettings : ScriptableObject +namespace VRBuilder.Editor.Settings { /// - /// Was VR Builder imported and therefore started for the first time. + /// Settings for a VR Builder Unity project. /// - [HideInInspector] - public bool IsFirstTimeStarted = true; + public partial class BuilderProjectSettings : ScriptableObject + { + /// + /// Was VR Builder imported and therefore started for the first time. + /// + [HideInInspector] + public bool IsFirstTimeStarted = true; - /// - /// Builder version used last time this was checked. - /// - [HideInInspector] - public string ProjectBuilderVersion = null; + /// + /// Builder version used last time this was checked. + /// + [HideInInspector] + public string ProjectBuilderVersion = null; - [HideInInspector, SerializeField] - public List OpenXRControllerProfiles = new List(); + [HideInInspector, SerializeField] + public List OpenXRControllerProfiles = new List(); - [HideInInspector, SerializeField] - public List XRSDKs = new List(); + [HideInInspector, SerializeField] + public List XRSDKs = new List(); - /// - /// Loads the VR Builder settings for this Unity project from Resources. - /// - /// Settings - public static BuilderProjectSettings Load() - { - BuilderProjectSettings settings = Resources.Load("BuilderProjectSettings"); - if (settings == null) + /// + /// Loads the VR Builder settings for this Unity project from Resources. + /// + /// Settings + public static BuilderProjectSettings Load() { - if (!Directory.Exists("Assets/MindPort/VR Builder/Resources")) + BuilderProjectSettings settings = Resources.Load("BuilderProjectSettings"); + if (settings == null) { - Directory.CreateDirectory("Assets/MindPort/VR Builder/Resources"); - } - // Create an instance - settings = CreateInstance(); - AssetDatabase.CreateAsset(settings, "Assets/MindPort/VR Builder/Resources/BuilderProjectSettings.asset"); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); + if (!Directory.Exists("Assets/MindPort/VR Builder/Resources")) + { + Directory.CreateDirectory("Assets/MindPort/VR Builder/Resources"); + } + // Create an instance + settings = CreateInstance(); + AssetDatabase.CreateAsset(settings, "Assets/MindPort/VR Builder/Resources/BuilderProjectSettings.asset"); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + return settings; + } return settings; } - return settings; - } - private void OnEnable() - { - if (string.IsNullOrEmpty(ProjectBuilderVersion)) + private void OnEnable() { - ProjectBuilderVersion = EditorUtils.GetCoreVersion(); + if (string.IsNullOrEmpty(ProjectBuilderVersion)) + { + ProjectBuilderVersion = EditorUtils.GetCoreVersion(); + } } - } - /// - /// Saves the VR Builder settings. - /// - public void Save() - { - EditorUtility.SetDirty(this); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); + /// + /// Saves the VR Builder settings. + /// + public void Save() + { + EditorUtility.SetDirty(this); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } } } diff --git a/Source/Core/Editor/InputSystemChecker.cs b/Source/Core/Editor/InputSystemChecker.cs index 814379049..b298c0a9c 100644 --- a/Source/Core/Editor/InputSystemChecker.cs +++ b/Source/Core/Editor/InputSystemChecker.cs @@ -3,20 +3,23 @@ // Modifications copyright (c) 2021-2024 MindPort GmbH using UnityEditor; +using VRBuilder.Editor.Settings; -[InitializeOnLoad] -public static class InputSystemChecker +namespace VRBuilder.Editor.Setup { - private const string message = - "VR Builder requires Unity's new Input System." + - "\n\nTo switch from the legacy input system to the new one, open the 'Player Settings' and set the " + - "option 'Active Input Handling' to 'Both' or 'Input System Package (New)'."; - - /// - /// This is a check if the new input system is active OR another concrete implementation of the InputController exists. - /// - static InputSystemChecker() + [InitializeOnLoad] + public static class InputSystemChecker { + private const string message = + "VR Builder requires Unity's new Input System." + + "\n\nTo switch from the legacy input system to the new one, open the 'Player Settings' and set the " + + "option 'Active Input Handling' to 'Both' or 'Input System Package (New)'."; + + /// + /// This is a check if the new input system is active OR another concrete implementation of the InputController exists. + /// + static InputSystemChecker() + { #if !INPUT_SYSTEM_PACKAGE || !ENABLE_INPUT_SYSTEM if (BuilderProjectSettings.Load().IsFirstTimeStarted == false) { @@ -24,5 +27,6 @@ static InputSystemChecker() } #endif + } } } diff --git a/Source/Core/Editor/ProcessUpgradeTool/Converters/SetObjectsWithTagEnabledBehaviorConverter.cs b/Source/Core/Editor/ProcessUpgradeTool/Converters/SetObjectsWithTagEnabledBehaviorConverter.cs index 3e6e8b92e..65e33852d 100644 --- a/Source/Core/Editor/ProcessUpgradeTool/Converters/SetObjectsWithTagEnabledBehaviorConverter.cs +++ b/Source/Core/Editor/ProcessUpgradeTool/Converters/SetObjectsWithTagEnabledBehaviorConverter.cs @@ -1,4 +1,5 @@ using VRBuilder.Core.Behaviors; +using VRBuilder.Core.SceneObjects; namespace VRBuilder.Editor.ProcessUpgradeTool { @@ -16,7 +17,16 @@ protected override SetObjectsEnabledBehavior PerformConversion(SetObjectsWithTag SetObjectsEnabledBehavior newBehavior = new SetObjectsEnabledBehavior(); newBehavior.Data.SetEnabled = oldBehavior.Data.SetEnabled; - newBehavior.Data.TargetObjects = oldBehavior.Data.TargetObjects; + if (oldBehavior.Data.TargetObjects.HasValue()) + { + newBehavior.Data.TargetObjects = oldBehavior.Data.TargetObjects; + } + else + { +#pragma warning disable CS0618 // Type or member is obsolete + newBehavior.Data.TargetObjects = new MultipleSceneObjectReference(oldBehavior.Data.Tag.Guid); +#pragma warning restore CS0618 // Type or member is obsolete + } newBehavior.Data.RevertOnDeactivation = oldBehavior.Data.RevertOnDeactivation; return newBehavior; diff --git a/Source/Core/Editor/ProcessUpgradeTool/ProcessUpgradeTool.cs b/Source/Core/Editor/ProcessUpgradeTool/ProcessUpgradeTool.cs index 6c35316bc..610d2778d 100644 --- a/Source/Core/Editor/ProcessUpgradeTool/ProcessUpgradeTool.cs +++ b/Source/Core/Editor/ProcessUpgradeTool/ProcessUpgradeTool.cs @@ -9,6 +9,7 @@ using VRBuilder.Core.Configuration; using VRBuilder.Core.EntityOwners; using VRBuilder.Core.SceneObjects; +using VRBuilder.Core.Settings; using VRBuilder.Core.Utils; using VRBuilder.Unity; @@ -58,6 +59,38 @@ public static IEnumerable Converters } } + [MenuItem("Tools/VR Builder/Developer/Update Object Groups", false, 75)] + private static void UpdateObjectGroupsMenuEntry() + { + if (EditorUtility.DisplayDialog("Update Object Groups", "If this project contains any legacy tags, these will be added to the list of object groups.\n" + + "Proceed?", "Yes", "No")) + { + UpdateObjectGroups(); + } + } + + private static void UpdateObjectGroups() + { + int counter = 0; +#pragma warning disable CS0618 // Type or member is obsolete + foreach (SceneObjectTags.Tag tag in SceneObjectTags.Instance.Tags) + { + if (SceneObjectGroups.Instance.GroupExists(tag.Guid) == false) + { + SceneObjectGroups.Instance.CreateGroup(tag.Label, tag.Guid); + counter++; + } + } +#pragma warning restore CS0618 // Type or member is obsolete + + if (counter > 0) + { + EditorUtility.SetDirty(SceneObjectGroups.Instance); + } + + Debug.Log($"Converted {counter} tags to object groups."); + } + [MenuItem("Tools/VR Builder/Developer/Update Process in Scene", false, 70)] private static void UpdateProcessMenuEntry() { @@ -85,10 +118,20 @@ private static void UpdateProcessMenuEntry() return; } + UpdateObjectGroups(); + IEnumerable processSceneObjects = SceneUtils.GetActiveAndInactiveComponents(); foreach (ProcessSceneObject sceneObject in processSceneObjects) { sceneObject.ResetUniqueId(); +#pragma warning disable CS0618 // Type or member is obsolete + foreach (Guid guid in sceneObject.Tags) + { + sceneObject.AddGuid(guid); + } +#pragma warning restore CS0618 // Type or member is obsolete + + EditorUtility.SetDirty(sceneObject); } UpdateDataOwnerRecursively(process); diff --git a/Source/Core/Editor/ProcessUpgradeTool/Updaters/PropertyUpdater.cs b/Source/Core/Editor/ProcessUpgradeTool/Updaters/PropertyUpdater.cs index 9c277f3d5..87fb99a69 100644 --- a/Source/Core/Editor/ProcessUpgradeTool/Updaters/PropertyUpdater.cs +++ b/Source/Core/Editor/ProcessUpgradeTool/Updaters/PropertyUpdater.cs @@ -32,23 +32,21 @@ public abstract class PropertyUpdater : IUpdater public void Update(MemberInfo memberInfo, object owner) { TNew propertyValue = (TNew)ReflectionUtils.GetValueFromPropertyOrField(owner, memberInfo); + string ownerName = owner is INamedData ? ((INamedData)owner).Name : owner.ToString(); if (ShouldBeUpdated(propertyValue) == false) { - string ownerName = owner is INamedData ? ((INamedData)owner).Name : owner.ToString(); Debug.Log($"Skipped {memberInfo.Name} in {ownerName}: does not need updating."); return; } if (AttemptToUpdateProperty(memberInfo, owner)) { - string ownerName = owner is INamedData ? ((INamedData)owner).Name : owner.ToString(); TNew updatedValue = (TNew)ReflectionUtils.GetValueFromPropertyOrField(owner, memberInfo); Debug.Log($"Successfully updated {memberInfo.Name} to {updatedValue} in {ownerName}."); } else { - string ownerName = owner is INamedData ? ((INamedData)owner).Name : owner.ToString(); Debug.LogWarning($"Failed to update {memberInfo.Name} in {ownerName}."); } } diff --git a/Source/Core/Editor/ProcessValidation/DisabledValidationHandler.cs b/Source/Core/Editor/ProcessValidation/DisabledValidationHandler.cs index 4132293b0..72d2bcf9d 100644 --- a/Source/Core/Editor/ProcessValidation/DisabledValidationHandler.cs +++ b/Source/Core/Editor/ProcessValidation/DisabledValidationHandler.cs @@ -1,26 +1,28 @@ -// Copyright (c) 2013-2019 Innoactive GmbH +// Copyright (c) 2013-2019 Innoactive GmbH // Licensed under the Apache License, Version 2.0 // Modifications copyright (c) 2021-2024 MindPort GmbH using VRBuilder.Core; -using VRBuilder.Editor.ProcessValidation; -/// -/// Does not validate, used to disabled the validation system. -/// -internal class DisabledValidationHandler : IValidationHandler +namespace VRBuilder.Editor.ProcessValidation { - public IContextResolver ContextResolver { get; set; } = null; + /// + /// Does not validate, used to disabled the validation system. + /// + internal class DisabledValidationHandler : IValidationHandler + { + public IContextResolver ContextResolver { get; set; } = null; - public IValidationReport LastReport { get; } = null; + public IValidationReport LastReport { get; } = null; - public bool IsAllowedToValidate() - { - return false; - } + public bool IsAllowedToValidate() + { + return false; + } - public IValidationReport Validate(IData data, IProcess process, IContext context = null) - { - return null; + public IValidationReport Validate(IData data, IProcess process, IContext context = null) + { + return null; + } } } diff --git a/Source/Core/Editor/UI/Drawers/MultiLineStringDrawer.cs b/Source/Core/Editor/UI/Drawers/MultiLineStringDrawer.cs new file mode 100644 index 000000000..fee1fa1da --- /dev/null +++ b/Source/Core/Editor/UI/Drawers/MultiLineStringDrawer.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2013-2019 Innoactive GmbH +// Licensed under the Apache License, Version 2.0 +// Modifications copyright (c) 2021-2024 MindPort GmbH + +using System; +using System.Linq; +using UnityEditor; +using UnityEngine; + +namespace VRBuilder.Editor.UI.Drawers +{ + /// + /// Process drawer for string members. + /// + internal class MultiLineStringDrawer : AbstractDrawer + { + /// + public override Rect Draw(Rect rect, object currentValue, Action changeValueCallback, GUIContent label) + { + string stringValue = (string)currentValue; + string newValue; + + // Calculate the height based on the wrapped text + GUIStyle style = new GUIStyle(EditorStyles.textArea) + { + wordWrap = true + }; + float textHeight = style.CalcHeight(new GUIContent(stringValue), rect.width); + + // Define the label and text areas + var labelRect = new Rect(rect.xMin, rect.yMin, rect.width, EditorGUIUtility.singleLineHeight); + var textRect = new Rect(rect.xMin, rect.yMin + labelRect.height + 2f, rect.width, textHeight); + + // Adjust the overall rect height to accommodate the text + rect = new Rect(rect.x, rect.y, rect.width, rect.height + textHeight); + + // Draw the label and text area + EditorGUI.LabelField(labelRect, label); + newValue = EditorGUI.TextArea(textRect, stringValue, style); + + if (stringValue != newValue) + { + ChangeValue(() => newValue, () => stringValue, changeValueCallback); + } + + return rect; + } + } +} diff --git a/Source/Core/Editor/UI/Drawers/MultiLineStringDrawer.cs.meta b/Source/Core/Editor/UI/Drawers/MultiLineStringDrawer.cs.meta new file mode 100644 index 000000000..cd9833f40 --- /dev/null +++ b/Source/Core/Editor/UI/Drawers/MultiLineStringDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 122c4a73f5494794996720a8f1c81652 +timeCreated: 1714393726 \ No newline at end of file diff --git a/Source/Core/Editor/UI/Drawers/ObjectDrawer.cs b/Source/Core/Editor/UI/Drawers/ObjectDrawer.cs index 19aefada6..e686d46e0 100644 --- a/Source/Core/Editor/UI/Drawers/ObjectDrawer.cs +++ b/Source/Core/Editor/UI/Drawers/ObjectDrawer.cs @@ -265,7 +265,7 @@ private GUIContent MergeGuiContents(GUIContent name, GUIContent typeName) { image = name.image, tooltip = name.tooltip, - }; + }; } else { diff --git a/Source/Core/Editor/UI/Menu/UpdateGroupsMenuEntry.cs b/Source/Core/Editor/UI/Menu/UpdateGroupsMenuEntry.cs deleted file mode 100644 index d56c118da..000000000 --- a/Source/Core/Editor/UI/Menu/UpdateGroupsMenuEntry.cs +++ /dev/null @@ -1,36 +0,0 @@ -using UnityEditor; -using UnityEngine; -using VRBuilder.Core.Settings; - -namespace VRBuilder.Editor.BuilderMenu -{ - internal static class UpdateGroupsMenuEntry - { - [MenuItem("Tools/VR Builder/Developer/Update Object Groups", false, 75)] - private static void UpdateObjectGroups() - { - if (EditorUtility.DisplayDialog("Update Object Groups", "If this project contains any legacy tags, these will be added to the list of object groups.\n" + - "Proceed?", "Yes", "No")) - { - int counter = 0; -#pragma warning disable CS0618 // Type or member is obsolete - foreach (SceneObjectTags.Tag tag in SceneObjectTags.Instance.Tags) - { - if (SceneObjectGroups.Instance.GroupExists(tag.Guid) == false) - { - SceneObjectGroups.Instance.CreateGroup(tag.Label, tag.Guid); - counter++; - } - } -#pragma warning restore CS0618 // Type or member is obsolete - - if (counter > 0) - { - EditorUtility.SetDirty(SceneObjectGroups.Instance); - } - - Debug.Log($"Converted {counter} tags to object groups."); - } - } - } -} diff --git a/Source/Core/Editor/UI/ProjectSettings/LanguageSettingsProvider.cs b/Source/Core/Editor/UI/ProjectSettings/LanguageSettingsProvider.cs index e66a09965..c67028c54 100644 --- a/Source/Core/Editor/UI/ProjectSettings/LanguageSettingsProvider.cs +++ b/Source/Core/Editor/UI/ProjectSettings/LanguageSettingsProvider.cs @@ -2,21 +2,20 @@ // Licensed under the Apache License, Version 2.0 // Modifications copyright (c) 2021-2024 MindPort GmbH +using System.Collections.Generic; using UnityEditor; -using VRBuilder.Editor.UI; -using VRBuilder.Core.Localization; using UnityEngine; -using UnityEngine.Localization.Settings; -using System.Collections.Generic; using UnityEngine.Localization; +using UnityEngine.Localization.Settings; +using VRBuilder.Core.Localization; -namespace VRBuilder.Editor.Localization +namespace VRBuilder.Editor.UI { public class LanguageSettingsProvider : BaseSettingsProvider { const string Path = "Project/VR Builder/Language"; - public LanguageSettingsProvider() : base(Path, SettingsScope.Project) {} + public LanguageSettingsProvider() : base(Path, SettingsScope.Project) { } protected override void InternalDraw(string searchContext) { @@ -37,7 +36,7 @@ private void ShowLanguageSelector() LanguageSettings.Instance.ApplicationLanguage = EditorGUILayout.TextField("Language Code", LanguageSettings.Instance.ApplicationLanguage); Locale locale = LanguageSettings.Instance.GetLocaleFromString(LanguageSettings.Instance.ApplicationLanguage); - if (locale.Identifier.CultureInfo != null ) + if (locale.Identifier.CultureInfo != null) { EditorGUILayout.LabelField($"Application language: {locale}"); } @@ -50,7 +49,7 @@ private void ShowLanguageSelector() private void ShowLocalePopup() { GUI.enabled = false; - EditorGUILayout.TextField("Project Locale ", LocalizationSettings.ProjectLocale? LocalizationSettings.ProjectLocale.ToString() : "None"); + EditorGUILayout.TextField("Project Locale ", LocalizationSettings.ProjectLocale ? LocalizationSettings.ProjectLocale.ToString() : "None"); GUI.enabled = true; if (LocalizationSettings.AvailableLocales != null && LocalizationSettings.AvailableLocales.Locales.Count > 1) @@ -80,7 +79,7 @@ private void ShowLocalePopup() GUI.enabled = true; } } - + public override void OnDeactivate() { diff --git a/Source/Core/Editor/UI/Wizard/Setup/InteractionSettingsPage.cs b/Source/Core/Editor/UI/Wizard/Setup/InteractionSettingsPage.cs index 61580ee51..41a2a9c6a 100644 --- a/Source/Core/Editor/UI/Wizard/Setup/InteractionSettingsPage.cs +++ b/Source/Core/Editor/UI/Wizard/Setup/InteractionSettingsPage.cs @@ -1,41 +1,42 @@ using UnityEngine; using VRBuilder.Core.Settings; -using VRBuilder.Editor.UI; -using VRBuilder.Editor.UI.Wizard; -/// -/// Wizard page where the user can set up interaction preferences. -/// -internal class InteractionSettingsPage : WizardPage +namespace VRBuilder.Editor.UI.Wizard { - [SerializeField] - private bool makeGrabbablesKinematic; - - public InteractionSettingsPage() : base("Interaction Settings") + /// + /// Wizard page where the user can set up interaction preferences. + /// + internal class InteractionSettingsPage : WizardPage { - makeGrabbablesKinematic = InteractionSettings.Instance.MakeGrabbablesKinematic; - } + [SerializeField] + private bool makeGrabbablesKinematic; - public override void Draw(Rect window) - { - GUILayout.BeginArea(window); + public InteractionSettingsPage() : base("Interaction Settings") + { + makeGrabbablesKinematic = InteractionSettings.Instance.MakeGrabbablesKinematic; + } - GUILayout.Label("Interaction Settings", BuilderEditorStyles.Title); + public override void Draw(Rect window) + { + GUILayout.BeginArea(window); - GUILayout.Label("You can choose how VR Builder configures objects that it makes grabbable. If you check the option below, the object will ignore physics and stay in place when the user releases it, even in mid-air. Otherwise, it will fall to the floor due to gravity.", BuilderEditorStyles.Paragraph); + GUILayout.Label("Interaction Settings", BuilderEditorStyles.Title); - GUILayout.Space(16); + GUILayout.Label("You can choose how VR Builder configures objects that it makes grabbable. If you check the option below, the object will ignore physics and stay in place when the user releases it, even in mid-air. Otherwise, it will fall to the floor due to gravity.", BuilderEditorStyles.Paragraph); - makeGrabbablesKinematic = GUILayout.Toggle(makeGrabbablesKinematic, "Make newly created grabbables ignore physics", BuilderEditorStyles.Toggle); + GUILayout.Space(16); - GUILayout.EndArea(); - } + makeGrabbablesKinematic = GUILayout.Toggle(makeGrabbablesKinematic, "Make newly created grabbables ignore physics", BuilderEditorStyles.Toggle); - public override void Apply() - { - base.Apply(); + GUILayout.EndArea(); + } + + public override void Apply() + { + base.Apply(); - InteractionSettings.Instance.MakeGrabbablesKinematic = makeGrabbablesKinematic; - InteractionSettings.Instance.Save(); + InteractionSettings.Instance.MakeGrabbablesKinematic = makeGrabbablesKinematic; + InteractionSettings.Instance.Save(); + } } } diff --git a/Source/Core/Editor/UI/Wizard/Setup/LocalizationSettingsPage.cs b/Source/Core/Editor/UI/Wizard/Setup/LocalizationSettingsPage.cs index 8a92c47d0..03f9b07b3 100644 --- a/Source/Core/Editor/UI/Wizard/Setup/LocalizationSettingsPage.cs +++ b/Source/Core/Editor/UI/Wizard/Setup/LocalizationSettingsPage.cs @@ -3,231 +3,232 @@ using UnityEditor.Localization.UI; using UnityEngine; using UnityEngine.Localization.Settings; -using VRBuilder.Editor.UI; -using VRBuilder.Editor.UI.Wizard; -/// -/// Wizard page where the user can set up localization preferences. -/// -internal class LocalizationSettingsPage : WizardPage +namespace VRBuilder.Editor.UI.Wizard { - private static Texts s_Texts; - - private bool projectSettingsOpened = false; - - [SerializeField] - private bool skipLocalization = true; - - public LocalizationSettingsPage() : base("Localization Settings") - { - projectSettingsOpened = false; - } - - public override void Apply() + /// + /// Wizard page where the user can set up localization preferences. + /// + internal class LocalizationSettingsPage : WizardPage { - base.Apply(); - } + private static Texts s_Texts; - public override void Draw(Rect window) - { - GUILayout.BeginArea(window); + private bool projectSettingsOpened = false; - GUILayout.Label("Unity Localization", BuilderEditorStyles.Title); + [SerializeField] + private bool skipLocalization = true; - if (GUILayout.Toggle(skipLocalization, "Use a single language in this project", BuilderEditorStyles.RadioButton)) + public LocalizationSettingsPage() : base("Localization Settings") { - skipLocalization = true; + projectSettingsOpened = false; } - if (GUILayout.Toggle(!skipLocalization, "Configure Unity localization to create a multi-language application", BuilderEditorStyles.RadioButton)) + public override void Apply() { - skipLocalization = false; + base.Apply(); } - if (skipLocalization == false) + public override void Draw(Rect window) { - DisplayLocalizationInstructions(); - } - GUILayout.EndArea(); - } + GUILayout.BeginArea(window); - private void DisplayLocalizationInstructions() - { - GUILayout.Label("For VR Builder Localization it is recommended to do the following steps:", BuilderEditorStyles.Paragraph); + GUILayout.Label("Unity Localization", BuilderEditorStyles.Title); - DrawHowToCreateLocalizationSettingsFile(); - DrawHowToCreateLanguagesAndLocales(); - DrawHowToChooseDefaultLanguageAndLocale(); - DrawHowToCreateStringTableCollection(); - DrawSelectLocalizationTable(); + if (GUILayout.Toggle(skipLocalization, "Use a single language in this project", BuilderEditorStyles.RadioButton)) + { + skipLocalization = true; + } - GUILayout.Space(16); + if (GUILayout.Toggle(!skipLocalization, "Configure Unity localization to create a multi-language application", BuilderEditorStyles.RadioButton)) + { + skipLocalization = false; + } - if (LocalizationEditorSettings.ActiveLocalizationSettings == null) - { - DrawCreateLocalizationSettingsFile(); - } - else - { - DrawProjectSettingsLocalization(); + if (skipLocalization == false) + { + DisplayLocalizationInstructions(); + } + GUILayout.EndArea(); } - } - private void DrawHowToCreateLocalizationSettingsFile() - { - GUILayout.BeginHorizontal(); - if (LocalizationEditorSettings.ActiveLocalizationSettings != null) - { - ShowCheckMarkToggle(); - } - else + private void DisplayLocalizationInstructions() { + GUILayout.Label("For VR Builder Localization it is recommended to do the following steps:", BuilderEditorStyles.Paragraph); + + DrawHowToCreateLocalizationSettingsFile(); + DrawHowToCreateLanguagesAndLocales(); + DrawHowToChooseDefaultLanguageAndLocale(); + DrawHowToCreateStringTableCollection(); + DrawSelectLocalizationTable(); + GUILayout.Space(16); - } - GUILayout.Label("1. Create a Localization Settings File", BuilderEditorStyles.Paragraph); - GUILayout.EndHorizontal(); - BuilderGUILayout.DrawLink("Quick Start Guide: Create the Localization Settings", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#create-the-localization-settings", BuilderEditorStyles.IndentLarge); - } - private void DrawHowToCreateLanguagesAndLocales() - { - GUILayout.BeginHorizontal(); - if ((LocalizationEditorSettings.ActiveLocalizationSettings != null && LocalizationEditorSettings.ActiveLocalizationSettings.GetAvailableLocales() != null && LocalizationEditorSettings.ActiveLocalizationSettings.GetAvailableLocales().Locales.Count > 0) - || (LocalizationSettings.HasSettings && (LocalizationSettings.AvailableLocales.Locales.Count > 0 || LocalizationSettings.SelectedLocale != null || LocalizationSettings.ProjectLocale != null))) - { - ShowCheckMarkToggle(); + if (LocalizationEditorSettings.ActiveLocalizationSettings == null) + { + DrawCreateLocalizationSettingsFile(); + } + else + { + DrawProjectSettingsLocalization(); + } } - else + + private void DrawHowToCreateLocalizationSettingsFile() { - GUILayout.Space(16); + GUILayout.BeginHorizontal(); + if (LocalizationEditorSettings.ActiveLocalizationSettings != null) + { + ShowCheckMarkToggle(); + } + else + { + GUILayout.Space(16); + } + GUILayout.Label("1. Create a Localization Settings File", BuilderEditorStyles.Paragraph); + GUILayout.EndHorizontal(); + BuilderGUILayout.DrawLink("Quick Start Guide: Create the Localization Settings", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#create-the-localization-settings", BuilderEditorStyles.IndentLarge); } - GUILayout.Label("2. Create Languages / Locales", BuilderEditorStyles.Paragraph); - GUILayout.EndHorizontal(); - BuilderGUILayout.DrawLink("Quick Start Guide: Create locales", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#create-locales", BuilderEditorStyles.IndentLarge); - } - private void DrawHowToChooseDefaultLanguageAndLocale() - { - GUILayout.BeginHorizontal(); - if (LocalizationEditorSettings.ActiveLocalizationSettings != null && LocalizationSettings.ProjectLocale != null) + private void DrawHowToCreateLanguagesAndLocales() { - ShowCheckMarkToggle(); + GUILayout.BeginHorizontal(); + if ((LocalizationEditorSettings.ActiveLocalizationSettings != null && LocalizationEditorSettings.ActiveLocalizationSettings.GetAvailableLocales() != null && LocalizationEditorSettings.ActiveLocalizationSettings.GetAvailableLocales().Locales.Count > 0) + || (LocalizationSettings.HasSettings && (LocalizationSettings.AvailableLocales.Locales.Count > 0 || LocalizationSettings.SelectedLocale != null || LocalizationSettings.ProjectLocale != null))) + { + ShowCheckMarkToggle(); + } + else + { + GUILayout.Space(16); + } + GUILayout.Label("2. Create Languages / Locales", BuilderEditorStyles.Paragraph); + GUILayout.EndHorizontal(); + BuilderGUILayout.DrawLink("Quick Start Guide: Create locales", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#create-locales", BuilderEditorStyles.IndentLarge); } - else + + private void DrawHowToChooseDefaultLanguageAndLocale() { - GUILayout.Space(16); + GUILayout.BeginHorizontal(); + if (LocalizationEditorSettings.ActiveLocalizationSettings != null && LocalizationSettings.ProjectLocale != null) + { + ShowCheckMarkToggle(); + } + else + { + GUILayout.Space(16); + } + GUILayout.Label("3. Choose a default Language / Locale", BuilderEditorStyles.Paragraph); + GUILayout.EndHorizontal(); + BuilderGUILayout.DrawLink("Quick Start Guide: Choose a default Locale", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#choose-a-default-locale", BuilderEditorStyles.IndentLarge); } - GUILayout.Label("3. Choose a default Language / Locale", BuilderEditorStyles.Paragraph); - GUILayout.EndHorizontal(); - BuilderGUILayout.DrawLink("Quick Start Guide: Choose a default Locale", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#choose-a-default-locale", BuilderEditorStyles.IndentLarge); - } - private void DrawHowToCreateStringTableCollection() - { - GUILayout.BeginHorizontal(); - if (LocalizationEditorSettings.GetStringTableCollections().Count > 0) + private void DrawHowToCreateStringTableCollection() { - ShowCheckMarkToggle(); + GUILayout.BeginHorizontal(); + if (LocalizationEditorSettings.GetStringTableCollections().Count > 0) + { + ShowCheckMarkToggle(); + } + else + { + GUILayout.Space(16); + } + GUILayout.Label("4. Create a String Table Collection", BuilderEditorStyles.Paragraph); + GUILayout.EndHorizontal(); + BuilderGUILayout.DrawLink("Quick Start Guide: Localize Strings", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#localize-strings", BuilderEditorStyles.IndentLarge); } - else + + private void DrawSelectLocalizationTable() { + GUILayout.BeginHorizontal(); GUILayout.Space(16); + GUILayout.Label("5. Select the string table just created on the PROCESS_CONFIGURATION\n game object in your scene.", BuilderEditorStyles.Paragraph); + GUILayout.EndHorizontal(); } - GUILayout.Label("4. Create a String Table Collection", BuilderEditorStyles.Paragraph); - GUILayout.EndHorizontal(); - BuilderGUILayout.DrawLink("Quick Start Guide: Localize Strings", "https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/QuickStartGuideWithVariants.html#localize-strings", BuilderEditorStyles.IndentLarge); - } - - private void DrawSelectLocalizationTable() - { - GUILayout.BeginHorizontal(); - GUILayout.Space(16); - GUILayout.Label("5. Select the string table just created on the PROCESS_CONFIGURATION\n game object in your scene.", BuilderEditorStyles.Paragraph); - GUILayout.EndHorizontal(); - } - private void DrawCreateLocalizationSettingsFile() - { - GUILayout.Label("Create a Localization Settings File", BuilderEditorStyles.Header); - GUILayout.Label("Click the button to create a Localization Settings File.", BuilderEditorStyles.Paragraph); + private void DrawCreateLocalizationSettingsFile() + { + GUILayout.Label("Create a Localization Settings File", BuilderEditorStyles.Header); + GUILayout.Label("Click the button to create a Localization Settings File.", BuilderEditorStyles.Paragraph); - GUILayout.Space(8); + GUILayout.Space(8); - if (s_Texts == null) - s_Texts = new Texts(); + if (s_Texts == null) + s_Texts = new Texts(); - EditorGUI.BeginChangeCheck(); - var obj = EditorGUILayout.ObjectField(s_Texts.activeSettings, LocalizationEditorSettings.ActiveLocalizationSettings, typeof(LocalizationSettings), false) as LocalizationSettings; - if (EditorGUI.EndChangeCheck()) - { - LocalizationEditorSettings.ActiveLocalizationSettings = obj; - } - EditorGUILayout.HelpBox(s_Texts.noSettingsMsg.text, MessageType.Info, true); - if (GUILayout.Button("Create Localization Settings", GUILayout.Width(300))) - { - var created = CreateLocalizationAsset(); - if (created != null) + EditorGUI.BeginChangeCheck(); + var obj = EditorGUILayout.ObjectField(s_Texts.activeSettings, LocalizationEditorSettings.ActiveLocalizationSettings, typeof(LocalizationSettings), false) as LocalizationSettings; + if (EditorGUI.EndChangeCheck()) + { + LocalizationEditorSettings.ActiveLocalizationSettings = obj; + } + EditorGUILayout.HelpBox(s_Texts.noSettingsMsg.text, MessageType.Info, true); + if (GUILayout.Button("Create Localization Settings", GUILayout.Width(300))) { - LocalizationEditorSettings.ActiveLocalizationSettings = created; + var created = CreateLocalizationAsset(); + if (created != null) + { + LocalizationEditorSettings.ActiveLocalizationSettings = created; + } } } - } - - private LocalizationSettings CreateLocalizationAsset() - { - var path = EditorUtility.SaveFilePanelInProject("Save Localization Settings", "Localization Settings", "asset", "Please enter a filename to save the projects localization settings to."); - if (string.IsNullOrEmpty(path)) + private LocalizationSettings CreateLocalizationAsset() { - return null; - } + var path = EditorUtility.SaveFilePanelInProject("Save Localization Settings", "Localization Settings", "asset", "Please enter a filename to save the projects localization settings to."); - var settings = ScriptableObject.CreateInstance(); - settings.name = "VR Builder Localization Settings"; + if (string.IsNullOrEmpty(path)) + { + return null; + } - AssetDatabase.CreateAsset(settings, path); - AssetDatabase.SaveAssets(); - return settings; - } + var settings = ScriptableObject.CreateInstance(); + settings.name = "VR Builder Localization Settings"; - private void DrawProjectSettingsLocalization() - { - GUILayout.Label("Project Settings: Localization", BuilderEditorStyles.Header); - GUILayout.Label("Use the Locale Generator to add new Languages to the Available Locales List.", BuilderEditorStyles.Paragraph); + AssetDatabase.CreateAsset(settings, path); + AssetDatabase.SaveAssets(); + return settings; + } - if (GUILayout.Button("Open Localization Project Settings", GUILayout.Width(300))) + private void DrawProjectSettingsLocalization() { - var settingsWindow = SettingsService.OpenProjectSettings("Project/Localization"); - projectSettingsOpened = true; - } + GUILayout.Label("Project Settings: Localization", BuilderEditorStyles.Header); + GUILayout.Label("Use the Locale Generator to add new Languages to the Available Locales List.", BuilderEditorStyles.Paragraph); - GUILayout.Space(8); + if (GUILayout.Button("Open Localization Project Settings", GUILayout.Width(300))) + { + var settingsWindow = SettingsService.OpenProjectSettings("Project/Localization"); + projectSettingsOpened = true; + } - if (projectSettingsOpened || (LocalizationSettings.AvailableLocales != null && LocalizationSettings.AvailableLocales.Locales.Count > 0)) - { - GUILayout.Label("Localization Tables", BuilderEditorStyles.Header); - GUILayout.Label("It is recommended to start with creating a new String Table Collection.", BuilderEditorStyles.Paragraph); + GUILayout.Space(8); - if (GUILayout.Button("Open Localization Tables Window", GUILayout.Width(300))) + if (projectSettingsOpened || (LocalizationSettings.AvailableLocales != null && LocalizationSettings.AvailableLocales.Locales.Count > 0)) { - LocalizationTablesWindow.ShowWindow(); + GUILayout.Label("Localization Tables", BuilderEditorStyles.Header); + GUILayout.Label("It is recommended to start with creating a new String Table Collection.", BuilderEditorStyles.Paragraph); + + if (GUILayout.Button("Open Localization Tables Window", GUILayout.Width(300))) + { + LocalizationTablesWindow.ShowWindow(); + } } } - } - private void ShowCheckMarkToggle() - { - var backgroundColor = GUI.backgroundColor; - GUI.backgroundColor = Color.green; - GUI.enabled = false; - GUILayout.Toggle(true, "", GUILayout.Width(8)); - GUI.enabled = true; - GUI.backgroundColor = backgroundColor; - } + private void ShowCheckMarkToggle() + { + var backgroundColor = GUI.backgroundColor; + GUI.backgroundColor = Color.green; + GUI.enabled = false; + GUILayout.Toggle(true, "", GUILayout.Width(8)); + GUI.enabled = true; + GUI.backgroundColor = backgroundColor; + } - private class Texts - { - public GUIContent activeSettings = EditorGUIUtility.TrTextContent("Active Settings", "The Localization Settings that will be used by this project and included into any builds."); - public GUIContent noSettingsMsg = EditorGUIUtility.TrTextContent("You have no active Localization Settings. Would you like to create one?"); + private class Texts + { + public GUIContent activeSettings = EditorGUIUtility.TrTextContent("Active Settings", "The Localization Settings that will be used by this project and included into any builds."); + public GUIContent noSettingsMsg = EditorGUIUtility.TrTextContent("You have no active Localization Settings. Would you like to create one?"); + } } } diff --git a/Source/Core/Editor/UI/Wizard/Setup/ProjectSetupWizard.cs b/Source/Core/Editor/UI/Wizard/Setup/ProjectSetupWizard.cs index 65bdc34e4..d63642f2f 100644 --- a/Source/Core/Editor/UI/Wizard/Setup/ProjectSetupWizard.cs +++ b/Source/Core/Editor/UI/Wizard/Setup/ProjectSetupWizard.cs @@ -10,6 +10,7 @@ using VRBuilder.Core.Configuration; using VRBuilder.Core.Utils; using VRBuilder.Editor.PackageManager; +using VRBuilder.Editor.Settings; using VRBuilder.Editor.XRUtils; namespace VRBuilder.Editor.UI.Wizard diff --git a/Source/Core/Editor/UI/Wizard/Setup/XRSDKSetupPage.cs b/Source/Core/Editor/UI/Wizard/Setup/XRSDKSetupPage.cs index 4cbb64145..c96318731 100644 --- a/Source/Core/Editor/UI/Wizard/Setup/XRSDKSetupPage.cs +++ b/Source/Core/Editor/UI/Wizard/Setup/XRSDKSetupPage.cs @@ -2,10 +2,11 @@ // Licensed under the Apache License, Version 2.0 // Modifications copyright (c) 2021-2024 MindPort GmbH -using UnityEngine; using System; -using System.Linq; using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using VRBuilder.Editor.Settings; using VRBuilder.Editor.XRUtils; namespace VRBuilder.Editor.UI.Wizard @@ -132,7 +133,7 @@ public override void Closing(bool isCompleted) { if (isCompleted && wasApplied) { - foreach(XRLoader loader in selectedLoaders) + foreach (XRLoader loader in selectedLoaders) { switch (loader) { diff --git a/Source/Core/Editor/UI/Wizard/WizardWindow.cs b/Source/Core/Editor/UI/Wizard/WizardWindow.cs index 53768dba0..b4acc9528 100644 --- a/Source/Core/Editor/UI/Wizard/WizardWindow.cs +++ b/Source/Core/Editor/UI/Wizard/WizardWindow.cs @@ -7,6 +7,7 @@ using System.Linq; using UnityEditor; using UnityEngine; +using VRBuilder.Editor.Settings; namespace VRBuilder.Editor.UI.Wizard { diff --git a/Source/Core/Editor/Unity/AssemblySymbolChecker.cs b/Source/Core/Editor/Unity/AssemblySymbolChecker.cs index 10ca614e7..bce324fd9 100644 --- a/Source/Core/Editor/Unity/AssemblySymbolChecker.cs +++ b/Source/Core/Editor/Unity/AssemblySymbolChecker.cs @@ -4,108 +4,110 @@ using System.Collections.Generic; using System.Linq; -using VRBuilder.Editor; using UnityEditor; using VRBuilder.Editor.Settings; -/// -/// Checks for assemblies specified and adds/removes the symbol according to their existence. -/// -[InitializeOnLoad] -internal class AssemblySymbolChecker +namespace VRBuilder.Editor.Setup { - static AssemblySymbolChecker() + /// + /// Checks for assemblies specified and adds/removes the symbol according to their existence. + /// + [InitializeOnLoad] + internal class AssemblySymbolChecker { - CheckForAssembly("VRBuilder.Core", "VR_BUILDER"); - CheckForAssembly("VRBuilder.XRInteraction", "VR_BUILDER_XR_INTERACTION"); - CheckForAssembly("VRBuilder.Animations", "VR_BUILDER_ANIMATIONS"); - CheckForAssembly("VRBuilder.StatesAndData", "VR_BUILDER_STATES_DATA"); - CheckForAssembly("Unity.Netcode.Components", "UNITY_NETCODE"); - - // Postpone if editor is busy to avoid errors - if (!EditorApplication.isUpdating) - { - AddXRInteraction(); - } - else + static AssemblySymbolChecker() { - EditorApplication.delayCall += () => + CheckForAssembly("VRBuilder.Core", "VR_BUILDER"); + CheckForAssembly("VRBuilder.XRInteraction", "VR_BUILDER_XR_INTERACTION"); + CheckForAssembly("VRBuilder.Animations", "VR_BUILDER_ANIMATIONS"); + CheckForAssembly("VRBuilder.StatesAndData", "VR_BUILDER_STATES_DATA"); + CheckForAssembly("Unity.Netcode.Components", "UNITY_NETCODE"); + + // Postpone if editor is busy to avoid errors + if (!EditorApplication.isUpdating) { AddXRInteraction(); - }; + } + else + { + EditorApplication.delayCall += () => + { + AddXRInteraction(); + }; + } } - } - private static void AddXRInteraction() - { - if (InteractionComponentSettings.Instance.EnableXRInteractionComponent) - { - AddSymbol("VR_BUILDER_ENABLE_XR_INTERACTION"); - } - else - { - RemoveSymbol("VR_BUILDER_XR_INTERACTION"); - RemoveSymbol("VR_BUILDER_ENABLE_XR_INTERACTION"); - } - } - /// - /// Tries to find the given assembly name, and add/removes the symbol according to the existence of it. - /// - /// The assembly name looked for, just the name, no full name. - /// The symbol added/removed. - public static void CheckForAssembly(string assemblyName, string symbol) - { - if (EditorReflectionUtils.AssemblyExists(assemblyName)) + private static void AddXRInteraction() { - AddSymbol(symbol); + if (InteractionComponentSettings.Instance.EnableXRInteractionComponent) + { + AddSymbol("VR_BUILDER_ENABLE_XR_INTERACTION"); + } + else + { + RemoveSymbol("VR_BUILDER_XR_INTERACTION"); + RemoveSymbol("VR_BUILDER_ENABLE_XR_INTERACTION"); + } } - else + /// + /// Tries to find the given assembly name, and add/removes the symbol according to the existence of it. + /// + /// The assembly name looked for, just the name, no full name. + /// The symbol added/removed. + public static void CheckForAssembly(string assemblyName, string symbol) { - RemoveSymbol(symbol); + if (EditorReflectionUtils.AssemblyExists(assemblyName)) + { + AddSymbol(symbol); + } + else + { + RemoveSymbol(symbol); + } } - } - /// - /// Tries to find the given assembly name, and add/removes the symbol according to the existence of it. - /// - /// The assembly name looked for, just the name, no full name. - /// The class name looked for. - /// The symbol added/removed. - public static void CheckForClass(string assemblyName, string className, string symbol) - { - if (EditorReflectionUtils.ClassExists(assemblyName, className)) + /// + /// Tries to find the given assembly name, and add/removes the symbol according to the existence of it. + /// + /// The assembly name looked for, just the name, no full name. + /// The class name looked for. + /// The symbol added/removed. + public static void CheckForClass(string assemblyName, string className, string symbol) { - AddSymbol(symbol); - } - else - { - RemoveSymbol(symbol); + if (EditorReflectionUtils.ClassExists(assemblyName, className)) + { + AddSymbol(symbol); + } + else + { + RemoveSymbol(symbol); + } } - } - private static void AddSymbol(string symbol) - { - BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget; - BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget); - List symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';').ToList(); - - if (symbols.Contains(symbol) == false) + private static void AddSymbol(string symbol) { - symbols.Add(symbol); - PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", symbols.ToArray())); - } - } + BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget; + BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget); + List symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';').ToList(); - private static void RemoveSymbol(string symbol) - { - BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget; - BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget); - List symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';').ToList(); + if (symbols.Contains(symbol) == false) + { + symbols.Add(symbol); + PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", symbols.ToArray())); + } + } - if (symbols.Contains(symbol)) + private static void RemoveSymbol(string symbol) { - symbols.Remove(symbol); - PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", symbols.ToArray())); + BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget; + BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget); + List symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';').ToList(); + + if (symbols.Contains(symbol)) + { + symbols.Remove(symbol); + PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", symbols.ToArray())); + } } } } diff --git a/Source/Core/Editor/Unity/PreBuildCloseProcessEditor.cs b/Source/Core/Editor/Unity/PreBuildCloseProcessEditor.cs index 0b447b367..dce6f9a63 100644 --- a/Source/Core/Editor/Unity/PreBuildCloseProcessEditor.cs +++ b/Source/Core/Editor/Unity/PreBuildCloseProcessEditor.cs @@ -13,7 +13,7 @@ namespace VRBuilder.Editor public class PreBuildCloseProcessEditor : IPreprocessBuildWithReport { /// - public int callbackOrder => 1; + public int callbackOrder => 2; /// public void OnPreprocessBuild(BuildReport report) diff --git a/Source/Core/Editor/Unity/PreBuildLinkXMLCreator.cs b/Source/Core/Editor/Unity/PreBuildLinkXMLCreator.cs new file mode 100644 index 000000000..2e11ebf0f --- /dev/null +++ b/Source/Core/Editor/Unity/PreBuildLinkXMLCreator.cs @@ -0,0 +1,54 @@ +using System.IO; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; + +namespace VRBuilder.Editor +{ + /// + /// Generates a file before the build process to preserve all Behaviors and Conditions from VR Builder add-ons. + /// + /// + /// The existing in the will be overwritten. + /// + public class PreBuildLinkXMLCreator : IPreprocessBuildWithReport + { + public int callbackOrder => 3; + public const string VRBuilderRootFolder = "Assets/MindPort/VR Builder"; + public const string LinkXML = "link.xml"; + + public void OnPreprocessBuild(BuildReport report) + { + if (!Directory.Exists(VRBuilderRootFolder)) + { + Directory.CreateDirectory(VRBuilderRootFolder); + } + + string linkXmlPath = Path.Combine(VRBuilderRootFolder, LinkXML); + string linkXmlContent = @" + + + + + + + + + + + + + + + + + + + + + +"; + + File.WriteAllText(linkXmlPath, linkXmlContent); + } + } +} \ No newline at end of file diff --git a/Source/Core/Editor/UI/Menu/UpdateGroupsMenuEntry.cs.meta b/Source/Core/Editor/Unity/PreBuildLinkXMLCreator.cs.meta similarity index 83% rename from Source/Core/Editor/UI/Menu/UpdateGroupsMenuEntry.cs.meta rename to Source/Core/Editor/Unity/PreBuildLinkXMLCreator.cs.meta index dd647b7b2..9e2646a8e 100644 --- a/Source/Core/Editor/UI/Menu/UpdateGroupsMenuEntry.cs.meta +++ b/Source/Core/Editor/Unity/PreBuildLinkXMLCreator.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5e03b6d4af66c024f928bb0a15b082a4 +guid: 992baad1a51bd0c41ba601a43a7f1591 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Source/Core/Editor/XRUtils/XRLoaderHelper.cs b/Source/Core/Editor/XRUtils/XRLoaderHelper.cs index 6b12f6553..814657546 100644 --- a/Source/Core/Editor/XRUtils/XRLoaderHelper.cs +++ b/Source/Core/Editor/XRUtils/XRLoaderHelper.cs @@ -8,6 +8,8 @@ using System.Collections.Generic; using VRBuilder.Editor.PackageManager; using Debug = UnityEngine.Debug; +using VRBuilder.Editor.Settings; + #if UNITY_XR_MANAGEMENT using UnityEngine; diff --git a/Source/Core/Editor/XRUtils/XRManagementPackageEnabler.cs b/Source/Core/Editor/XRUtils/XRManagementPackageEnabler.cs index 7d27ba953..b9bd914a3 100644 --- a/Source/Core/Editor/XRUtils/XRManagementPackageEnabler.cs +++ b/Source/Core/Editor/XRUtils/XRManagementPackageEnabler.cs @@ -3,11 +3,10 @@ // Modifications copyright (c) 2021-2024 MindPort GmbH #if UNITY_XR_MANAGEMENT -using UnityEditor; using System; -using VRBuilder.Editor.PackageManager; -using UnityEngine; using System.Linq; +using VRBuilder.Editor.PackageManager; +using VRBuilder.Editor.Settings; namespace VRBuilder.Editor.XRUtils { @@ -39,7 +38,7 @@ private void InitializeXRLoader(object sender, EventArgs e) { BuilderProjectSettings settings = BuilderProjectSettings.Load(); - if(settings.XRSDKs.Count > 0 ) + if (settings.XRSDKs.Count > 0) { XRLoaderHelper.XRSDK sdk = settings.XRSDKs.First(); diff --git a/Source/Core/Editor/XRUtils/XRProviders/OpenXRPackageEnabler.cs b/Source/Core/Editor/XRUtils/XRProviders/OpenXRPackageEnabler.cs index 2d2ccff4c..aefe97253 100644 --- a/Source/Core/Editor/XRUtils/XRProviders/OpenXRPackageEnabler.cs +++ b/Source/Core/Editor/XRUtils/XRProviders/OpenXRPackageEnabler.cs @@ -9,6 +9,7 @@ using UnityEditor.XR.OpenXR.Features; using UnityEngine.XR.OpenXR; using UnityEngine.XR.OpenXR.Features; +using VRBuilder.Editor.Settings; namespace VRBuilder.Editor.XRUtils { diff --git a/Source/Core/Runtime/Behaviors/EmptyProcess.cs b/Source/Core/Runtime/Behaviors/EmptyProcess.cs index 98079f56e..e8746de9d 100644 --- a/Source/Core/Runtime/Behaviors/EmptyProcess.cs +++ b/Source/Core/Runtime/Behaviors/EmptyProcess.cs @@ -3,31 +3,33 @@ // Modifications copyright (c) 2021-2024 MindPort GmbH using System.Collections; -using VRBuilder.Core; -/// -/// A stage process that does nothing. -/// -public sealed class EmptyProcess : IStageProcess +namespace VRBuilder.Core { - /// - public void Start() + /// + /// A stage process that does nothing. + /// + public sealed class EmptyProcess : IStageProcess { - } + /// + public void Start() + { + } - /// - public IEnumerator Update() - { - yield break; - } + /// + public IEnumerator Update() + { + yield break; + } - /// - public void End() - { - } + /// + public void End() + { + } - /// - public void FastForward() - { + /// + public void FastForward() + { + } } } diff --git a/Source/Core/Runtime/Chapter.cs b/Source/Core/Runtime/Chapter.cs index ae1abd78b..b36b9530e 100644 --- a/Source/Core/Runtime/Chapter.cs +++ b/Source/Core/Runtime/Chapter.cs @@ -2,17 +2,17 @@ // Licensed under the Apache License, Version 2.0 // Modifications copyright (c) 2021-2024 MindPort GmbH -using UnityEngine; -using System.Linq; +using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; +using UnityEngine; using VRBuilder.Core.Attributes; using VRBuilder.Core.Configuration.Modes; using VRBuilder.Core.EntityOwners; using VRBuilder.Core.Exceptions; using VRBuilder.Core.Utils; using VRBuilder.Core.Utils.Logging; -using System; namespace VRBuilder.Core { @@ -63,6 +63,9 @@ public void SetName(string name) /// [IgnoreDataMember] public IStep Current { get; set; } + + /// + IEntity IEntitySequenceData.Current => Current; } private class ActivatingProcess : EntityIteratingProcess, IStep> @@ -194,11 +197,11 @@ public IChapter Clone() Dictionary clonedSteps = new Dictionary(); - foreach(IStep step in Data.Steps) + foreach (IStep step in Data.Steps) { IStep clonedStep = step.Clone(); clonedChapter.Data.Steps.Add(clonedStep); - if(Data.FirstStep == step) + if (Data.FirstStep == step) { clonedChapter.Data.FirstStep = clonedStep; } diff --git a/Source/Core/Runtime/Configuration/BaseRuntimeConfiguration.cs b/Source/Core/Runtime/Configuration/BaseRuntimeConfiguration.cs index 9b87ba542..9dca49717 100644 --- a/Source/Core/Runtime/Configuration/BaseRuntimeConfiguration.cs +++ b/Source/Core/Runtime/Configuration/BaseRuntimeConfiguration.cs @@ -91,6 +91,7 @@ public virtual UnityEngine.InputSystem.InputActionAsset CurrentInputActionAsset public IModeHandler Modes { get; protected set; } /// + [Obsolete("This property is obsolete and no longer returns a valid value. Use LocalUser instead.", true)] public abstract ProcessSceneObject User { get; } /// diff --git a/Source/Core/Runtime/Configuration/DefaultRuntimeConfiguration.cs b/Source/Core/Runtime/Configuration/DefaultRuntimeConfiguration.cs index 7dddc0d84..83b2d050f 100644 --- a/Source/Core/Runtime/Configuration/DefaultRuntimeConfiguration.cs +++ b/Source/Core/Runtime/Configuration/DefaultRuntimeConfiguration.cs @@ -2,13 +2,13 @@ // Licensed under the Apache License, Version 2.0 // Modifications copyright (c) 2021-2024 MindPort GmbH -using UnityEngine; using System; using System.Collections.Generic; +using System.Linq; +using UnityEngine; using VRBuilder.Core.Configuration.Modes; -using VRBuilder.Core.SceneObjects; using VRBuilder.Core.Properties; -using System.Linq; +using VRBuilder.Core.SceneObjects; namespace VRBuilder.Core.Configuration { @@ -27,11 +27,20 @@ public class DefaultRuntimeConfiguration : BaseRuntimeConfiguration public DefaultRuntimeConfiguration() { - Modes = new BaseModeHandler(new List {DefaultMode}); + Modes = new BaseModeHandler(new List { DefaultMode }); } /// - public override ProcessSceneObject User => LocalUser; +#pragma warning disable CS0672 // Member overrides obsolete member + public override ProcessSceneObject User +#pragma warning restore CS0672 // Member overrides obsolete member + { + get + { + Debug.LogError("The User property is obsolete and no longer returns a valid value. Use LocalUser instead."); + return null; + } + } /// public override UserSceneObject LocalUser diff --git a/Source/Core/Runtime/Entity.cs b/Source/Core/Runtime/Entity.cs index f7fd7e1d6..4e5a8ceb7 100644 --- a/Source/Core/Runtime/Entity.cs +++ b/Source/Core/Runtime/Entity.cs @@ -90,10 +90,15 @@ public virtual void Configure(IMode mode) /// public void Update() { - LifeCycle.Update(); - if (Data is IEntityCollectionData collectionData) + // IStepData implements IEntitySequenceData despite not being a sequence, + // so we have to manually exclude it. + if (Data is IEntitySequenceData sequenceData && Data is IStepData == false) + { + sequenceData.Current?.Update(); + } + else if (Data is IEntityCollectionData collectionData) { foreach (IEntity child in collectionData.GetChildren().Distinct()) { diff --git a/Source/Core/Runtime/EntityOwners/Sequence/IEntitySequenceData.cs b/Source/Core/Runtime/EntityOwners/Sequence/IEntitySequenceData.cs index 9c17835a9..950499300 100644 --- a/Source/Core/Runtime/EntityOwners/Sequence/IEntitySequenceData.cs +++ b/Source/Core/Runtime/EntityOwners/Sequence/IEntitySequenceData.cs @@ -4,11 +4,19 @@ namespace VRBuilder.Core.EntityOwners { - public interface IEntitySequenceData : IEntityCollectionData where TEntity : IEntity + public interface IEntitySequenceData : IEntityCollectionData, IEntitySequenceData where TEntity : IEntity { /// /// Current entity in the sequence. /// - TEntity Current { get; set; } + new TEntity Current { get; set; } + } + + public interface IEntitySequenceData : IData + { + /// + /// Current entity in the sequence. + /// + IEntity Current { get; } } } diff --git a/Source/Core/Runtime/Process.cs b/Source/Core/Runtime/Process.cs index 05690aed5..cdb103afb 100644 --- a/Source/Core/Runtime/Process.cs +++ b/Source/Core/Runtime/Process.cs @@ -60,6 +60,9 @@ public void SetName(string name) /// public IMode Mode { get; set; } + + /// + IEntity IEntitySequenceData.Current => Current; } /// @@ -103,13 +106,13 @@ protected override bool ShouldDeactivateCurrent() /// protected override bool TryNext(out IChapter entity) { - if(Data.OverrideNext != null && chapters.Contains(Data.OverrideNext)) + if (Data.OverrideNext != null && chapters.Contains(Data.OverrideNext)) { currentChapterIndex = chapters.IndexOf(Data.OverrideNext); Data.OverrideNext = null; } - if(chapters == null || currentChapterIndex >= chapters.Count() || currentChapterIndex < 0) + if (chapters == null || currentChapterIndex >= chapters.Count() || currentChapterIndex < 0) { entity = default; return false; diff --git a/Source/Core/Runtime/ProcessController/DefaultAudioPlayer.cs b/Source/Core/Runtime/ProcessController/DefaultAudioPlayer.cs index 00d7c9e28..f22227237 100644 --- a/Source/Core/Runtime/ProcessController/DefaultAudioPlayer.cs +++ b/Source/Core/Runtime/ProcessController/DefaultAudioPlayer.cs @@ -1,56 +1,58 @@ using UnityEngine; using VRBuilder.Core.Audio; -using VRBuilder.Core.Configuration; -/// -/// Default process audio player. -/// -public class DefaultAudioPlayer : IProcessAudioPlayer +namespace VRBuilder.Core.Configuration { - private AudioSource audioSource; - - public DefaultAudioPlayer() + /// + /// Default process audio player. + /// + public class DefaultAudioPlayer : IProcessAudioPlayer { - GameObject user = RuntimeConfigurator.Configuration.LocalUser.Head.gameObject; - - audioSource = user.GetComponent(); + private AudioSource audioSource; - if (audioSource == null) + public DefaultAudioPlayer() { - audioSource = user.AddComponent(); + GameObject user = RuntimeConfigurator.Configuration.LocalUser.Head.gameObject; + + audioSource = user.GetComponent(); + + if (audioSource == null) + { + audioSource = user.AddComponent(); + } } - } - public DefaultAudioPlayer(AudioSource audioSource) - { - this.audioSource = audioSource; - } + public DefaultAudioPlayer(AudioSource audioSource) + { + this.audioSource = audioSource; + } - /// - public AudioSource FallbackAudioSource => audioSource; + /// + public AudioSource FallbackAudioSource => audioSource; - /// - public bool IsPlaying => audioSource.isPlaying; + /// + public bool IsPlaying => audioSource.isPlaying; - /// - public void PlayAudio(IAudioData audioData, float volume = 1, float pitch = 1) - { - audioSource.clip = audioData.AudioClip; - audioSource.volume = volume; - audioSource.pitch = pitch; - audioSource.Play(); - } + /// + public void PlayAudio(IAudioData audioData, float volume = 1, float pitch = 1) + { + audioSource.clip = audioData.AudioClip; + audioSource.volume = volume; + audioSource.pitch = pitch; + audioSource.Play(); + } - /// - public void Reset() - { - audioSource.clip = null; - } + /// + public void Reset() + { + audioSource.clip = null; + } - /// - public void Stop() - { - audioSource.Stop(); - audioSource.clip = null; + /// + public void Stop() + { + audioSource.Stop(); + audioSource.clip = null; + } } } diff --git a/Source/Core/Runtime/Properties/UserSceneObject.cs b/Source/Core/Runtime/Properties/UserSceneObject.cs index 94023d8a3..661719167 100644 --- a/Source/Core/Runtime/Properties/UserSceneObject.cs +++ b/Source/Core/Runtime/Properties/UserSceneObject.cs @@ -3,14 +3,13 @@ // Modifications copyright (c) 2021-2024 MindPort GmbH using UnityEngine; -using VRBuilder.Core.SceneObjects; namespace VRBuilder.Core.Properties { /// /// Used to identify the user within the scene. /// - public class UserSceneObject : ProcessSceneObject + public class UserSceneObject : MonoBehaviour { [SerializeField] private Transform head, leftHand, rightHand; diff --git a/Source/Core/Runtime/SceneObjects/ProcessSceneObject.cs b/Source/Core/Runtime/SceneObjects/ProcessSceneObject.cs index 1d2f0b2e9..cdefaccd8 100644 --- a/Source/Core/Runtime/SceneObjects/ProcessSceneObject.cs +++ b/Source/Core/Runtime/SceneObjects/ProcessSceneObject.cs @@ -82,6 +82,14 @@ public Guid Guid /// public IEnumerable Guids => guids.Select(bytes => bytes.Guid); + [SerializeField] + [Obsolete("This field will be removed in a future major version.")] + protected List tags = new List(); + + /// + [Obsolete("This property will be removed in a future major version.")] + public IEnumerable Tags => tags.Select(tag => Guid.Parse(tag)); + /// public GameObject GameObject => gameObject; diff --git a/Source/Core/Runtime/SceneObjects/SceneObjectExtensions.cs b/Source/Core/Runtime/SceneObjects/SceneObjectExtensions.cs index e4a276967..36d236a8e 100644 --- a/Source/Core/Runtime/SceneObjects/SceneObjectExtensions.cs +++ b/Source/Core/Runtime/SceneObjects/SceneObjectExtensions.cs @@ -121,7 +121,8 @@ public static void AddProcessPropertyExtensions(this ISceneObjectProperty proper { string assemblyName = concreteExtension.Assembly.FullName; - if (RuntimeConfigurator.Configuration.SceneConfiguration.IsAllowedInAssembly(concreteExtension, assemblyName)) + if (RuntimeConfigurator.Configuration.SceneConfiguration.IsAllowedInAssembly(concreteExtension, assemblyName) && + property.SceneObject.GameObject.GetComponent(concreteExtension) == null) { property.SceneObject.GameObject.AddComponent(concreteExtension); } diff --git a/Source/Core/Runtime/Step.cs b/Source/Core/Runtime/Step.cs index d7da41daa..b2a34292f 100644 --- a/Source/Core/Runtime/Step.cs +++ b/Source/Core/Runtime/Step.cs @@ -91,6 +91,9 @@ public IDictionary> TagsToUnlock [HideInProcessInspector] public IDictionary> GroupsToUnlock { get; set; } = new Dictionary>(); + /// + IEntity IEntitySequenceData.Current => Current; + public EntityData() { } diff --git a/Source/Package-Manager/PackageDependencies/NewtonsoftJSONPackageEnabler.cs b/Source/Package-Manager/PackageDependencies/NewtonsoftJSONPackageEnabler.cs index a6c45cc25..099aafb9b 100644 --- a/Source/Package-Manager/PackageDependencies/NewtonsoftJSONPackageEnabler.cs +++ b/Source/Package-Manager/PackageDependencies/NewtonsoftJSONPackageEnabler.cs @@ -1,10 +1,11 @@ -using VRBuilder.Editor.PackageManager; - -public class NewtonsoftJSONPackageEnabler : Dependency +namespace VRBuilder.Editor.PackageManager { - /// - public override string Package { get; } = "com.unity.nuget.newtonsoft-json"; + public class NewtonsoftJSONPackageEnabler : Dependency + { + /// + public override string Package { get; } = "com.unity.nuget.newtonsoft-json"; - /// - public override int Priority { get; } = 3; -} + /// + public override int Priority { get; } = 3; + } +} \ No newline at end of file diff --git a/Source/TextToSpeech-Component/Editor/ProjectSettings/TextToSpeechSectionProvider.cs b/Source/TextToSpeech-Component/Editor/ProjectSettings/TextToSpeechSectionProvider.cs index 2b27c3b0d..2842bebc2 100644 --- a/Source/TextToSpeech-Component/Editor/ProjectSettings/TextToSpeechSectionProvider.cs +++ b/Source/TextToSpeech-Component/Editor/ProjectSettings/TextToSpeechSectionProvider.cs @@ -1,9 +1,8 @@ using System; -using VRBuilder.TextToSpeech; -using VRBuilder.Editor.UI; -using VRBuilder.Editor.Localization; using UnityEditor; using UnityEngine; +using VRBuilder.Editor.UI; +using VRBuilder.TextToSpeech; namespace VRBuilder.Editor.TextToSpeech.UI.ProjectSettings { @@ -14,29 +13,29 @@ public class TextToSpeechSectionProvider : IProjectSettingsSection { /// public string Title { get; } = "Text to Speech"; - + /// public Type TargetPageProvider { get; } = typeof(LanguageSettingsProvider); - + /// public int Priority { get; } = 0; - + /// public void OnGUI(string searchContext) { GUILayout.Label("Configuration for your Text to Speech provider.", BuilderEditorStyles.ApplyPadding(BuilderEditorStyles.Label, 0)); - + GUILayout.Space(8); - + TextToSpeechConfiguration config = TextToSpeechConfiguration.Instance; UnityEditor.Editor.CreateEditor(config, typeof(VRBuilder.Editor.TextToSpeech.UI.TextToSpeechConfigurationEditor)).OnInspectorGUI(); GUILayout.Space(8); - - BuilderGUILayout.DrawLink("Need Help? Visit our documentation", "https://www.mindport.co/vr-builder-tutorials/text-to-speech-audio", 0); - + + BuilderGUILayout.DrawLink("Need Help? Visit our documentation", "https://www.mindport.co/vr-builder-tutorials/text-to-speech-audio", 0); + } - + ~TextToSpeechSectionProvider() { if (EditorUtility.IsDirty(TextToSpeechConfiguration.Instance)) diff --git a/Source/TextToSpeech-Component/Editor/TextToSpeechBuildPreprocessor.cs b/Source/TextToSpeech-Component/Editor/TextToSpeechBuildPreprocessor.cs index 05fadfa74..ffdf257eb 100644 --- a/Source/TextToSpeech-Component/Editor/TextToSpeechBuildPreprocessor.cs +++ b/Source/TextToSpeech-Component/Editor/TextToSpeechBuildPreprocessor.cs @@ -9,7 +9,7 @@ namespace VRBuilder.Editor.TextToSpeech /// public class TextToSpeechBuildPreprocessor : IPreprocessBuildWithReport { - public int callbackOrder => 0; + public int callbackOrder => 1; /// /// Generates TTS files for all processes before a build. diff --git a/Source/TextToSpeech-Component/Runtime/TextToSpeechAudio.cs b/Source/TextToSpeech-Component/Runtime/TextToSpeechAudio.cs index 09852ec9b..ef2b0a04e 100644 --- a/Source/TextToSpeech-Component/Runtime/TextToSpeechAudio.cs +++ b/Source/TextToSpeech-Component/Runtime/TextToSpeechAudio.cs @@ -1,10 +1,11 @@ using System; -using UnityEngine; using System.Runtime.Serialization; +using UnityEngine; +using UnityEngine.Localization; +using UnityEngine.Localization.Settings; +using VRBuilder.Core.Attributes; using VRBuilder.Core.Audio; using VRBuilder.Core.Configuration; -using UnityEngine.Localization.Settings; -using UnityEngine.Localization; using VRBuilder.Core.Localization; namespace VRBuilder.TextToSpeech.Audio @@ -13,7 +14,7 @@ namespace VRBuilder.TextToSpeech.Audio /// This class retrieves and stores AudioClips generated based in a provided localized text. /// [DataContract(IsReference = true)] - [VRBuilder.Core.Attributes.DisplayName("Play Text to Speech")] + [Core.Attributes.DisplayName("Play Text to Speech")] public class TextToSpeechAudio : TextToSpeechContent, IAudioData { private bool isLoading; @@ -21,6 +22,7 @@ public class TextToSpeechAudio : TextToSpeechContent, IAudioData /// [DataMember] + [UsesSpecificProcessDrawer("MultiLineStringDrawer")] [Core.Attributes.DisplayName("Text/Key")] public override string Text { diff --git a/Source/XR-Interaction-Component/Source/Editor/ProjectSettings/SnapZoneSettingsProvider.cs b/Source/XR-Interaction-Component/Source/Editor/ProjectSettings/SnapZoneSettingsProvider.cs index 7fe805246..c4a5597a7 100644 --- a/Source/XR-Interaction-Component/Source/Editor/ProjectSettings/SnapZoneSettingsProvider.cs +++ b/Source/XR-Interaction-Component/Source/Editor/ProjectSettings/SnapZoneSettingsProvider.cs @@ -1,49 +1,51 @@ -using VRBuilder.XRInteraction; -using VRBuilder.Editor.UI; -using VRBuilder.Editor.XRInteraction; -using UnityEditor; +using UnityEditor; using UnityEngine; using UnityEngine.UIElements; +using VRBuilder.Editor.XRInteraction; +using VRBuilder.XRInteraction; -internal class SnapZoneSettingsProvider : SettingsProvider +namespace VRBuilder.Editor.UI { - const string Path = "Project/VR Builder/Snap Zones"; + internal class SnapZoneSettingsProvider : SettingsProvider + { + const string Path = "Project/VR Builder/Snap Zones"; - private Editor editor; - - public SnapZoneSettingsProvider() : base(Path, SettingsScope.Project) {} + private UnityEditor.Editor editor; - public override void OnGUI(string searchContext) - { - EditorGUILayout.Space(); - GUIStyle labelStyle = BuilderEditorStyles.ApplyPadding(BuilderEditorStyles.Paragraph, 0); - GUILayout.Label("These settings help you to configure Snap Zones within your scenes. You can define colors and other values that will be set to Snap Zones created by clicking the 'Create Snap Zone' button of a Snappable Property.", labelStyle); - EditorGUILayout.Space(); - - editor.OnInspectorGUI(); - - EditorGUILayout.Space(20f); - - if (GUILayout.Button("Apply settings in current scene")) + public SnapZoneSettingsProvider() : base(Path, SettingsScope.Project) { } + + public override void OnGUI(string searchContext) { - SnapZone[] snapZones = Resources.FindObjectsOfTypeAll(); - - foreach (SnapZone snapZone in snapZones) + EditorGUILayout.Space(); + GUIStyle labelStyle = BuilderEditorStyles.ApplyPadding(BuilderEditorStyles.Paragraph, 0); + GUILayout.Label("These settings help you to configure Snap Zones within your scenes. You can define colors and other values that will be set to Snap Zones created by clicking the 'Create Snap Zone' button of a Snappable Property.", labelStyle); + EditorGUILayout.Space(); + + editor.OnInspectorGUI(); + + EditorGUILayout.Space(20f); + + if (GUILayout.Button("Apply settings in current scene")) { - SnapZoneSettings.Instance.ApplySettingsToSnapZone(snapZone); + SnapZone[] snapZones = Resources.FindObjectsOfTypeAll(); + + foreach (SnapZone snapZone in snapZones) + { + SnapZoneSettings.Instance.ApplySettingsToSnapZone(snapZone); + } } } - } - public override void OnActivate(string searchContext, VisualElement rootElement) - { - editor = Editor.CreateEditor(SnapZoneSettings.Instance); - } + public override void OnActivate(string searchContext, VisualElement rootElement) + { + editor = UnityEditor.Editor.CreateEditor(SnapZoneSettings.Instance); + } - [SettingsProvider] - public static SettingsProvider Provider() - { - SettingsProvider provider = new SnapZoneSettingsProvider(); - return provider; + [SettingsProvider] + public static SettingsProvider Provider() + { + SettingsProvider provider = new SnapZoneSettingsProvider(); + return provider; + } } -} +} \ No newline at end of file diff --git a/Source/XR-Interaction-Component/Source/Runtime/Interaction/Action-based/ActionBasedControllerManager.cs b/Source/XR-Interaction-Component/Source/Runtime/Interaction/Action-based/ActionBasedControllerManager.cs index 8734a0765..159e11050 100644 --- a/Source/XR-Interaction-Component/Source/Runtime/Interaction/Action-based/ActionBasedControllerManager.cs +++ b/Source/XR-Interaction-Component/Source/Runtime/Interaction/Action-based/ActionBasedControllerManager.cs @@ -358,6 +358,32 @@ protected void OnDisable() uiState.OnExit.RemoveListener(OnExitUIState); } + /// + /// Forces a transition to the desired state, bypassing the provided input actions. + /// The controller will be locked in the specified state until manually unlocked. + /// + /// ID of the state to switch to. + public void ForceLockControllerState(StateID stateID) + { + ForceStateTransition(stateID); + + DisableAction(teleportModeActivate); + DisableAction(teleportModeCancel); + DisableAction(UIModeActivate); + } + + /// + /// Transitions to the default state and allows regular state switching via input actions. + /// + public void UnlockControllerState() + { + ForceStateTransition(StateID.Select); + + EnableAction(teleportModeActivate); + EnableAction(teleportModeCancel); + EnableAction(UIModeActivate); + } + protected void Start() { // Add states to the list @@ -397,6 +423,22 @@ private void TransitionState(ControllerState fromState, ControllerState toState) } } + private void ForceStateTransition(StateID stateID) + { + ControllerState currentState = defaultStates.Where(state => state.Enabled).FirstOrDefault(); + ControllerState targetState = defaultStates.Where(state => state.ID == stateID).FirstOrDefault(); + + if (targetState == null) + { + throw new ArgumentNullException("Attempted to force transition to null state"); + } + + if (currentState != targetState) + { + TransitionState(currentState, targetState); + } + } + private void FindBaseControllerComponents() { if (baseController == null) @@ -677,7 +719,7 @@ private void OnUpdateSelectState() { return; } - + // Transition from Select state to Teleport state when the user triggers the "Teleport Mode Activate" action but not the "Cancel Teleport" action InputAction teleportModeAction = GetInputAction(teleportModeActivate); InputAction cancelTeleportModeAction = GetInputAction(teleportModeCancel); @@ -766,7 +808,7 @@ private void DisableAction(InputActionReference actionReference) action.Disable(); } } - + private bool IsInteractorInteracting() { if (baseXRInteractor == null) diff --git a/Tests/TestUtils/Builders/BasicProcessSteps.cs b/Tests/TestUtils/Builders/BasicProcessSteps.cs index fc576ed88..9bf39bab4 100644 --- a/Tests/TestUtils/Builders/BasicProcessSteps.cs +++ b/Tests/TestUtils/Builders/BasicProcessSteps.cs @@ -22,30 +22,6 @@ private static ISceneObject GetFromRegistry(string name) return RuntimeConfigurator.Configuration.SceneObjectRegistry.GetObjects(Guid.Parse(name)).FirstOrDefault(); } - /// - /// Get builder for a step where the user has to enter collider. - /// - /// The name of the step. - /// Target collider for the user to enter. - /// How long the user should stay inside the collider to continue. - /// Configured builder. - public static BasicStepBuilder UserInArea(string name, string targetAreaCollider, float triggerDelay = 0f) - { - return UserInArea(name, GetFromRegistry(targetAreaCollider), triggerDelay); - } - - /// - /// Get builder for a step where the user has to enter collider. - /// - /// The name of the step. - /// Target collider for the user to enter. - /// How long the user should stay inside the collider to continue. - /// Configured builder. - public static BasicStepBuilder UserInArea(string name, ISceneObject targetAreaCollider, float triggerDelay = 0f) - { - return PutIntoCollider(name, targetAreaCollider, triggerDelay, RuntimeConfigurator.Configuration.User); - } - /// /// Get builder for a step during which user has to put given objects into given collider. /// diff --git a/package.json b/package.json index 3f93a6332..d6fb4901d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "displayName": "VR Builder", "name": "co.mindport.vrbuilder.core", - "version": "4.0.0", + "version": "4.1.0", "unity": "2021.1", "description": "VR Builder core functionality.", "keywords": [