Skip to content

Commit

Permalink
Add new interaction behaviour "SteeringWheelBehaviour" (#135)
Browse files Browse the repository at this point in the history
* Add default SteeringWheelBehaviour

* Complete inspector
  • Loading branch information
FejZa authored Jul 5, 2024
1 parent ad28b61 commit 09497d3
Show file tree
Hide file tree
Showing 12 changed files with 460 additions and 17 deletions.
16 changes: 5 additions & 11 deletions Editor/Inspectors/BaseInteractionBehaviourInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,18 @@ namespace RealityToolkit.Editor.Inspectors
/// </summary>
public abstract class BaseInteractionBehaviourInspector : UnityEditor.Editor
{
private const string sortingOrderBindingPath = "sortingOrder";
private const string targetHandednessBindingPath = "targetHandedness";

/// <summary>
/// <inheritdoc/>
/// </summary>
public override VisualElement CreateInspectorGUI()
{
var inspector = new VisualElement();

inspector.Add(new PropertyField
{
label = "Sorting Order",
bindingPath = "sortingOrder"
});

inspector.Add(new PropertyField
{
label = "Target Handedness",
bindingPath = "targetHandedness"
});
inspector.Add(new PropertyField(serializedObject.FindProperty(sortingOrderBindingPath)));
inspector.Add(new PropertyField(serializedObject.FindProperty(targetHandednessBindingPath)));

return inspector;
}
Expand Down
7 changes: 6 additions & 1 deletion Editor/Inspectors/LeverBehaviourInspector.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using RealityToolkit.Input.InteractionBehaviours;
// Copyright (c) Reality Collective. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using RealityToolkit.Editor.Utilities;
using RealityToolkit.Input.InteractionBehaviours;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
Expand Down Expand Up @@ -100,6 +104,7 @@ public override VisualElement CreateInspectorGUI()
bindingPath = "valueZ"
});

