### Configure LocomotionTeleport State Machine Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Runtime configuration for LocomotionTeleport, including enabling/disabling movement during different states and subscribing to state-change events. This example sets up a parabolic NavMesh teleport. ```csharp public class TeleportConfigurator : MonoBehaviour { [SerializeField] private LocomotionTeleport _teleport; void Start() { // Allow walking while aiming but lock it during pre-teleport confirmation _teleport.EnableMovement( ready: true, aim: true, pre: false, // prevent accidental movement while confirming target post: true); // Subscribe to state-change notifications for audio/visual feedback _teleport.EnterStateReady += () => Debug.Log("Teleport: Ready"); _teleport.EnterStateAim += () => Debug.Log("Teleport: Aiming"); _teleport.EnterStateTeleporting += () => Debug.Log("Teleport: Jumping!"); _teleport.EnterStatePostTeleport += () => Debug.Log("Teleport: Landed"); } } ``` -------------------------------- ### Setup and Compare OVROverlay Rendering Modes Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Configures an OVROverlay component for Quad or Cylinder shapes and demonstrates switching between world-geometry and overlay rendering to compare visual quality. Attach OVROverlay to the panel GameObject and configure it. ```csharp // OVROverlay layers are compositor-level quads rendered outside Unity's render pipeline. // Attach OVROverlay to the panel GameObject and configure it as shown: public class UIOverlaySetup : MonoBehaviour { [SerializeField] private OVROverlay _overlayLayer; void Start() { // Use as a Quad overlay (highest quality for flat UI) _overlayLayer.currentOverlayShape = OVROverlay.OverlayShape.Quad; _overlayLayer.currentOverlayType = OVROverlay.OverlayType.Overlay; // drawn on top // Supply a render texture as the overlay source RenderTexture rt = new RenderTexture(1024, 512, 0, RenderTextureFormat.ARGB32); _overlayLayer.textures = new Texture[] { rt }; // For a cylinder overlay (good for curved UI panels) // _overlayLayer.currentOverlayShape = OVROverlay.OverlayShape.Cylinder; // Toggle between world-geo and overlay to compare sharpness at runtime: StartCoroutine(CompareRenderModes()); } IEnumerator CompareRenderModes() { // World geometry: overlay disabled _overlayLayer.enabled = false; Debug.Log("Rendering as world geometry (lower quality)"); yield return new WaitForSeconds(3f); // Overlay layer: compositor-level (sharper, less aliasing) _overlayLayer.enabled = true; Debug.Log("Rendering as OVROverlay (higher quality)"); } } // Expected: noticeable reduction in text aliasing and moire patterns when // OVROverlay is enabled versus world-geometry rendering. ``` -------------------------------- ### Configure NavMesh Teleport Target Areas Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Custom TeleportTargetHandlerNavMesh to restrict teleportation to specific NavMesh areas. This example ensures teleports only occur on 'Walkable' or 'Jump' areas. ```csharp public class NavMeshTeleportTarget : TeleportTargetHandlerNavMesh { void Awake() { // Only allow teleporting onto Walkable + Jump areas NavMeshAreaMask = (1 << NavMesh.GetAreaFromName("Walkable")) | (1 << NavMesh.GetAreaFromName("Jump")); } } ``` -------------------------------- ### Clone Starter Samples Repository Source: https://github.com/oculus-samples/unity-startersamples/blob/main/README.md Use this command to clone the Unity Starter Samples repository to your local machine. ```sh git clone https://github.com/oculus-samples/Unity-StarterSamples.git ``` -------------------------------- ### Initialize and Use FingerTipPokeTool Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Manually initialize FingerTipPokeTool to register it with the input router. Use IsNearInteractable to detect proximity to interactables and Velocity for internal calculations. ```csharp public class PokeSetup : MonoBehaviour { [SerializeField] private FingerTipPokeTool _leftIndexPokeTool; void Awake() { // Initialize registers the tool with the global input router _leftIndexPokeTool.Initialize(); } void Update() { // The tool's IsNearInteractable flag becomes true when the fingertip // enters a ButtonTriggerZone's trigger collider. if (_leftIndexPokeTool.IsNearInteractable) { Debug.Log("Finger is near an interactable object"); } // Current velocity is used internally to determine poke direction/intent Debug.Log($"Fingertip velocity: {_leftIndexPokeTool.Velocity}"); } } ``` -------------------------------- ### OVR Hand Tracking Component Aggregation and Visualization Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt A singleton that caches OVR hand tracking components and provides methods to switch visualization modes (Mesh, Skeleton, Both). It also offers a helper to retrieve physics capsules per bone. ```csharp // Place HandsManager on a scene manager GameObject. // Assign _leftHand and _rightHand OVR prefab instances in the Inspector. public class MyHandInteractionLogic : MonoBehaviour { void Start() { // Wait until both skeletons and meshes are fully initialized StartCoroutine(WaitForHands()); } IEnumerator WaitForHands() { yield return new WaitUntil(() => HandsManager.Instance.IsInitialized()); OVRHand rightHand = HandsManager.Instance.RightHand; OVRSkeleton rightSkeleton = HandsManager.Instance.RightHandSkeleton; // Retrieve all capsules for the index fingertip bone var indexCapsules = HandsManager.GetCapsulesPerBone( rightSkeleton, OVRSkeleton.BoneId.Hand_IndexTip); Debug.Log($ ``` -------------------------------- ### Configure 360° Video Playback with Stereo Layout Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Sets up a MoviePlayerSample for 360° video playback, specifying the video file, shape, stereo layout, and refresh rate. Auto-detection of stereo layout can be enabled if metadata is available. ```csharp // Attach MoviePlayerSample to a sphere/quad mesh that acts as the video surface. // Assign MovieName to the StreamingAssets-relative path of the video file. public class VideoSceneSetup : MonoBehaviour { [SerializeField] private MoviePlayerSample _player; void Start() { // Configure for a top-bottom stereo 360 video _player.MovieName = "intro_360_tb.mp4"; // in StreamingAssets/ _player.Shape = MoviePlayerSample.VideoShape._360; _player.Stereo = MoviePlayerSample.VideoStereo.TopBottom; _player.LoopVideo = true; _player.DisplayMono = false; _player.VideoPlaybackRefreshRate = 120; // Auto-detect stereo layout from video metadata if uncertain _player.AutoDetectStereoLayout = false; } void Update() { // Query live playback state Debug.Log($"Playing: {_player.IsPlaying} " + $ ``` -------------------------------- ### Implement Thumbstick Locomotion with SimpleCapsuleWithStickMovement Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Configure SimpleCapsuleWithStickMovement to drive a Rigidbody-based capsule character for HMD-aligned forward movement and snap-turning. Customize speed, snap-turn angle, and subscribe to pre-move events for custom physics. ```csharp public class PlayerSetup : MonoBehaviour { [SerializeField] private SimpleCapsuleWithStickMovement _movement; void Awake() { // Enable smooth forward/backward movement at 3 m/s _movement.EnableLinearMovement = true; _movement.Speed = 3.0f; // Allow snap rotation at 45° per thumbstick click _movement.EnableRotation = true; _movement.RotationAngle = 45.0f; // Player body rotates to match HMD yaw automatically _movement.HMDRotatesPlayer = true; // Subscribe to pre-move event to apply custom forces _movement.PreCharacterMove += () => { Debug.Log("About to move character — apply custom physics here"); }; } } ``` -------------------------------- ### Build In-VR Debug Menu with DebugUIBuilder Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Use DebugUIBuilder.instance to programmatically add interactive elements like labels, toggles, sliders, and buttons to an in-world VR debug panel. Manage panel visibility with Show() and Hide(), and control scene object enablement/disablement. ```csharp public class MyDebugMenu : MonoBehaviour { void Start() { var db = DebugUIBuilder.instance; // Center pane controls db.AddLabel("Graphics Settings"); db.AddDivider(); db.AddToggle("Enable Shadows", OnShadowToggle, defaultValue: true); db.AddSlider("Render Scale", 0.5f, 2.0f, OnRenderScaleChanged, wholeNumbersOnly: false); db.AddButton("Reset Defaults", OnResetDefaults); // Right pane radio group db.AddRadio("Quality Low", "quality", t => SetQuality("Low", t), DebugUIBuilder.DEBUG_PANE_RIGHT); db.AddRadio("Quality Medium", "quality", t => SetQuality("Medium", t), DebugUIBuilder.DEBUG_PANE_RIGHT); db.AddRadio("Quality High", "quality", t => SetQuality("High", t), DebugUIBuilder.DEBUG_PANE_RIGHT); db.Show(); } void OnShadowToggle(Toggle t) => QualitySettings.shadows = t.isOn ? ShadowQuality.All : ShadowQuality.Disable; void OnRenderScaleChanged(float scale) => UnityEngine.XR.XRSettings.renderViewportScale = scale; void OnResetDefaults() => Debug.Log("Defaults restored"); void SetQuality(string level, Toggle t) { if (t.isOn) QualitySettings.SetQualityLevel(System.Array.IndexOf( QualitySettings.names, level)); } void Update() { // Toggle menu with controller B/Y button if (OVRInput.GetDown(OVRInput.Button.Two)) DebugUIBuilder.instance.Show(); else if (OVRInput.GetUp(OVRInput.Button.Two)) DebugUIBuilder.instance.Hide(); } } ``` -------------------------------- ### Save and Load Spatial Anchors Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Demonstrates saving a new spatial anchor at the controller's current pose and loading previously saved anchors by UUID. Requires OVRSpatialAnchor and Anchor components on the prefab. ```csharp public class AnchorSessionManager : MonoBehaviour { [SerializeField] private SpatialAnchorLoader _loader; [SerializeField] private OVRSpatialAnchor _anchorPrefab; async void Start() { // --- Saving a new anchor at the controller's current pose --- var controllerPos = OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch); var controllerRot = OVRInput.GetLocalControllerRotation(OVRInput.Controller.RTouch); var newAnchor = Instantiate(_anchorPrefab, controllerPos, controllerRot); // Wait for anchor creation to complete while (newAnchor.PendingCreation) await System.Threading.Tasks.Task.Yield(); var saveResult = await newAnchor.SaveAnchorAsync(); if (saveResult.Success) { AnchorUuidStore.Add(newAnchor.Uuid); Debug.Log($ ``` -------------------------------- ### Apply Grayscale and Tint to Passthrough Layer Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Demonstrates direct API usage for passthrough layer styling, including grayscale conversion and edge tinting. Ensure the device supports color passthrough before applying color adjustments. ```csharp // Attach PassthroughStyler to a grabbable prop GameObject. // Assign _passthroughLayer (OVRPassthroughLayer), _colorTexture, and _colorLutTexture in Inspector. public class PassthroughDemo : MonoBehaviour { [SerializeField] private OVRPassthroughLayer passthroughLayer; void Start() { // --- Direct API usage without the grabbable prop --- // Apply grayscale look: reduce saturation to -1 passthroughLayer.SetBrightnessContrastSaturation( brightness: 0.0f, contrast: 0.0f, saturation: -1.0f); // -1 = fully desaturated // Tint the edge rendering yellow at 50% opacity passthroughLayer.edgeRenderingEnabled = true; passthroughLayer.edgeColor = new Color(1f, 1f, 0f, 0.5f); // Apply a LUT texture for a stylized look (e.g. warm vintage filter) Texture2D lutTexture = Resources.Load("WarmLUT"); var colorLut = new OVRPassthroughColorLut(lutTexture); passthroughLayer.SetColorLut(colorLut, blendFactor: 0.8f); // Check device capability before using color features if (!OVRManager.GetPassthroughCapabilities().SupportsColorPassthrough) { Debug.LogWarning("Device only supports black-and-white passthrough."); passthroughLayer.SetBrightnessContrastSaturation(0, 0, -1); } } } // Expected: passthrough video feed is tinted/styled as specified; on monochrome // devices, only brightness/contrast changes are honored. ``` -------------------------------- ### Control Touch Pro Per-Zone Haptic Feedback Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Attach this script to a scene GameObject and set the m_handedness in the Inspector. It maps thumb-rest pressure, index trigger squeeze, and hand trigger squeeze to the Thumb, Index, and Hand haptic zones respectively. Each zone activates at full amplitude when its corresponding input exceeds 0.5. ```csharp // Attach LocalizedHaptics to any scene GameObject. // Set m_handedness in the Inspector (LeftHanded or RightHanded). public class HapticsDemo : MonoBehaviour { [SerializeField] private OVRInput.Controller controller = OVRInput.Controller.RTouch; void Update() { // Thumb zone: driven by thumb-rest pressure (Touch Pro only) float thumbForce = OVRInput.Get(OVRInput.Axis1D.PrimaryThumbRestForce, controller); OVRInput.SetControllerLocalizedVibration( OVRInput.HapticsLocation.Thumb, frequency: 0f, amplitude: thumbForce > 0.5f ? 1f : 0f, controller); // Index zone: driven by index trigger squeeze float indexTrigger = OVRInput.Get(OVRInput.Axis1D.PrimaryIndexTrigger, controller); OVRInput.SetControllerLocalizedVibration( OVRInput.HapticsLocation.Index, frequency: 0f, amplitude: indexTrigger > 0.5f ? 1f : 0f, controller); // Hand/grip zone: driven by hand trigger squeeze float handTrigger = OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, controller); OVRInput.SetControllerLocalizedVibration( OVRInput.HapticsLocation.Hand, frequency: 0f, amplitude: handTrigger > 0.5f ? 1f : 0f, controller); } } // Expected: each part of the Touch Pro controller rumbles independently // in response to the corresponding physical input being pressed past half-way. ``` -------------------------------- ### Query RayTool State for Far-Field Interaction Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Query the state of RayTool from another script to determine user input actions like pinching. IsFarFieldTool indicates if the tool is configured for far-field interaction. ```csharp public class FarFieldUI : MonoBehaviour { [SerializeField] private RayTool _rayTool; void Update() { // Check whether the user is currently pinching on a focused interactable switch (_rayTool.ToolInputState) { case ToolInputState.PrimaryInputDown: Debug.Log("Pinch started on focused object"); break; case ToolInputState.PrimaryInputDownStay: Debug.Log("Pinch held"); break; case ToolInputState.PrimaryInputUp: Debug.Log("Pinch released — action confirmed"); break; case ToolInputState.Inactive: break; } // IsFarFieldTool == true; cone angle and max distance configurable in Inspector Debug.Log($"Is far-field tool: {_rayTool.IsFarFieldTool}"); } } ``` -------------------------------- ### Animated Touch Controller Hand Visuals with OVRInput Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Drives a skinned-mesh hand's animator layers based on live OVRInput axis and near-touch data. Manages collision enablement and hides renderers when Oculus Dash captures input focus. ```csharp // Attach Hand.cs to the OVRGrabberLeft/Right GameObject. // Assign m_controller, m_animator, and m_defaultGrabPose in the Inspector. [RequireComponent(typeof(OVRGrabber))] public class Hand : MonoBehaviour { // Inspector-assigned fields [SerializeField] private OVRInput.Controller m_controller = OVRInput.Controller.LTouch; [SerializeField] private Animator m_animator; [SerializeField] private HandPose m_defaultGrabPose; void Update() { // Reads index near-touch to drive "Point" animation layer bool isPointing = !OVRInput.Get(OVRInput.NearTouch.PrimaryIndexTrigger, m_controller); // Reads hand trigger to decide whether physics colliders should be active float flex = OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, m_controller); // CollisionEnable(flex >= Hand.THRESH_COLLISION_FLEX); // handled internally // Drive the Flex blend-tree parameter directly m_animator.SetFloat(Animator.StringToHash("Flex"), flex); // Drive pinch for index curl float pinch = OVRInput.Get(OVRInput.Axis1D.PrimaryIndexTrigger, m_controller); m_animator.SetFloat("Pinch", pinch); } } // Expected: hand mesh smoothly transitions between open, point, thumbs-up, and fist poses // in sync with physical controller inputs. ``` -------------------------------- ### Erase Spatial Anchor Source: https://context7.com/oculus-samples/unity-startersamples/llms.txt Asynchronously erases a spatial anchor from persistent storage and removes its UUID from the store. The anchor's GameObject is then destroyed. ```csharp async void EraseAnchor(OVRSpatialAnchor anchor) { var result = await anchor.EraseAnchorAsync(); if (result.Success) { AnchorUuidStore.Remove(anchor.Uuid); Destroy(anchor.gameObject); Debug.Log("Anchor erased from persistent storage"); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.