diff --git a/Assets/Resources/Prefabs/Players/XRRig.prefab b/Assets/Resources/Prefabs/Players/XRRig.prefab
index d82cf3b294..957f67085f 100644
--- a/Assets/Resources/Prefabs/Players/XRRig.prefab
+++ b/Assets/Resources/Prefabs/Players/XRRig.prefab
@@ -3324,7 +3324,7 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
- radialMenu: {fileID: -5982496924579745919, guid: c348712bda248c246b8c49b3db54643f,
+ RadialMenuActionRef: {fileID: -5982496924579745919, guid: c348712bda248c246b8c49b3db54643f,
type: 3}
--- !u!1 &7806924667908141112
GameObject:
@@ -5196,7 +5196,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: df5e8c7d8b96d6944aaafef73a15f5b0, type: 3}
m_Name:
m_EditorClassIdentifier:
- m_RayInteractor: {fileID: 645861538944586177}
inputAction: {fileID: -1379689384741821685, guid: c348712bda248c246b8c49b3db54643f,
type: 3}
undo: {fileID: -989603093121905207, guid: c348712bda248c246b8c49b3db54643f, type: 3}
diff --git a/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs b/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs
index 846173d9df..1f522ff174 100644
--- a/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs
+++ b/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs
@@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
+using SEE.XR;
namespace SEE.Controls.Actions
{
@@ -116,7 +117,7 @@ public override bool Update()
{
if (SceneSettings.InputType == PlayerInputType.VRPlayer)
{
- if (XRSEEActions.Selected
+ if (XRSEEActions.Selected
&& XRSEEActions.RayInteractor.TryGetCurrent3DRaycastHit(out RaycastHit hit))
{
// find the edge representing the divergence that should be solved.
diff --git a/Assets/SEE/Controls/Actions/AddEdgeAction.cs b/Assets/SEE/Controls/Actions/AddEdgeAction.cs
index fd8a0f42aa..48ee5a6596 100644
--- a/Assets/SEE/Controls/Actions/AddEdgeAction.cs
+++ b/Assets/SEE/Controls/Actions/AddEdgeAction.cs
@@ -10,6 +10,7 @@
using SEE.Audio;
using SEE.DataModel.DG;
using SEE.Game.SceneManipulation;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/AddNodeAction.cs b/Assets/SEE/Controls/Actions/AddNodeAction.cs
index 826a4f340d..3265bf9b74 100644
--- a/Assets/SEE/Controls/Actions/AddNodeAction.cs
+++ b/Assets/SEE/Controls/Actions/AddNodeAction.cs
@@ -9,6 +9,7 @@
using System;
using SEE.UI.PropertyDialog;
using SEE.DataModel.DG;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/ContextMenuAction.cs b/Assets/SEE/Controls/Actions/ContextMenuAction.cs
index 48c8c6c462..fd5f318e2d 100644
--- a/Assets/SEE/Controls/Actions/ContextMenuAction.cs
+++ b/Assets/SEE/Controls/Actions/ContextMenuAction.cs
@@ -17,6 +17,7 @@
using SEE.GO.Menu;
using SEE.UI.Menu.Drawable;
using SEE.UI.Window.PropertyWindow;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/DeleteAction.cs b/Assets/SEE/Controls/Actions/DeleteAction.cs
index 30c953d6e8..4f0b192c7b 100644
--- a/Assets/SEE/Controls/Actions/DeleteAction.cs
+++ b/Assets/SEE/Controls/Actions/DeleteAction.cs
@@ -8,6 +8,7 @@
using SEE.Audio;
using SEE.Game.SceneManipulation;
using SEE.Utils.History;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/HideAction.cs b/Assets/SEE/Controls/Actions/HideAction.cs
index cce5ac7909..55ff682297 100644
--- a/Assets/SEE/Controls/Actions/HideAction.cs
+++ b/Assets/SEE/Controls/Actions/HideAction.cs
@@ -7,6 +7,7 @@
using UnityEngine;
using UnityEngine.Assertions;
using SEE.Utils.History;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/MoveAction.cs b/Assets/SEE/Controls/Actions/MoveAction.cs
index d9befd1768..64b24523bd 100644
--- a/Assets/SEE/Controls/Actions/MoveAction.cs
+++ b/Assets/SEE/Controls/Actions/MoveAction.cs
@@ -15,6 +15,7 @@
using SEE.Utils.History;
using UnityEngine;
using UnityEngine.EventSystems;
+using SEE.XR;
namespace SEE.Controls.Actions
diff --git a/Assets/SEE/Controls/Actions/NodeManipulationAction.cs b/Assets/SEE/Controls/Actions/NodeManipulationAction.cs
index 309f602b1a..c63b6425b0 100644
--- a/Assets/SEE/Controls/Actions/NodeManipulationAction.cs
+++ b/Assets/SEE/Controls/Actions/NodeManipulationAction.cs
@@ -9,6 +9,7 @@
using SEE.Utils.History;
using System.Collections.Generic;
using UnityEngine;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/SelectAction.cs b/Assets/SEE/Controls/Actions/SelectAction.cs
index b0606a0f9b..11ec58733a 100644
--- a/Assets/SEE/Controls/Actions/SelectAction.cs
+++ b/Assets/SEE/Controls/Actions/SelectAction.cs
@@ -4,6 +4,7 @@
using UnityEngine;
using SEE.Audio;
using SEE.GO;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/ShowCodeAction.cs b/Assets/SEE/Controls/Actions/ShowCodeAction.cs
index 78c294e06f..463e533975 100644
--- a/Assets/SEE/Controls/Actions/ShowCodeAction.cs
+++ b/Assets/SEE/Controls/Actions/ShowCodeAction.cs
@@ -14,6 +14,7 @@
using SEE.Utils.History;
using SEE.Game.City;
using SEE.VCS;
+using SEE.XR;
using GraphElementRef = SEE.GO.GraphElementRef;
using Range = SEE.DataModel.DG.Range;
diff --git a/Assets/SEE/Controls/Actions/ShowLabel.cs b/Assets/SEE/Controls/Actions/ShowLabel.cs
index a24c896cd8..2c2b49b77d 100644
--- a/Assets/SEE/Controls/Actions/ShowLabel.cs
+++ b/Assets/SEE/Controls/Actions/ShowLabel.cs
@@ -6,6 +6,7 @@
using SEE.Game.Operator;
using SEE.GO;
using UnityEngine;
+using SEE.XR;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/SEEInput.cs b/Assets/SEE/Controls/SEEInput.cs
index d48ca989d5..4949199b23 100644
--- a/Assets/SEE/Controls/SEEInput.cs
+++ b/Assets/SEE/Controls/SEEInput.cs
@@ -2,6 +2,7 @@
using SEE.Utils;
using UnityEngine;
using SEE.GO;
+using SEE.XR;
namespace SEE.Controls
{
diff --git a/Assets/SEE/GameObjects/Menu/PlayerMenu.cs b/Assets/SEE/GameObjects/Menu/PlayerMenu.cs
index f4c338cb43..4813ba0500 100644
--- a/Assets/SEE/GameObjects/Menu/PlayerMenu.cs
+++ b/Assets/SEE/GameObjects/Menu/PlayerMenu.cs
@@ -8,6 +8,7 @@
using SEE.UI.StateIndicator;
using SEE.Utils;
using UnityEngine;
+using SEE.XR;
namespace SEE.GO.Menu
{
diff --git a/Assets/SEE/UI/PopupMenu/PopupMenu.cs b/Assets/SEE/UI/PopupMenu/PopupMenu.cs
index f5da016dcc..0fb9636d27 100644
--- a/Assets/SEE/UI/PopupMenu/PopupMenu.cs
+++ b/Assets/SEE/UI/PopupMenu/PopupMenu.cs
@@ -10,6 +10,7 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
+using SEE.XR;
namespace SEE.UI.PopupMenu
{
diff --git a/Assets/SEE/UI/Window/PropertyWindow/PropertyWindowContextMenu.cs b/Assets/SEE/UI/Window/PropertyWindow/PropertyWindowContextMenu.cs
index 34e49db663..7c17499681 100644
--- a/Assets/SEE/UI/Window/PropertyWindow/PropertyWindowContextMenu.cs
+++ b/Assets/SEE/UI/Window/PropertyWindow/PropertyWindowContextMenu.cs
@@ -10,6 +10,7 @@
using TMPro;
using UnityEngine;
using UnityEngine.Events;
+using SEE.XR;
namespace SEE.UI.Window.PropertyWindow
{
diff --git a/Assets/SEE/UI/Window/TreeWindow/DesktopTreeWindow.cs b/Assets/SEE/UI/Window/TreeWindow/DesktopTreeWindow.cs
index 1a7a17f345..3bb2287793 100644
--- a/Assets/SEE/UI/Window/TreeWindow/DesktopTreeWindow.cs
+++ b/Assets/SEE/UI/Window/TreeWindow/DesktopTreeWindow.cs
@@ -16,6 +16,7 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
+using SEE.XR;
using ArgumentException = System.ArgumentException;
using Edge = SEE.DataModel.DG.Edge;
using Node = SEE.DataModel.DG.Node;
diff --git a/Assets/SEE/Utils/Raycasting.cs b/Assets/SEE/Utils/Raycasting.cs
index 8f57f8a24b..45362bf88b 100644
--- a/Assets/SEE/Utils/Raycasting.cs
+++ b/Assets/SEE/Utils/Raycasting.cs
@@ -7,6 +7,7 @@
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.UI;
+using SEE.XR;
namespace SEE.Utils
{
diff --git a/Assets/SEE/XR/KeyboardInputHandler.cs b/Assets/SEE/XR/KeyboardInputHandler.cs
index b44b526a8d..fd71ee5660 100644
--- a/Assets/SEE/XR/KeyboardInputHandler.cs
+++ b/Assets/SEE/XR/KeyboardInputHandler.cs
@@ -4,35 +4,38 @@
using UnityEngine;
using UnityEngine.EventSystems;
-///
-/// This class changes the inputfield for the VR-Keyboard and
-/// also activates the keyboard.
-/// This script is based on this tutorial: https://www.youtube.com/watch?v=vTonHBr4t4g
-///
-public class KeyboardInputHandler : MonoBehaviour, IPointerClickHandler
+namespace SEE.XR
{
///
- /// The reference to the keyboard GameObject.
+ /// This class changes the inputfield for the VR-Keyboard and
+ /// also activates the keyboard.
+ /// This script is based on this tutorial: https://www.youtube.com/watch?v=vTonHBr4t4g
///
- private GameObject keyboardGameObject;
-
- private void Start()
+ public class KeyboardInputHandler : MonoBehaviour, IPointerClickHandler
{
- // Cache the reference to the keyboard GameObject
- keyboardGameObject = KeyboardManager.instance.gameObject.transform.Find("Keyboard").gameObject;
- }
+ ///
+ /// The reference to the keyboard GameObject.
+ ///
+ private GameObject keyboardGameObject;
- ///
- /// This method gets called when the user clicks the input field.
- /// If the user is in VR, the keyboard gets activated.
- ///
- /// Event data associated with the event when the user clicks on the inputfield.
- public void OnPointerClick(PointerEventData eventdata)
- {
- if (SceneSettings.InputType == PlayerInputType.VRPlayer)
+ private void Start()
+ {
+ // Cache the reference to the keyboard GameObject
+ keyboardGameObject = KeyboardManager.instance.gameObject.transform.Find("Keyboard").gameObject;
+ }
+
+ ///
+ /// This method gets called when the user clicks the input field.
+ /// If the user is in VR, the keyboard gets activated.
+ ///
+ /// Event data associated with the event when the user clicks on the inputfield.
+ public void OnPointerClick(PointerEventData eventdata)
{
- KeyboardManager.instance.inputField = GetComponent();
- keyboardGameObject.SetActive(true);
+ if (SceneSettings.InputType == PlayerInputType.VRPlayer)
+ {
+ KeyboardManager.instance.inputField = GetComponent();
+ keyboardGameObject.SetActive(true);
+ }
}
}
}
diff --git a/Assets/SEE/XR/KeyboardKey.cs b/Assets/SEE/XR/KeyboardKey.cs
index 89b242eb88..5684eb8311 100644
--- a/Assets/SEE/XR/KeyboardKey.cs
+++ b/Assets/SEE/XR/KeyboardKey.cs
@@ -2,106 +2,109 @@
using UnityEngine;
using UnityEngine.UI;
-///
-/// This class handles a single keyboard key.
-/// This script is based on this tutorial: https://www.youtube.com/watch?v=vTonHBr4t4g
-///
-public class KeyboardKey : MonoBehaviour
+namespace SEE.XR
{
///
- /// The character of the key.
+ /// This class handles a single keyboard key.
+ /// This script is based on this tutorial: https://www.youtube.com/watch?v=vTonHBr4t4g
///
- public string character;
-
- ///
- /// The shifted character.
- ///
- public string shiftCharacter;
-
- ///
- /// Is true when the key is shifted.
- ///
- private bool isShifted = false;
+ public class KeyboardKey : MonoBehaviour
+ {
+ ///
+ /// The character of the key.
+ ///
+ public string character;
- ///
- /// The actual keyboard key.
- ///
- private Button key;
+ ///
+ /// The shifted character.
+ ///
+ public string shiftCharacter;
- ///
- /// The label of the keyboard key.
- ///
- public TextMeshProUGUI keyLabel;
+ ///
+ /// Is true when the key is shifted.
+ ///
+ private bool isShifted = false;
- private void Start()
- {
- KeyboardManager.instance.shiftButton.onClick.AddListener(HandleShift);
- key = GetComponent();
- key.onClick.AddListener(TypeKey);
- character = keyLabel.text;
- shiftCharacter = keyLabel.text.ToUpper();
+ ///
+ /// The actual keyboard key.
+ ///
+ private Button key;
- string numbers = "1234567890";
+ ///
+ /// The label of the keyboard key.
+ ///
+ public TextMeshProUGUI keyLabel;
- if (numbers.Contains(keyLabel.text))
+ private void Start()
{
- shiftCharacter = GetShiftCharacter();
- }
- }
+ KeyboardManager.instance.shiftButton.onClick.AddListener(HandleShift);
+ key = GetComponent();
+ key.onClick.AddListener(TypeKey);
+ character = keyLabel.text;
+ shiftCharacter = keyLabel.text.ToUpper();
- ///
- /// This method returns the shifted equivalent to
- /// each number on the keyboard.
- ///
- /// The shifted equivalent to each number.
- private string GetShiftCharacter()
- {
- return keyLabel.text switch
- {
- "1" => "!",
- "2" => ".",
- "3" => "#",
- "4" => "?",
- "5" => "%",
- "6" => "&",
- "7" => "+",
- "8" => "(",
- "9" => ")",
- "0" => "=",
- _ => string.Empty
- };
- }
-
- ///
- /// This method handles the shifting of the
- /// alphabetical characters.
- ///
- private void HandleShift()
- {
- isShifted = !isShifted;
+ string numbers = "1234567890";
- if (isShifted)
- {
- keyLabel.text = shiftCharacter;
+ if (numbers.Contains(keyLabel.text))
+ {
+ shiftCharacter = GetShiftCharacter();
+ }
}
- else
+
+ ///
+ /// This method returns the shifted equivalent to
+ /// each number on the keyboard.
+ ///
+ /// The shifted equivalent to each number.
+ private string GetShiftCharacter()
{
- keyLabel.text = character;
+ return keyLabel.text switch
+ {
+ "1" => "!",
+ "2" => ".",
+ "3" => "#",
+ "4" => "?",
+ "5" => "%",
+ "6" => "&",
+ "7" => "+",
+ "8" => "(",
+ "9" => ")",
+ "0" => "=",
+ _ => string.Empty
+ };
}
- }
- ///
- /// This method transfers the character to the inputfield.
- ///
- private void TypeKey()
- {
- if (isShifted)
+ ///
+ /// This method handles the shifting of the
+ /// alphabetical characters.
+ ///
+ private void HandleShift()
{
- KeyboardManager.instance.inputField.text += shiftCharacter;
+ isShifted = !isShifted;
+
+ if (isShifted)
+ {
+ keyLabel.text = shiftCharacter;
+ }
+ else
+ {
+ keyLabel.text = character;
+ }
}
- else
+
+ ///
+ /// This method transfers the character to the inputfield.
+ ///
+ private void TypeKey()
{
- KeyboardManager.instance.inputField.text += character;
+ if (isShifted)
+ {
+ KeyboardManager.instance.inputField.text += shiftCharacter;
+ }
+ else
+ {
+ KeyboardManager.instance.inputField.text += character;
+ }
}
}
}
diff --git a/Assets/SEE/XR/KeyboardManager.cs b/Assets/SEE/XR/KeyboardManager.cs
index 62671b85fd..adb3893ae2 100644
--- a/Assets/SEE/XR/KeyboardManager.cs
+++ b/Assets/SEE/XR/KeyboardManager.cs
@@ -2,109 +2,112 @@
using UnityEngine;
using UnityEngine.UI;
-///
-/// This class manages the input for all buttons on the keyboard.
-/// This script is based on this tutorial: https://www.youtube.com/watch?v=vTonHBr4t4g
-///
-public class KeyboardManager : MonoBehaviour
+namespace SEE.XR
{
///
- /// The instance of the keyboardmanager.
+ /// This class manages the input for all buttons on the keyboard.
+ /// This script is based on this tutorial: https://www.youtube.com/watch?v=vTonHBr4t4g
///
- public static KeyboardManager instance;
+ public class KeyboardManager : MonoBehaviour
+ {
+ ///
+ /// The instance of the keyboardmanager.
+ ///
+ public static KeyboardManager instance;
- ///
- /// The shiftbutton, which shifts a character.
- ///
- public Button shiftButton;
+ ///
+ /// The shiftbutton, which shifts a character.
+ ///
+ public Button shiftButton;
- ///
- /// The deletebutton, which deletes a character.
- ///
- public Button deleteButton;
+ ///
+ /// The deletebutton, which deletes a character.
+ ///
+ public Button deleteButton;
- ///
- /// The spacebuttom, which adds a space.
- ///
- public Button spaceButton;
+ ///
+ /// The spacebuttom, which adds a space.
+ ///
+ public Button spaceButton;
- ///
- /// The enterbutton, which finalizes the input.
- ///
- public Button enterButton;
+ ///
+ /// The enterbutton, which finalizes the input.
+ ///
+ public Button enterButton;
- ///
- /// The inputfield, which is accessed by the keyboard.
- ///
- public TMP_InputField inputField;
+ ///
+ /// The inputfield, which is accessed by the keyboard.
+ ///
+ public TMP_InputField inputField;
- ///
- /// This image is used to tell the user that the shiftbutton is active.
- ///
- private Image shiftButtonImage;
+ ///
+ /// This image is used to tell the user that the shiftbutton is active.
+ ///
+ private Image shiftButtonImage;
- ///
- /// Is true when the shiftbutton is active.
- ///
- private bool isShifted = false;
+ ///
+ /// Is true when the shiftbutton is active.
+ ///
+ private bool isShifted = false;
- private void Awake()
- {
- if (instance == null)
+ private void Awake()
{
- instance = this;
+ if (instance == null)
+ {
+ instance = this;
+ }
+ spaceButton.onClick.AddListener(Space);
+ deleteButton.onClick.AddListener(Delete);
+ shiftButton.onClick.AddListener(Shifted);
+ enterButton.onClick.AddListener(Enter);
+ shiftButtonImage = shiftButton.gameObject.GetComponent();
}
- spaceButton.onClick.AddListener(Space);
- deleteButton.onClick.AddListener(Delete);
- shiftButton.onClick.AddListener(Shifted);
- enterButton.onClick.AddListener(Enter);
- shiftButtonImage = shiftButton.gameObject.GetComponent();
- }
-
- ///
- /// This method adds a whitespace character.
- ///
- private void Space()
- {
- inputField.text += " ";
- }
-
- ///
- /// This method performs the enter-action on the keyboard.
- ///
- private void Enter()
- {
- inputField.onSubmit.Invoke(inputField.text);
- gameObject.transform.Find("Keyboard").gameObject.SetActive(false);
- }
- ///
- /// This method performs the delete-action on the keyboard.
- ///
- private void Delete()
- {
- int length = inputField.text.Length;
- if (length != 0)
+ ///
+ /// This method adds a whitespace character.
+ ///
+ private void Space()
{
- length = length - 1;
- inputField.text = inputField.text.Substring(0, length);
+ inputField.text += " ";
}
- }
- ///
- /// This method performs the shift-action on the keyboard.
- ///
- private void Shifted()
- {
- isShifted = !isShifted;
+ ///
+ /// This method performs the enter-action on the keyboard.
+ ///
+ private void Enter()
+ {
+ inputField.onSubmit.Invoke(inputField.text);
+ gameObject.transform.Find("Keyboard").gameObject.SetActive(false);
+ }
- if (isShifted)
+ ///
+ /// This method performs the delete-action on the keyboard.
+ ///
+ private void Delete()
{
- shiftButtonImage.color = Color.yellow;
+ int length = inputField.text.Length;
+ if (length != 0)
+ {
+ length = length - 1;
+ inputField.text = inputField.text.Substring(0, length);
+ }
}
- else
+
+ ///
+ /// This method performs the shift-action on the keyboard.
+ ///
+ private void Shifted()
{
- shiftButtonImage.color = Color.white;
+ isShifted = !isShifted;
+
+ if (isShifted)
+ {
+ shiftButtonImage.color = Color.yellow;
+ }
+ else
+ {
+ shiftButtonImage.color = Color.white;
+ }
}
}
}
diff --git a/Assets/SEE/XR/RadialSelection.cs b/Assets/SEE/XR/RadialSelection.cs
index 5863fec673..20c49c5c5f 100644
--- a/Assets/SEE/XR/RadialSelection.cs
+++ b/Assets/SEE/XR/RadialSelection.cs
@@ -7,447 +7,449 @@
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.UI;
-using UnityEngine.XR.Interaction.Toolkit;
using SEE.Utils;
-///
-/// This component is used to open a radial menu in VR.
-/// This script is based on this tutorial: https://www.youtube.com/watch?v=n-xPN1v3dvA
-///
-public class RadialSelection : MonoBehaviour
+namespace SEE.XR
{
///
- /// The number of radial-parts.
+ /// This component is used to open a radial menu in VR.
+ /// This script is based on this tutorial: https://www.youtube.com/watch?v=n-xPN1v3dvA
///
- private int numberOfRadialParts = 0;
-
- ///
- /// The prefab for the single radial-parts.
- ///
- public GameObject radialPartPrefab;
-
- ///
- /// The canvas on which the radial should be shown.
- ///
- public Transform radialPartCanvas;
-
- ///
- /// The angle between the radial-parts.
- ///
- public float angleBetweenPart = 10;
-
- ///
- /// The radial-parts which got spawned.
- ///
- private List spawnedParts = new();
-
- ///
- /// The transform of the controller.
- ///
- public Transform handTransform;
-
- ///
- /// The currently selected radial-part.
- ///
- private int currentSelectedRadialPart = -1;
-
- ///
- /// The selected radial-part.
- ///
- public UnityEvent OnPartSelected;
-
- ///
- /// The button that triggers the radial-menu.
- ///
- public InputActionReference RadialMenuActionRef;
-
- ///
- /// All actions, which are currently available.
- ///
- List actions = new();
-
- ///
- /// Alle submenus and their entries.
- ///
- List<(string, List)> subMenus = new();
-
- ///
- /// All entry of a submenu.
- /// This list is used, to swap between the main-menu and sub-menus.
- /// The main menu contains all "main-actions" and the sub-menus more
- /// specific sub-actions. We safe the main-actions here for the case,
- /// that the user wants to go back to the main-menu.
- ///
- List menuEntries = new();
-
- ///
- /// This is used for the rotate-action, because in this case we
- /// have a dial, which is getting spawned, and should be despawned, when the action changes.
- ///
- GameObject actionObject;
-
- ///
- /// The position of the submenu.
- /// It should be the same, as the position from the mainmenu.
- ///
- Vector3? subMenuPosition;
-
- ///
- /// The rotation of the submenu.
- /// It should be the same, as the rotation from the mainmenu.
- ///
- Quaternion? subMenuRotation;
-
- ///
- /// The selected HideMode.
- /// The hide-action is a special action, because it has sub-actions, which we need to access.
- ///
- public static HideModeSelector HideMode { get; set; }
-
- private void Awake()
+ public class RadialSelection : MonoBehaviour
{
- RadialMenuActionRef.action.performed += RadialMenu;
- ActionStateTypes.AllRootTypes.PreorderTraverse(Visit);
- bool Visit(AbstractActionStateType child, AbstractActionStateType parent)
+ ///
+ /// The number of radial-parts.
+ ///
+ private int numberOfRadialParts = 0;
+
+ ///
+ /// The prefab for the single radial-parts.
+ ///
+ public GameObject radialPartPrefab;
+
+ ///
+ /// The canvas on which the radial should be shown.
+ ///
+ public Transform radialPartCanvas;
+
+ ///
+ /// The angle between the radial-parts.
+ ///
+ public float angleBetweenPart = 10;
+
+ ///
+ /// The radial-parts which got spawned.
+ ///
+ private List spawnedParts = new();
+
+ ///
+ /// The transform of the controller.
+ ///
+ public Transform handTransform;
+
+ ///
+ /// The currently selected radial-part.
+ ///
+ private int currentSelectedRadialPart = -1;
+
+ ///
+ /// The selected radial-part.
+ ///
+ public UnityEvent OnPartSelected;
+
+ ///
+ /// The button that triggers the radial-menu.
+ ///
+ public InputActionReference RadialMenuActionRef;
+
+ ///
+ /// All actions, which are currently available.
+ ///
+ List actions = new();
+
+ ///
+ /// Alle submenus and their entries.
+ ///
+ List<(string, List)> subMenus = new();
+
+ ///
+ /// All entry of a submenu.
+ /// This list is used, to swap between the main-menu and sub-menus.
+ /// The main menu contains all "main-actions" and the sub-menus more
+ /// specific sub-actions. We safe the main-actions here for the case,
+ /// that the user wants to go back to the main-menu.
+ ///
+ List menuEntries = new();
+
+ ///
+ /// This is used for the rotate-action, because in this case we
+ /// have a dial, which is getting spawned, and should be despawned, when the action changes.
+ ///
+ GameObject actionObject;
+
+ ///
+ /// The position of the submenu.
+ /// It should be the same, as the position from the mainmenu.
+ ///
+ Vector3? subMenuPosition;
+
+ ///
+ /// The rotation of the submenu.
+ /// It should be the same, as the rotation from the mainmenu.
+ ///
+ Quaternion? subMenuRotation;
+
+ ///
+ /// The selected HideMode.
+ /// The hide-action is a special action, because it has sub-actions, which we need to access.
+ ///
+ public static HideModeSelector HideMode { get; set; }
+
+ private void Awake()
{
- string name;
-
- if (child is ActionStateType actionStateType)
+ RadialMenuActionRef.action.performed += RadialMenu;
+ ActionStateTypes.AllRootTypes.PreorderTraverse(Visit);
+ bool Visit(AbstractActionStateType child, AbstractActionStateType parent)
{
- name = child.Name;
- }
- else if (child is ActionStateTypeGroup actionStateTypeGroup)
- {
- name = child.Name;
- }
- else
- {
- throw new System.NotImplementedException($"{nameof(child)} not handled.");
- }
+ string name;
- // If child is not a root (i.e., has a parent), we will add the entry to
- // the InnerEntries of the menu corresponding to the parent.
- // We know that such a menu must exist, because we are doing a
- // preorder traversal.
- if (parent != null)
- {
- if (parent is ActionStateTypeGroup parentGroup)
+ if (child is ActionStateType actionStateType)
{
- var search = subMenus.FirstOrDefault(item => item.Item1 == parent.Name);
- for (int i = 0; i < subMenus.Count; i++)
+ name = child.Name;
+ }
+ else if (child is ActionStateTypeGroup actionStateTypeGroup)
+ {
+ name = child.Name;
+ }
+ else
+ {
+ throw new System.NotImplementedException($"{nameof(child)} not handled.");
+ }
+
+ // If child is not a root (i.e., has a parent), we will add the entry to
+ // the InnerEntries of the menu corresponding to the parent.
+ // We know that such a menu must exist, because we are doing a
+ // preorder traversal.
+ if (parent != null)
+ {
+ if (parent is ActionStateTypeGroup parentGroup)
{
- if (subMenus[i].Item1 == parent.Name && subMenus[i].Item2 == null)
- {
- subMenus[i] = (subMenus[i].Item1, new());
- subMenus[i].Item2.Add(name);
- }
- else if (subMenus[i].Item1 == parent.Name && subMenus[i].Item2 != null)
+ var search = subMenus.FirstOrDefault(item => item.Item1 == parent.Name);
+ for (int i = 0; i < subMenus.Count; i++)
{
- subMenus[i].Item2.Add(name);
+ if (subMenus[i].Item1 == parent.Name && subMenus[i].Item2 == null)
+ {
+ subMenus[i] = (subMenus[i].Item1, new());
+ subMenus[i].Item2.Add(name);
+ }
+ else if (subMenus[i].Item1 == parent.Name && subMenus[i].Item2 != null)
+ {
+ subMenus[i].Item2.Add(name);
+ }
}
}
+ else
+ {
+ throw new System.InvalidCastException($"Parent is expected to be an {nameof(ActionStateTypeGroup)}.");
+ }
}
else
{
- throw new System.InvalidCastException($"Parent is expected to be an {nameof(ActionStateTypeGroup)}.");
+ subMenus.Add((name, null));
+ actions.Add(name);
+ numberOfRadialParts += 1;
}
+ // Continue with the traversal.
+ return true;
}
- else
- {
- subMenus.Add((name, null));
- actions.Add(name);
- numberOfRadialParts += 1;
- }
- // Continue with the traversal.
- return true;
}
- }
- ///
- /// Whether the radial menu is open.
- ///
- bool radialMenuTrigger;
+ ///
+ /// Whether the radial menu is open.
+ ///
+ bool radialMenuTrigger;
- ///
- /// This method gets called, when the button for the radial-menu is pressed.
- ///
- /// Information provided to action callbacks about what triggered an action.
- private void RadialMenu(InputAction.CallbackContext context)
- {
- radialMenuTrigger = true;
- }
-
- private void Update()
- {
- if (radialMenuTrigger && !spawned)
+ ///
+ /// This method gets called, when the button for the radial-menu is pressed.
+ ///
+ /// Information provided to action callbacks about what triggered an action.
+ private void RadialMenu(InputAction.CallbackContext context)
{
- SpawnRadialPart();
- radialMenuTrigger = false;
+ radialMenuTrigger = true;
}
- if (spawned)
- {
- UpdateSelectedRadialPart();
- }
- if (radialMenuTrigger && spawned)
- {
- spawned = false;
- radialMenuTrigger = false;
- HideAndTriggerSelected();
- }
- }
-
- ///
- /// Whether the current action changed.
- /// It is used to trigger the update for the GlobalActionHistory.
- ///
- public static bool IndicatorChange { set; get; }
-
- ///
- /// This method activates the selected action and deactivates the radial menu.
- ///
- public void HideAndTriggerSelected()
- {
- radialPartCanvas.gameObject.SetActive(false);
- OnPartSelected.Invoke(currentSelectedRadialPart);
- IndicatorChange = true;
- }
-
- ///
- /// This method calculates at which radial-part the user is aiming at.
- /// The selected radial part is saved in currentSelectedRadialPart, so that
- /// if the user decides to activate this part, the matching action gets triggered.
- ///
- public void UpdateSelectedRadialPart()
- {
- Vector3 centerToHand = handTransform.position - radialPartCanvas.position;
- Vector3 centerToHandProjected = Vector3.ProjectOnPlane(centerToHand, radialPartCanvas.forward);
-
- float angle = Vector3.SignedAngle(radialPartCanvas.up, centerToHandProjected, -radialPartCanvas.forward);
- if (angle < 0)
+ private void Update()
{
- angle += 360;
- }
-
- currentSelectedRadialPart = (int)angle * numberOfRadialParts / 360;
-
- for (int i = 0; i < spawnedParts.Count; i++)
- {
- if (i == currentSelectedRadialPart)
+ if (radialMenuTrigger && !spawned)
{
- spawnedParts[i].GetComponent().color = Color.yellow;
- spawnedParts[i].transform.localScale = 1.1f * Vector3.one;
- TextMeshProUGUI tmpGUI = spawnedParts[i].gameObject.transform.Find("TextField").gameObject.MustGetComponent();
- tmpGUI.color = Color.yellow;
- tmpGUI.fontStyle = (FontStyles)FontStyle.Bold;
+ SpawnRadialPart();
+ radialMenuTrigger = false;
}
- else
+ if (spawned)
{
- spawnedParts[i].GetComponent().color = Color.white;
- spawnedParts[i].transform.localScale = Vector3.one;
- TextMeshProUGUI tmpGUI = spawnedParts[i].gameObject.transform.Find("TextField").gameObject.MustGetComponent();
- tmpGUI.color = Color.black;
- tmpGUI.fontStyle = (FontStyles)FontStyle.Normal;
+ UpdateSelectedRadialPart();
+ }
+ if (radialMenuTrigger && spawned)
+ {
+ spawned = false;
+ radialMenuTrigger = false;
+ HideAndTriggerSelected();
}
}
- }
- ///
- /// Is true if the radial menu is open.
- ///
- bool spawned;
-
- ///
- /// This list represents all hideActions.
- ///
- static List hideActions = new()
- {
- "HideAll",
- "HideSelected",
- "HideUnselected",
- "HideOutgoing",
- "HideIncoming",
- "HideAllEdgesOfSelected",
- "HideForwardTransitiveClosure",
- "HideBackwardTransitiveClosure",
- "HideAllTransitiveClosure",
- "HighlightEdges",
- "Back"
- };
+ ///
+ /// Whether the current action changed.
+ /// It is used to trigger the update for the GlobalActionHistory.
+ ///
+ public static bool IndicatorChange { set; get; }
+ ///
+ /// This method activates the selected action and deactivates the radial menu.
+ ///
+ public void HideAndTriggerSelected()
+ {
+ radialPartCanvas.gameObject.SetActive(false);
+ OnPartSelected.Invoke(currentSelectedRadialPart);
+ IndicatorChange = true;
+ }
- ///
- /// This method activates the selected action, or opens a submenu/mainmenu.
- ///
- /// the current selected radialPart.
- public void SelectAction(int i)
- {
- if (menuEntries.Count != 0)
+ ///
+ /// This method calculates at which radial-part the user is aiming at.
+ /// The selected radial part is saved in currentSelectedRadialPart, so that
+ /// if the user decides to activate this part, the matching action gets triggered.
+ ///
+ public void UpdateSelectedRadialPart()
{
- if (actions[i] == "Back")
- {
- actions.Clear();
- actions.AddRange(menuEntries);
- numberOfRadialParts = actions.Count();
- radialMenuTrigger = true;
- menuEntries.Clear();
- subMenuPosition = radialPartCanvas.position;
- subMenuRotation = radialPartCanvas.rotation;
- }
- else if (actions[i] == "HideAll")
- {
- HideMode = HideModeSelector.HideAll;
- TriggerHideAction();
- }
- else if (actions[i] == "HideSelected")
- {
- HideMode = HideModeSelector.HideSelected;
- TriggerHideAction();
- }
- else if (actions[i] == "HideUnselected")
- {
- HideMode = HideModeSelector.HideUnselected;
- TriggerHideAction();
- }
- else if (actions[i] == "HideOutgoing")
- {
- HideMode = HideModeSelector.HideOutgoing;
- TriggerHideAction();
- }
- else if (actions[i] == "HideIncoming")
- {
- HideMode = HideModeSelector.HideIncoming;
- TriggerHideAction();
- }
- else if (actions[i] == "HideAllEdgesOfSelected")
- {
- HideMode = HideModeSelector.HideAllEdgesOfSelected;
- TriggerHideAction();
- }
- else if (actions[i] == "HideForwardTransitiveClosure")
- {
- HideMode = HideModeSelector.HideForwardTransitiveClosure;
- TriggerHideAction();
- }
- else if (actions[i] == "HideBackwardTransitiveClosure")
- {
- HideMode = HideModeSelector.HideBackwardTransitiveClosure;
- TriggerHideAction();
- }
- else if (actions[i] == "HideAllTransitiveClosure")
- {
- HideMode = HideModeSelector.HideAllTransitiveClosure;
- TriggerHideAction();
- }
- else if (actions[i] == "HighlightEdges")
+ Vector3 centerToHand = handTransform.position - radialPartCanvas.position;
+ Vector3 centerToHandProjected = Vector3.ProjectOnPlane(centerToHand, radialPartCanvas.forward);
+
+ float angle = Vector3.SignedAngle(radialPartCanvas.up, centerToHandProjected, -radialPartCanvas.forward);
+
+ if (angle < 0)
{
- HideMode = HideModeSelector.HighlightEdges;
- TriggerHideAction();
+ angle += 360;
}
- else
+
+ currentSelectedRadialPart = (int)angle * numberOfRadialParts / 360;
+
+ for (int i = 0; i < spawnedParts.Count; i++)
{
- GlobalActionHistory.Execute((ActionStateType)ActionStateTypes.AllRootTypes.AllElements().FirstOrDefault(a => a.Name == actions[i]));
+ if (i == currentSelectedRadialPart)
+ {
+ spawnedParts[i].GetComponent().color = Color.yellow;
+ spawnedParts[i].transform.localScale = 1.1f * Vector3.one;
+ TextMeshProUGUI tmpGUI = spawnedParts[i].gameObject.transform.Find("TextField").gameObject.MustGetComponent();
+ tmpGUI.color = Color.yellow;
+ tmpGUI.fontStyle = (FontStyles)FontStyle.Bold;
+ }
+ else
+ {
+ spawnedParts[i].GetComponent().color = Color.white;
+ spawnedParts[i].transform.localScale = Vector3.one;
+ TextMeshProUGUI tmpGUI = spawnedParts[i].gameObject.transform.Find("TextField").gameObject.MustGetComponent();
+ tmpGUI.color = Color.black;
+ tmpGUI.fontStyle = (FontStyles)FontStyle.Normal;
+ }
}
}
- else
+
+ ///
+ /// Is true if the radial menu is open.
+ ///
+ bool spawned;
+
+ ///
+ /// This list represents all hideActions.
+ ///
+ static List hideActions = new()
{
- if (subMenus[i].Item2 == null)
+ "HideAll",
+ "HideSelected",
+ "HideUnselected",
+ "HideOutgoing",
+ "HideIncoming",
+ "HideAllEdgesOfSelected",
+ "HideForwardTransitiveClosure",
+ "HideBackwardTransitiveClosure",
+ "HideAllTransitiveClosure",
+ "HighlightEdges",
+ "Back"
+ };
+
+
+ ///
+ /// This method activates the selected action, or opens a submenu/mainmenu.
+ ///
+ /// the current selected radialPart.
+ public void SelectAction(int i)
+ {
+ if (menuEntries.Count != 0)
{
- if (subMenus[i].Item1 == "Hide")
+ if (actions[i] == "Back")
{
- numberOfRadialParts = hideActions.Count();
- menuEntries.AddRange(actions);
actions.Clear();
- actions.AddRange(hideActions);
+ actions.AddRange(menuEntries);
+ numberOfRadialParts = actions.Count();
radialMenuTrigger = true;
+ menuEntries.Clear();
subMenuPosition = radialPartCanvas.position;
subMenuRotation = radialPartCanvas.rotation;
}
- if (actions[i] == ActionStateTypes.Rotate.Name)
+ else if (actions[i] == "HideAll")
{
- if (actionObject != null)
- {
- Destroyer.Destroy(actionObject);
- }
- actionObject = PrefabInstantiator.InstantiatePrefab("Prefabs/Dial").transform.gameObject;
- actionObject.transform.position = handTransform.position;
- actionObject.SetActive(true);
+ HideMode = HideModeSelector.HideAll;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideSelected")
+ {
+ HideMode = HideModeSelector.HideSelected;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideUnselected")
+ {
+ HideMode = HideModeSelector.HideUnselected;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideOutgoing")
+ {
+ HideMode = HideModeSelector.HideOutgoing;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideIncoming")
+ {
+ HideMode = HideModeSelector.HideIncoming;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideAllEdgesOfSelected")
+ {
+ HideMode = HideModeSelector.HideAllEdgesOfSelected;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideForwardTransitiveClosure")
+ {
+ HideMode = HideModeSelector.HideForwardTransitiveClosure;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideBackwardTransitiveClosure")
+ {
+ HideMode = HideModeSelector.HideBackwardTransitiveClosure;
+ TriggerHideAction();
+ }
+ else if (actions[i] == "HideAllTransitiveClosure")
+ {
+ HideMode = HideModeSelector.HideAllTransitiveClosure;
+ TriggerHideAction();
}
- else if (actionObject != null)
+ else if (actions[i] == "HighlightEdges")
{
- actionObject.SetActive(false);
+ HideMode = HideModeSelector.HighlightEdges;
+ TriggerHideAction();
+ }
+ else
+ {
+ GlobalActionHistory.Execute((ActionStateType)ActionStateTypes.AllRootTypes.AllElements().FirstOrDefault(a => a.Name == actions[i]));
}
- GlobalActionHistory.Execute((ActionStateType)ActionStateTypes.AllRootTypes.AllElements().FirstOrDefault(a => a.Name == subMenus[i].Item1));
}
else
{
- numberOfRadialParts = subMenus[i].Item2.Count() + 1;
- menuEntries.AddRange(actions);
- actions.Clear();
- actions.AddRange(subMenus[i].Item2);
- actions.Add("Back");
- radialMenuTrigger = true;
- subMenuPosition = radialPartCanvas.position;
- subMenuRotation = radialPartCanvas.rotation;
+ if (subMenus[i].Item2 == null)
+ {
+ if (subMenus[i].Item1 == "Hide")
+ {
+ numberOfRadialParts = hideActions.Count();
+ menuEntries.AddRange(actions);
+ actions.Clear();
+ actions.AddRange(hideActions);
+ radialMenuTrigger = true;
+ subMenuPosition = radialPartCanvas.position;
+ subMenuRotation = radialPartCanvas.rotation;
+ }
+ if (actions[i] == ActionStateTypes.Rotate.Name)
+ {
+ if (actionObject != null)
+ {
+ Destroyer.Destroy(actionObject);
+ }
+ actionObject = PrefabInstantiator.InstantiatePrefab("Prefabs/Dial").transform.gameObject;
+ actionObject.transform.position = handTransform.position;
+ actionObject.SetActive(true);
+ }
+ else if (actionObject != null)
+ {
+ actionObject.SetActive(false);
+ }
+ GlobalActionHistory.Execute((ActionStateType)ActionStateTypes.AllRootTypes.AllElements().FirstOrDefault(a => a.Name == subMenus[i].Item1));
+ }
+ else
+ {
+ numberOfRadialParts = subMenus[i].Item2.Count() + 1;
+ menuEntries.AddRange(actions);
+ actions.Clear();
+ actions.AddRange(subMenus[i].Item2);
+ actions.Add("Back");
+ radialMenuTrigger = true;
+ subMenuPosition = radialPartCanvas.position;
+ subMenuRotation = radialPartCanvas.rotation;
+ }
}
}
- }
-
- ///
- /// This triggers the HideAction.
- ///
- private void TriggerHideAction()
- {
- GlobalActionHistory.Execute((ActionStateType)ActionStateTypes.AllRootTypes.AllElements().FirstOrDefault(a => a.Name == "Hide"));
- }
- ///
- /// This method spawns all radial-parts for the current menu.
- ///
- public void SpawnRadialPart()
- {
- radialPartCanvas.gameObject.SetActive(true);
- if (subMenuPosition != null && subMenuRotation != null)
+ ///
+ /// This triggers the HideAction.
+ ///
+ private void TriggerHideAction()
{
- radialPartCanvas.position = (Vector3)subMenuPosition;
- radialPartCanvas.rotation = (Quaternion)subMenuRotation;
- subMenuPosition = null;
- subMenuRotation = null;
+ GlobalActionHistory.Execute((ActionStateType)ActionStateTypes.AllRootTypes.AllElements().FirstOrDefault(a => a.Name == "Hide"));
}
- else
- {
- radialPartCanvas.position = handTransform.position + new Vector3(0, 0, 0.2f);
- radialPartCanvas.rotation = handTransform.rotation;
- }
-
- foreach (GameObject item in spawnedParts)
+ ///
+ /// This method spawns all radial-parts for the current menu.
+ ///
+ public void SpawnRadialPart()
{
- Destroyer.Destroy(item);
- }
+ radialPartCanvas.gameObject.SetActive(true);
+ if (subMenuPosition != null && subMenuRotation != null)
+ {
+ radialPartCanvas.position = (Vector3)subMenuPosition;
+ radialPartCanvas.rotation = (Quaternion)subMenuRotation;
+ subMenuPosition = null;
+ subMenuRotation = null;
+ }
+ else
+ {
+ radialPartCanvas.position = handTransform.position + new Vector3(0, 0, 0.2f);
+ radialPartCanvas.rotation = handTransform.rotation;
+ }
- spawnedParts.Clear();
- for (int i = 0; i < numberOfRadialParts; i++)
- {
- float angle = -i * 360 / numberOfRadialParts - angleBetweenPart / 2;
- Vector3 radialPartEulerAngle = new Vector3(0, 0, angle);
+ foreach (GameObject item in spawnedParts)
+ {
+ Destroyer.Destroy(item);
+ }
- GameObject spawnRadialPart = Instantiate(radialPartPrefab, radialPartCanvas);
- spawnRadialPart.transform.position = radialPartCanvas.position;
- spawnRadialPart.transform.localEulerAngles = radialPartEulerAngle;
+ spawnedParts.Clear();
- spawnRadialPart.GetComponent().fillAmount = (1 / (float)numberOfRadialParts) - (angleBetweenPart / 360);
- TextMeshProUGUI tmpUGUI = spawnRadialPart.transform.Find("TextField").gameObject.MustGetComponent();
- if (i > (numberOfRadialParts / 2))
+ for (int i = 0; i < numberOfRadialParts; i++)
{
- RectTransform rectTransform = spawnRadialPart.transform.Find("TextField").gameObject.MustGetComponent();
- rectTransform.rotation *= Quaternion.Euler(0, 0, 180);
- tmpUGUI.alignment = TextAlignmentOptions.Right;
+ float angle = -i * 360 / numberOfRadialParts - angleBetweenPart / 2;
+ Vector3 radialPartEulerAngle = new Vector3(0, 0, angle);
+
+ GameObject spawnRadialPart = Instantiate(radialPartPrefab, radialPartCanvas);
+ spawnRadialPart.transform.position = radialPartCanvas.position;
+ spawnRadialPart.transform.localEulerAngles = radialPartEulerAngle;
+
+ spawnRadialPart.GetComponent().fillAmount = (1 / (float)numberOfRadialParts) - (angleBetweenPart / 360);
+ TextMeshProUGUI tmpUGUI = spawnRadialPart.transform.Find("TextField").gameObject.MustGetComponent();
+ if (i > (numberOfRadialParts / 2))
+ {
+ RectTransform rectTransform = spawnRadialPart.transform.Find("TextField").gameObject.MustGetComponent();
+ rectTransform.rotation *= Quaternion.Euler(0, 0, 180);
+ tmpUGUI.alignment = TextAlignmentOptions.Right;
+ }
+ tmpUGUI.text = actions[i];
+ spawnedParts.Add(spawnRadialPart);
}
- tmpUGUI.text = actions[i];
- spawnedParts.Add(spawnRadialPart);
+ spawned = true;
}
- spawned = true;
}
}
diff --git a/Assets/SEE/XR/Rotator.cs b/Assets/SEE/XR/Rotator.cs
index 8b91c22920..70ad75b0f7 100644
--- a/Assets/SEE/XR/Rotator.cs
+++ b/Assets/SEE/XR/Rotator.cs
@@ -5,200 +5,203 @@
using UnityEngine.XR.Interaction.Toolkit.Interactables;
using UnityEngine.XR.Interaction.Toolkit.Interactors;
-///
-/// This class is used to rotate nodes in VR.
-/// This script is based on this tutorial: "https://www.youtube.com/watch?v=vIrgCMNsE3s".
-///
-public class Rotator : MonoBehaviour
+namespace SEE.XR
{
///
- /// The actual dial, which gets rotated.
+ /// This class is used to rotate nodes in VR.
+ /// This script is based on this tutorial: "https://www.youtube.com/watch?v=vIrgCMNsE3s".
///
- [SerializeField]
- private Transform linkedDial;
-
- ///
- /// The amount of degrees the dial gets roated each time.
- ///
- [SerializeField]
- private int snapRotationAmount = 25;
-
- ///
- /// The amount of degrees at which the dial is starting to rotate.
- ///
- [SerializeField]
- private float angleTolerance;
-
- ///
- /// The controller, which is used to rotated the dial/node.
- ///
- private XRBaseInteractor interactor;
-
- ///
- /// The base angle.
- ///
- private float startAngle;
-
- ///
- /// Whether this is the first rotation.
- ///
- private bool firstRotation = true;
-
- ///
- /// Whether the dial/node should be rotated according to the hand-rotation.
- ///
- public static bool ShouldGetHandRotation { get; private set; } = false;
-
- ///
- /// The grab-interactor of the dial.
- ///
- private XRGrabInteractable grabInteractor;
-
- private void Awake()
- {
- grabInteractor = GetComponent();
- }
-
- private void OnEnable()
+ public class Rotator : MonoBehaviour
{
- grabInteractor.selectEntered.AddListener(GrabbedBy);
- grabInteractor.selectExited.AddListener(GrabEnd);
- }
-
- private void OnDisable()
- {
- grabInteractor.selectEntered.RemoveListener(GrabbedBy);
- grabInteractor.selectExited.RemoveListener(GrabEnd);
- }
+ ///
+ /// The actual dial, which gets rotated.
+ ///
+ [SerializeField]
+ private Transform linkedDial;
+
+ ///
+ /// The amount of degrees the dial gets roated each time.
+ ///
+ [SerializeField]
+ private int snapRotationAmount = 25;
+
+ ///
+ /// The amount of degrees at which the dial is starting to rotate.
+ ///
+ [SerializeField]
+ private float angleTolerance;
+
+ ///
+ /// The controller, which is used to rotated the dial/node.
+ ///
+ private XRBaseInteractor interactor;
+
+ ///
+ /// The base angle.
+ ///
+ private float startAngle;
+
+ ///
+ /// Whether this is the first rotation.
+ ///
+ private bool firstRotation = true;
+
+ ///
+ /// Whether the dial/node should be rotated according to the hand-rotation.
+ ///
+ public static bool ShouldGetHandRotation { get; private set; } = false;
+
+ ///
+ /// The grab-interactor of the dial.
+ ///
+ private XRGrabInteractable grabInteractor;
+
+ private void Awake()
+ {
+ grabInteractor = GetComponent();
+ }
- ///
- /// This method gets called when the user stops using the dial.
- ///
- /// Event data associated with the event when an Interactor stops selecting an Interactable.
- private void GrabEnd(SelectExitEventArgs args)
- {
- ShouldGetHandRotation = false;
- firstRotation = true;
- }
+ private void OnEnable()
+ {
+ grabInteractor.selectEntered.AddListener(GrabbedBy);
+ grabInteractor.selectExited.AddListener(GrabEnd);
+ }
- ///
- /// This method gets called when the user begins using the dial.
- ///
- /// Event data associated with the event when an Interactor first initiates selecting an Interactable.
- private void GrabbedBy(SelectEnterEventArgs args)
- {
- interactor = (XRBaseInteractor)GetComponent().interactorsSelecting[0];
- ShouldGetHandRotation = true;
- startAngle = 0f;
- }
+ private void OnDisable()
+ {
+ grabInteractor.selectEntered.RemoveListener(GrabbedBy);
+ grabInteractor.selectExited.RemoveListener(GrabEnd);
+ }
- private void Update()
- {
- if (GlobalActionHistory.Current() != ActionStateTypes.Rotate)
+ ///
+ /// This method gets called when the user stops using the dial.
+ ///
+ /// Event data associated with the event when an Interactor stops selecting an Interactable.
+ private void GrabEnd(SelectExitEventArgs args)
{
- Destroyer.Destroy(gameObject);
+ ShouldGetHandRotation = false;
+ firstRotation = true;
}
- if (ShouldGetHandRotation)
+
+ ///
+ /// This method gets called when the user begins using the dial.
+ ///
+ /// Event data associated with the event when an Interactor first initiates selecting an Interactable.
+ private void GrabbedBy(SelectEnterEventArgs args)
{
- float rotationAngle = GetInteractorRotation();
- GetRotationDistance(rotationAngle);
+ interactor = (XRBaseInteractor)GetComponent().interactorsSelecting[0];
+ ShouldGetHandRotation = true;
+ startAngle = 0f;
}
- }
- ///
- /// Returns the current rotation-angle from the controller.
- ///
- /// The current rotation-angle from the controller.
- public float GetInteractorRotation() => interactor.transform.eulerAngles.z;
+ private void Update()
+ {
+ if (GlobalActionHistory.Current() != ActionStateTypes.Rotate)
+ {
+ Destroyer.Destroy(gameObject);
+ }
+ if (ShouldGetHandRotation)
+ {
+ float rotationAngle = GetInteractorRotation();
+ GetRotationDistance(rotationAngle);
+ }
+ }
- ///
- /// Determines in which direction and how much the dial/node should be rotated.
- ///
- /// The current angle from the controller.
- private void GetRotationDistance(float currentAngle)
- {
- if (!firstRotation)
+ ///
+ /// Returns the current rotation-angle from the controller.
+ ///
+ /// The current rotation-angle from the controller.
+ public float GetInteractorRotation() => interactor.transform.eulerAngles.z;
+
+ ///
+ /// Determines in which direction and how much the dial/node should be rotated.
+ ///
+ /// The current angle from the controller.
+ private void GetRotationDistance(float currentAngle)
{
- float angleDifference = Mathf.Abs(startAngle - currentAngle);
- if (angleDifference > angleTolerance)
+ if (!firstRotation)
{
- if (angleDifference > 270f)
+ float angleDifference = Mathf.Abs(startAngle - currentAngle);
+ if (angleDifference > angleTolerance)
{
- float angleCheck;
- if (startAngle < currentAngle)
+ if (angleDifference > 270f)
{
- angleCheck = CheckAngle(currentAngle, startAngle);
- if (angleCheck < angleTolerance)
+ float angleCheck;
+ if (startAngle < currentAngle)
{
- return;
+ angleCheck = CheckAngle(currentAngle, startAngle);
+ if (angleCheck < angleTolerance)
+ {
+ return;
+ }
+ else
+ {
+ RotateDialClockwise();
+ startAngle = currentAngle;
+ }
}
- else
+ else if (startAngle > currentAngle)
{
- RotateDialClockwise();
- startAngle = currentAngle;
+ angleCheck = CheckAngle(currentAngle, startAngle);
+ if (angleCheck < angleTolerance)
+ {
+ return;
+ }
+ else
+ {
+ RotateDialAntiClockwise();
+ startAngle = currentAngle;
+ }
}
}
- else if (startAngle > currentAngle)
+ else
{
- angleCheck = CheckAngle(currentAngle, startAngle);
- if (angleCheck < angleTolerance)
+ if (startAngle < currentAngle)
{
- return;
+ RotateDialAntiClockwise();
}
- else
+ else if (startAngle > currentAngle)
{
- RotateDialAntiClockwise();
- startAngle = currentAngle;
+ RotateDialClockwise();
}
+ startAngle = currentAngle;
}
}
- else
- {
- if (startAngle < currentAngle)
- {
- RotateDialAntiClockwise();
- }
- else if (startAngle > currentAngle)
- {
- RotateDialClockwise();
- }
- startAngle = currentAngle;
- }
+ }
+ else
+ {
+ firstRotation = false;
+ startAngle = currentAngle;
}
}
- else
+
+ ///
+ /// Calculates the current rotation angle of the controller.
+ ///
+ /// The current angle of the controller.
+ /// The base angle.
+ /// the amount of rotation
+ private float CheckAngle(float currentAngle, float startAngle) => (360f - currentAngle) + startAngle;
+
+ ///
+ /// Rotates the dial/node clockwise.
+ ///
+ private void RotateDialClockwise()
{
- firstRotation = false;
- startAngle = currentAngle;
+ linkedDial.localEulerAngles = new Vector3(linkedDial.localEulerAngles.x, linkedDial.localEulerAngles.y + snapRotationAmount, linkedDial.localEulerAngles.z);
+ Transform rotateObject = XRSEEActions.RotateObject.transform;
+ rotateObject.localEulerAngles = new Vector3(rotateObject.localEulerAngles.x, linkedDial.localEulerAngles.y, rotateObject.localEulerAngles.z);
}
- }
-
- ///
- /// Calculates the current rotation angle of the controller.
- ///
- /// The current angle of the controller.
- /// The base angle.
- /// the amount of rotation
- private float CheckAngle(float currentAngle, float startAngle) => (360f - currentAngle) + startAngle;
- ///
- /// Rotates the dial/node clockwise.
- ///
- private void RotateDialClockwise()
- {
- linkedDial.localEulerAngles = new Vector3(linkedDial.localEulerAngles.x, linkedDial.localEulerAngles.y + snapRotationAmount, linkedDial.localEulerAngles.z);
- Transform rotateObject = XRSEEActions.RotateObject.transform;
- rotateObject.localEulerAngles = new Vector3(rotateObject.localEulerAngles.x, linkedDial.localEulerAngles.y, rotateObject.localEulerAngles.z);
- }
+ ///
+ /// Rotates the dial/node anticlockwise.
+ ///
+ private void RotateDialAntiClockwise()
+ {
+ linkedDial.localEulerAngles = new Vector3(linkedDial.localEulerAngles.x, linkedDial.localEulerAngles.y - snapRotationAmount, linkedDial.localEulerAngles.z);
+ Transform rotateObject = XRSEEActions.RotateObject.transform;
+ rotateObject.localEulerAngles = new Vector3(rotateObject.localEulerAngles.x, linkedDial.localEulerAngles.y, rotateObject.localEulerAngles.z);
+ }
- ///
- /// Rotates the dial/node anticlockwise.
- ///
- private void RotateDialAntiClockwise()
- {
- linkedDial.localEulerAngles = new Vector3(linkedDial.localEulerAngles.x, linkedDial.localEulerAngles.y - snapRotationAmount, linkedDial.localEulerAngles.z);
- Transform rotateObject = XRSEEActions.RotateObject.transform;
- rotateObject.localEulerAngles = new Vector3(rotateObject.localEulerAngles.x, linkedDial.localEulerAngles.y, rotateObject.localEulerAngles.z);
}
-
}
diff --git a/Assets/SEE/XR/XRSEEActions.cs b/Assets/SEE/XR/XRSEEActions.cs
index 5accf42b64..b54c4684f9 100644
--- a/Assets/SEE/XR/XRSEEActions.cs
+++ b/Assets/SEE/XR/XRSEEActions.cs
@@ -8,248 +8,251 @@
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactors;
-///
-/// This is a central control class for VR.
-/// It is used to provide the input from the controllers
-/// for all actions in SEE.
-///
-public class XRSEEActions : MonoBehaviour
+namespace SEE.XR
{
///
- /// The RayInteractor that we use to get the current position of the laserpointer.
+ /// This is a central control class for VR.
+ /// It is used to provide the input from the controllers
+ /// for all actions in SEE.
///
- public static XRRayInteractor RayInteractor { get; set; }
+ public class XRSEEActions : MonoBehaviour
+ {
+ ///
+ /// The RayInteractor that we use to get the current position of the laserpointer.
+ ///
+ public static XRRayInteractor RayInteractor { get; set; }
- ///
- /// Whether the user is hovering over an interactable.
- ///
- private bool hovering = false;
+ ///
+ /// Whether the user is hovering over an interactable.
+ ///
+ private bool hovering = false;
- ///
- /// The GameObject the user is currently hovering over.
- ///
- public static GameObject hoveredGameObject { get; private set; }
+ ///
+ /// The GameObject the user is currently hovering over.
+ ///
+ public static GameObject hoveredGameObject { get; private set; }
- ///
- /// The old parent of a node. We need this for the MoveAction.
- ///
- public static Transform oldParent { get; set; }
+ ///
+ /// The old parent of a node. We need this for the MoveAction.
+ ///
+ public static Transform oldParent { get; set; }
- ///
- /// The button that's used for the primary actions.
- ///
- public InputActionReference inputAction;
-
- ///
- /// The button that's used for the undo-action.
- ///
- public InputActionReference undo;
+ ///
+ /// The button that's used for the primary actions.
+ ///
+ public InputActionReference inputAction;
- ///
- /// The button that's used for the redo-action.
- ///
- public InputActionReference redo;
+ ///
+ /// The button that's used for the undo-action.
+ ///
+ public InputActionReference undo;
- ///
- /// The button that's used to open the tooltip.
- ///
- public InputActionReference tooltip;
+ ///
+ /// The button that's used for the redo-action.
+ ///
+ public InputActionReference redo;
- ///
- /// Shows the source name of the hovered or selected object as a text label above the
- /// object. In between that label and the game object, a connecting bar
- /// will be shown.
- ///
- private ShowLabel showLabel;
+ ///
+ /// The button that's used to open the tooltip.
+ ///
+ public InputActionReference tooltip;
- private void Awake()
- {
- tooltip.action.performed += Tooltip;
- undo.action.performed += Undo;
- redo.action.performed += Redo;
- inputAction.action.Enable();
- inputAction.action.performed += Action;
- RayInteractor = GameObject.Find("XRRig(Clone)/Camera Offset/Right Controller/XRRay").MustGetComponent();
- Selected = false;
- }
+ ///
+ /// Shows the source name of the hovered or selected object as a text label above the
+ /// object. In between that label and the game object, a connecting bar
+ /// will be shown.
+ ///
+ private ShowLabel showLabel;
- ///
- /// This method gets called, when the user begins to hover over an interactable.
- /// It provides the input data from the controller with regard to the start of a hover over an object in the CodeCity.
- ///
- /// Event data associated with the event when an Interactor first initiates hovering over an Interactable.
- public void OnHoverEnter(HoverEnterEventArgs args)
- {
- hovering = true;
- hoveredGameObject = args.interactableObject.transform.gameObject;
- if (GlobalActionHistory.Current() == ActionStateTypes.Move)
- {
- oldParent = args.interactableObject.transform.parent;
- }
- if (hoveredGameObject.transform.TryGetComponent(out showLabel))
- {
- showLabel.On();
- }
- if (hoveredGameObject.transform.TryGetComponent(out InteractableObject io))
+ private void Awake()
{
- io.SetHoverFlag(HoverFlag.World, true, true);
+ tooltip.action.performed += Tooltip;
+ undo.action.performed += Undo;
+ redo.action.performed += Redo;
+ inputAction.action.Enable();
+ inputAction.action.performed += Action;
+ RayInteractor = GameObject.Find("XRRig(Clone)/Camera Offset/Right Controller/XRRay").MustGetComponent();
+ Selected = false;
}
- }
- ///
- /// This method gets called, when the user stops hovering over an interactable.
- /// It provides the input data from the controller with regard to the end of a hover over an object in the CodeCity.
- ///
- /// Event data associated with the event when an Interactor stops hovering over an Interactable.
- public void OnHoverExited(HoverExitEventArgs args)
- {
- hovering = false;
- hoveredGameObject = args.interactableObject.transform.gameObject;
- hoveredGameObject.transform.TryGetComponent(out showLabel);
- if (hoveredGameObject.transform.TryGetComponent(out showLabel))
+ ///
+ /// This method gets called, when the user begins to hover over an interactable.
+ /// It provides the input data from the controller with regard to the start of a hover over an object in the CodeCity.
+ ///
+ /// Event data associated with the event when an Interactor first initiates hovering over an Interactable.
+ public void OnHoverEnter(HoverEnterEventArgs args)
{
- showLabel.Off();
+ hovering = true;
+ hoveredGameObject = args.interactableObject.transform.gameObject;
+ if (GlobalActionHistory.Current() == ActionStateTypes.Move)
+ {
+ oldParent = args.interactableObject.transform.parent;
+ }
+ if (hoveredGameObject.transform.TryGetComponent(out showLabel))
+ {
+ showLabel.On();
+ }
+ if (hoveredGameObject.transform.TryGetComponent(out InteractableObject io))
+ {
+ io.SetHoverFlag(HoverFlag.World, true, true);
+ }
}
- if (hoveredGameObject.transform.TryGetComponent(out InteractableObject io))
+
+ ///
+ /// This method gets called, when the user stops hovering over an interactable.
+ /// It provides the input data from the controller with regard to the end of a hover over an object in the CodeCity.
+ ///
+ /// Event data associated with the event when an Interactor stops hovering over an Interactable.
+ public void OnHoverExited(HoverExitEventArgs args)
{
- io.SetHoverFlag(HoverFlag.World, false, true);
+ hovering = false;
+ hoveredGameObject = args.interactableObject.transform.gameObject;
+ hoveredGameObject.transform.TryGetComponent(out showLabel);
+ if (hoveredGameObject.transform.TryGetComponent(out showLabel))
+ {
+ showLabel.Off();
+ }
+ if (hoveredGameObject.transform.TryGetComponent(out InteractableObject io))
+ {
+ io.SetHoverFlag(HoverFlag.World, false, true);
+ }
}
- }
- ///
- /// Whether the button for the primary actions is pressed.
- ///
- public static bool Selected { get; set; }
+ ///
+ /// Whether the button for the primary actions is pressed.
+ ///
+ public static bool Selected { get; set; }
- ///
- /// Whether an object in the code city should marked as selected.
- ///
- public static bool SelectedFlag { get; set; }
+ ///
+ /// Whether an object in the code city should marked as selected.
+ ///
+ public static bool SelectedFlag { get; set; }
- ///
- /// The GameObject, which should be rotated.
- ///
- public static GameObject RotateObject { get; set; }
+ ///
+ /// The GameObject, which should be rotated.
+ ///
+ public static GameObject RotateObject { get; set; }
- ///
- /// This method gets called, when the button for the primary actions is pressed.
- /// After the button got pressed, the desired action will be performed if all conditions are matching.
- ///
- /// Information provided to action callbacks about what triggered an action.
- private void Action(InputAction.CallbackContext context)
- {
- if (hovering)
+ ///
+ /// This method gets called, when the button for the primary actions is pressed.
+ /// After the button got pressed, the desired action will be performed if all conditions are matching.
+ ///
+ /// Information provided to action callbacks about what triggered an action.
+ private void Action(InputAction.CallbackContext context)
{
- if (GlobalActionHistory.Current() == ActionStateTypes.Move && Selected)
+ if (hovering)
{
- Selected = false;
- SelectedFlag = false;
- }
- else
- {
- if (GlobalActionHistory.Current() == ActionStateTypes.Rotate)
+ if (GlobalActionHistory.Current() == ActionStateTypes.Move && Selected)
{
- RayInteractor.TryGetCurrent3DRaycastHit(out RaycastHit hit);
- RotateObject = hit.collider.transform.gameObject;
+ Selected = false;
+ SelectedFlag = false;
}
- Selected = true;
- if (GlobalActionHistory.Current() != ActionStateTypes.Move)
+ else
{
- SelectedFlag = true;
+ if (GlobalActionHistory.Current() == ActionStateTypes.Rotate)
+ {
+ RayInteractor.TryGetCurrent3DRaycastHit(out RaycastHit hit);
+ RotateObject = hit.collider.transform.gameObject;
+ }
+ Selected = true;
+ if (GlobalActionHistory.Current() != ActionStateTypes.Move)
+ {
+ SelectedFlag = true;
+ }
}
}
+ else
+ {
+ InteractableObject.ReplaceSelection(null, true);
+ }
}
- else
- {
- InteractableObject.ReplaceSelection(null, true);
- }
- }
- ///
- /// Whether the TreeView is open while the user tries to move a node.
- /// We need to know if the user has the TreeView open, while moving a node,
- /// because this can caus lags, which we prevent by closing the TreeView, befor
- /// the node gets moved.
- ///
- public static bool CloseTreeView { get; set; }
+ ///
+ /// Whether the TreeView is open while the user tries to move a node.
+ /// We need to know if the user has the TreeView open, while moving a node,
+ /// because this can caus lags, which we prevent by closing the TreeView, befor
+ /// the node gets moved.
+ ///
+ public static bool CloseTreeView { get; set; }
- ///
- /// Whether the Tooltip is getting activated.
- ///
- public static bool TooltipToggle { get; set; }
+ ///
+ /// Whether the Tooltip is getting activated.
+ ///
+ public static bool TooltipToggle { get; set; }
- ///
- /// Whether the Tooltip is open.
- /// This is used to close the Tooltip if the user does not want to use an action.
- ///
- public static bool OnSelectToggle { get; set; }
+ ///
+ /// Whether the Tooltip is open.
+ /// This is used to close the Tooltip if the user does not want to use an action.
+ ///
+ public static bool OnSelectToggle { get; set; }
- ///
- /// Whether the user opened the tooltip in the treeview.
- ///
- public static bool OnTreeViewToggle { get; set; }
+ ///
+ /// Whether the user opened the tooltip in the treeview.
+ ///
+ public static bool OnTreeViewToggle { get; set; }
- ///
- /// The treeview entry for which the tooltip should be shown.
- ///
- public static GameObject TreeViewEntry { get; set; }
+ ///
+ /// The treeview entry for which the tooltip should be shown.
+ ///
+ public static GameObject TreeViewEntry { get; set; }
- ///
- /// This method gets called, when the button for the tooltip is pressed.
- /// When the user points at an object in the CodeCity, or an entry in the TreeView and
- /// presses the corresponding button, it opens up and after another
- /// button-press or the selection of an entry it gets closed.
- ///
- /// Information provided to action callbacks about what triggered an action.
- private void Tooltip(InputAction.CallbackContext context)
- {
- if (OnTreeViewToggle)
- {
- TooltipToggle = true;
- TreeViewEntry.MustGetComponent().ThumbstickEvent.Invoke(new PointerEventData(EventSystem.current));
- }
- else if (hovering && !OnTreeViewToggle)
- {
- TooltipToggle = true;
- }
- else if (OnSelectToggle)
+ ///
+ /// This method gets called, when the button for the tooltip is pressed.
+ /// When the user points at an object in the CodeCity, or an entry in the TreeView and
+ /// presses the corresponding button, it opens up and after another
+ /// button-press or the selection of an entry it gets closed.
+ ///
+ /// Information provided to action callbacks about what triggered an action.
+ private void Tooltip(InputAction.CallbackContext context)
{
- TooltipToggle = true;
+ if (OnTreeViewToggle)
+ {
+ TooltipToggle = true;
+ TreeViewEntry.MustGetComponent().ThumbstickEvent.Invoke(new PointerEventData(EventSystem.current));
+ }
+ else if (hovering && !OnTreeViewToggle)
+ {
+ TooltipToggle = true;
+ }
+ else if (OnSelectToggle)
+ {
+ TooltipToggle = true;
+ }
}
- }
- ///
- /// Whether the button for the undo-action is pressed.
- ///
- public static bool UndoToggle { get; set; }
+ ///
+ /// Whether the button for the undo-action is pressed.
+ ///
+ public static bool UndoToggle { get; set; }
- ///
- /// This method gets called, when the button for the undo-action is pressed.
- /// It will undo the last action.
- ///
- /// Information provided to action callbacks about what triggered an action.
- private void Undo(InputAction.CallbackContext context)
- {
- UndoToggle = true;
- }
+ ///
+ /// This method gets called, when the button for the undo-action is pressed.
+ /// It will undo the last action.
+ ///
+ /// Information provided to action callbacks about what triggered an action.
+ private void Undo(InputAction.CallbackContext context)
+ {
+ UndoToggle = true;
+ }
- ///
- /// Whether the button for the redo-action is pressed.
- ///
- public static bool RedoToggle { get; set; }
+ ///
+ /// Whether the button for the redo-action is pressed.
+ ///
+ public static bool RedoToggle { get; set; }
- ///
- /// This method gets called, when the button for the redo-action is pressed.
- /// It will redo the last action that was undone.
- ///
- /// Information provided to action callbacks about what triggered an action.
- private void Redo(InputAction.CallbackContext context)
- {
- RedoToggle = true;
- }
+ ///
+ /// This method gets called, when the button for the redo-action is pressed.
+ /// It will redo the last action that was undone.
+ ///
+ /// Information provided to action callbacks about what triggered an action.
+ private void Redo(InputAction.CallbackContext context)
+ {
+ RedoToggle = true;
+ }
- private void Update()
- {
- GlobalActionHistory.Update();
+ private void Update()
+ {
+ GlobalActionHistory.Update();
+ }
}
}