inspector.Add(UIElementsUtilities.VerticalSpace());
inspector.Add(new PropertyField
{
label = "On Value Changed",
Expand Down
84 changes: 84 additions & 0 deletions Editor/Inspectors/LockControllerVisualizerBehaviourInspector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) Reality Collective. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using RealityToolkit.Editor.Utilities;
using RealityToolkit.Input.InteractionBehaviours;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

namespace RealityToolkit.Editor.Inspectors
{
[CustomEditor(typeof(LockControllerVisualizerBehaviour), true)]
public class LockControllerVisualizerBehaviourInspector : BaseInteractionBehaviourInspector
{
private VisualElement inspector;
private PropertyField smoothSyncPose;
private PropertyField syncPositionSpeed;
private PropertyField syncRotationSpeed;

private const string grabOffsetPoseBindingPath = "localOffsetPose";
private const string smoothSyncPoseBindingPath = "smoothSyncPose";
private const string syncPositionSpeedBindingPath = "syncPositionSpeed";
private const string syncRotationSpeedBindingPath = "syncRotationSpeed";

/// <summary>
/// <inheritdoc/>
/// </summary>
public override VisualElement CreateInspectorGUI()
{
inspector = base.CreateInspectorGUI();

inspector.Add(new PropertyField(serializedObject.FindProperty(grabOffsetPoseBindingPath)));

smoothSyncPose = new PropertyField(serializedObject.FindProperty(smoothSyncPoseBindingPath));
smoothSyncPose.RegisterCallback<ChangeEvent<bool>>(SmoothSyncPose_ValueChanged);
inspector.Add(smoothSyncPose);

syncPositionSpeed = new PropertyField(serializedObject.FindProperty(syncPositionSpeedBindingPath));
syncPositionSpeed.style.paddingLeft = UIElementsUtilities.DefaultInset;

syncRotationSpeed = new PropertyField(serializedObject.FindProperty(syncRotationSpeedBindingPath));
syncRotationSpeed.style.paddingLeft = UIElementsUtilities.DefaultInset;

UpdateSmoothSyncPoseFields(serializedObject.FindProperty(smoothSyncPoseBindingPath).boolValue);

return inspector;
}

/// <summary>
/// <inheritdoc/>
/// </summary>
private void OnDestroy()
{
if (smoothSyncPose != null)
{
smoothSyncPose.UnregisterCallback<ChangeEvent<bool>>(SmoothSyncPose_ValueChanged);
}
}

private void SmoothSyncPose_ValueChanged(ChangeEvent<bool> changeEvent) => UpdateSmoothSyncPoseFields(changeEvent.newValue);

private void UpdateSmoothSyncPoseFields(bool showFields)
{
if (showFields)
{
inspector.Add(syncPositionSpeed);
syncPositionSpeed.PlaceInFront(smoothSyncPose);
inspector.Add(syncRotationSpeed);
syncRotationSpeed.PlaceInFront(syncPositionSpeed);
return;
}

if (inspector.Contains(syncPositionSpeed))
{
inspector.Remove(syncPositionSpeed);
}

if (inspector.Contains(syncRotationSpeed))
{
inspector.Remove(syncRotationSpeed);
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 112 additions & 0 deletions Editor/Inspectors/SteeringWheelBehaviourInspector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) Reality Collective. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using RealityToolkit.Editor.Utilities;
using RealityToolkit.Input.InteractionBehaviours;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

namespace RealityToolkit.Editor.Inspectors
{
[CustomEditor(typeof(SteeringWheelBehaviour), true)]
public class SteeringWheelBehaviourInspector : BaseInteractionBehaviourInspector
{
private VisualElement inspector;
private PropertyField resetsToNeutral;
private PropertyField smoothReset;
private PropertyField smoothResetDuration;

private const string steeringAngleLimitBindingPath = "steeringAngleLimit";
private const string upTransformBindingPath = "upTransform";
private const string resetsToNeutralBindingPath = "resetsToNeutral";
private const string smoothResetBindingPath = "smoothReset";
private const string smoothResetDurationBindingPath = "smoothResetDuration";
private const string steeringChangedBindingPath = "SteeringChanged";

/// <summary>
/// <inheritdoc/>
/// </summary>
public override VisualElement CreateInspectorGUI()
{
inspector = base.CreateInspectorGUI();

inspector.Add(new PropertyField(serializedObject.FindProperty(steeringAngleLimitBindingPath)));
inspector.Add(new PropertyField(serializedObject.FindProperty(upTransformBindingPath)));

resetsToNeutral = new PropertyField(serializedObject.FindProperty(resetsToNeutralBindingPath));
resetsToNeutral.RegisterCallback<ChangeEvent<bool>>(ResetsToNeutral_ValueChanged);
inspector.Add(resetsToNeutral);

smoothReset = new PropertyField(serializedObject.FindProperty(smoothResetBindingPath));
smoothReset.RegisterCallback<ChangeEvent<bool>>(SmoothReset_ValueChanged);
smoothReset.style.paddingLeft = UIElementsUtilities.DefaultInset;

smoothResetDuration = new PropertyField(serializedObject.FindProperty(smoothResetDurationBindingPath));
smoothResetDuration.style.paddingLeft = 2 * UIElementsUtilities.DefaultInset;

UpdateResetsToNeutralFields(serializedObject.FindProperty(resetsToNeutralBindingPath).boolValue);
UpdateSmoothResetFields(serializedObject.FindProperty(smoothResetBindingPath).boolValue);

inspector.Add(UIElementsUtilities.VerticalSpace());
inspector.Add(new PropertyField(serializedObject.FindProperty(steeringChangedBindingPath)));

return inspector;
}

/// <summary>
/// <inheritdoc/>
/// </summary>
private void OnDestroy()
{
if (resetsToNeutral != null)
{
resetsToNeutral.UnregisterCallback<ChangeEvent<bool>>(ResetsToNeutral_ValueChanged);
}

if (smoothReset != null)
{
smoothReset.UnregisterCallback<ChangeEvent<bool>>(SmoothReset_ValueChanged);
}
}

private void ResetsToNeutral_ValueChanged(ChangeEvent<bool> changeEvent) => UpdateResetsToNeutralFields(changeEvent.newValue);

private void UpdateResetsToNeutralFields(bool showFields)
{
if (showFields)
{
inspector.Add(smoothReset);
smoothReset.PlaceInFront(resetsToNeutral);
return;
}

if (inspector.Contains(smoothReset))
{
inspector.Remove(smoothReset);
}

if (inspector.Contains(smoothResetDuration))
{
inspector.Remove(smoothResetDuration);
}
}

private void SmoothReset_ValueChanged(ChangeEvent<bool> changeEvent) => UpdateSmoothResetFields(changeEvent.newValue);

private void UpdateSmoothResetFields(bool showFields)
{
if (serializedObject.FindProperty(resetsToNeutralBindingPath).boolValue && showFields)
{
inspector.Add(smoothResetDuration);
smoothResetDuration.PlaceInFront(smoothReset);
return;
}

if (inspector.Contains(smoothResetDuration))
{
inspector.Remove(smoothResetDuration);
}
}
}
}
11 changes: 11 additions & 0 deletions Editor/Inspectors/SteeringWheelBehaviourInspector.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Editor/Utilities/UIElementsUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public static class UIElementsUtilities
{
private const int defaultVerticalSpace = 10;

/// <summary>
/// Inset in pixels per intendation level for custom inspectors.
/// </summary>
public const int DefaultInset = 16;

/// <summary>
/// Creates an empty <see cref="VisualElement"/> to create vertical space.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace RealityToolkit.Input.InteractionBehaviours
// Copyright (c) Reality Collective. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

namespace RealityToolkit.Input.InteractionBehaviours
{
/// <summary>
/// Supported interactor tracking modes.
Expand Down
5 changes: 4 additions & 1 deletion Runtime/Input/InteractionBehaviours/LeverBehaviour.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using RealityCollective.Utilities.Extensions;
// Copyright (c) Reality Collective. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using RealityCollective.Utilities.Extensions;
using RealityToolkit.Input.Events;
using RealityToolkit.Input.Interactors;
using UnityEngine;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public class LockControllerVisualizerBehaviour : BaseInteractionBehaviour
[SerializeField, Tooltip("Optional offset pose applied to the visualizer.")]
private Pose localOffsetPose = Pose.identity;

[SerializeField, Tooltip("If set, the controller visualizer will snap to the interactable instead of a smooth transition.")]
private bool snapToLockPose = false;
[SerializeField, Tooltip("If set, the controller visualizer will smoothly attach to the interactable instead of instantly.")]
private bool smoothSyncPose = true;

[SerializeField, Tooltip("Speed applied to smoothly move to the interactable position."), Min(1f)]
private float syncPositionSpeed = 2f;
Expand Down Expand Up @@ -114,7 +114,7 @@ protected override void OnGrabExited(InteractionExitEventArgs eventArgs)

private void LockVisualizer(IControllerVisualizer visualizer)
{
lockedVisualizers.EnsureDictionaryItem(visualizer, snapToLockPose, true);
lockedVisualizers.EnsureDictionaryItem(visualizer, !smoothSyncPose, true);
visualizer.OverrideSourcePose = true;
}

Expand Down
Loading

0 comments on commit 09497d3

Please sign in to comment.