Hi XR Developers! In today’s post we’re tearing open Cryptic Cabinet, one of Meta’s most ambitious open-source demos. The project is packed with goodies, but we’ll focus on three main systems you can lift straight into your own apps:
- Room-aware object placement powered by MRUK
- Custom interactions overriding Metas’s Interaction SDK
- Dynamic Passthrough effects for environment dimming and mood-switching
Stick around to see how each piece fits together, grab the sample, and ship your game in no time. If this helps, drop a 👍 and subscribe. Hop into our Discord to bounce questions with fellow tinkerers!
🚀 Prerequisites & Setup
What you need | Version / Notes |
---|---|
Meta Quest 3 / 3 S | Horizon OS v77+ |
Unity | ≥ 2022.3.16 LTS, Android build target |
Meta XR Core SDK | v77 (includes MRUK, Passthrough, Anchors, Scene, Platform) |
Photon Fusion | 2.x (free 20 CCU tier is fine) |
Git LFS | Handles large binary assets |
Optional | Meta XR Simulator for device-free iteration |
1. Grab the Code ⬇️
# 1-time install for large file support
git lfs install
# Clone wherever you keep your projects
git clone https://github.com/oculus-samples/Unity-CrypticCabinet.git
Open the newly–cloned folder in Unity Hub, select a 2022.3.16 LTS (or newer) editor, set Platform → Android, and hit Open.
2. Wire Up Meta Platform 🔑
- Meta Developer Center → Create App, and give it a name
- Complete Requirements → Data Use Checkup (User ID + Profile, age group)
- Copy the App ID from Deployment → API
- In Unity: Meta → Platform → Edit Settings → paste ID for both Quest + Rift
- Tick Use Standalone Platform and supply Test User creds for in-Editor login
3. Hook Photon Fusion 🌐
- Sign in at dashboard.photonengine.com → Create App → Fusion
- Copy the generated App ID
- Unity: Fusion → Realtime Settings → paste ID under Fusion section
4. Sign & Upload the APK 📲
Step | Why |
---|---|
Generate Android Keystore | Every Quest APK must be signed |
Unique Package Name & Bundle Version Code | Bump versionCode on every upload |
Meta → Tools → Create store-compatible AndroidManifest.xml | Automates required permissions |
Build Main.unity → .apk | ✔️ |
Quest Developer Hub → App Distribution → choose Organization & Channel | Push the build |
Add testers / org members | Grant entitlement before launch |
That’s it—time to dive into the magic. 🪄
🔍 Feature 1 – MRUK Auto-Placement & Room Setup
Cryptic Cabinet can drop its cupboards, desks, and gizmos exactly where they make sense in your room—no manual fiddling. The workflow:
- Scene scan via MRUK returns walls, floors, desks, etc.
- ObjectPlacementManager orchestrates five passes, largest-to-smallest:
- Floor-against-wall → Walls → Desks → Floors → Any horizontal
- SceneUnderstandingLocationPlacer harvests MRUK anchors and funnels them into dedicated finders:
WallSpaceFinder
,DeskSpaceFinder
,FloorSpaceFinder
- Each finder tiles its surface into a 3-D grid of cells (green = free, red = blocked) with edge-distance metadata.
- Remaining rejects?
RandomlyPlaceFailedObjects
sprinkles them onto valid cells. - The user previews blue (reachable) / green (visible) / red (invalid) boxes and nudges any red stragglers before saving the layout.
Takeaway: MRUK turns raw scene meshes into a semantic playground—just ask for RequestRandomDeskLocation() and you’re golden.
🔧 Feature 2 – “Grab → Insert → Twist” Interactions (Keys & Light-Bulbs)
Cryptic Cabinet’s keyholes and bulb sockets feel exactly like the real thing thanks to a custom transformer trio that blends free-form grabbing with single-axis screwing:
Script | Role |
---|---|
OneGrabToggleRotateTransformer | Swaps between free movement and pivot-locked rotation at runtime |
ScrewSnapZone | Collider that captures an inserted prop, stores it as CurrentObject, and raises events (OnSnap, OnTightened, OnUnscrew, OnRemoved) |
ScrewableObject | Lives on each key/bulb, orchestrates the lock-in, lerps the “screw” motion, and fires completion callbacks |
How It Works 🔩
- OneGrabToggleRotateTransformer starts in “free” mode, mimicking
OneGrabFreeTransformer
, so the prop behaves like any normal grabbable. - Snap-In Detection
The prop’sOnTriggerEnter
with a ScrewSnapZone:
void OnTriggerEnter(Collider other) {
if (other.TryGetComponent(out ScrewSnapZone zone)) {
rb.isKinematic = true; // freeze physics
transformer.LockPosition(zone.transform); // pivot-lock
transformer.ResetRotation();
zone.CurrentObject = this;
}
}
3. Lock & RotateLockPosition = true
freezes translation and activates the transformer’s single-axis mode (like OneGrabRotateTransformer
). The public ConstrainedRelativeAngle
exposes live rotation.
4. Screw Motion & Events
Each frame, ScrewableObject maps ConstrainedRelativeAngle → 0–1
turn percentage, lerping the mesh between start and tight guide poses.
OnScrewComplete fires when the angle exceeds tightThreshold
; OnObjectStartUnscrew fires on the way back.
5. Break-Snap Escape
If the user yanks the prop beyond unlockBreakDistance
, the transformer auto-switches back to free movement and rb.isKinematic = false
, letting the player pull it out naturally.
// Inside Update of ScrewableObject
float pct = transformer.ConstrainedRelativeAngle / maxAngle;
transform.position = Vector3.Lerp(loosePose.position, tightPose.position, pct);
if (!completed && pct >= 1f) { completed = true; OnScrewComplete?.Invoke();
}
🎛️ Feature 3 – Dynamic Passthrough FX
Want an eerie blackout or UV-glow on demand? Cryptic Cabinet blends LUTs and post-processing in perfect sync with gameplay.
Component | Responsibility |
---|---|
PassthroughChanger (singleton) | Toggles m_uvActive / m_darkActive and calls SetPassthroughLut() |
PassthroughConfigurator (NetworkBehaviour) | Holds LUT textures, lerps opacity/contrast/brightness and RPCs them to peers |
BlackoutVolume | When the camera’s inside props, disables renderPostProcessing to avoid seeing through geometry |
// Dark mode 🌑
public void EnableDarkRoom(bool enable) {
SetPassthroughLut(ELutId.DARKER_ROOM, enable ? 1f : 0f);
}
The result: flick a switch and everyone’s environment dims together, sharp and artifact-free.
🧪 Testing Checklist
Host | Guest |
---|---|
Builds & uploads signed APK → release channel | Installs same channel |
Runs scene: verifies MRUK scan, anchor broadcast | Logs show anchor reception, room load |
Flips UV light / blackout | Sees identical Passthrough blend |
If anything drifts, re-scan the room or check that Fusion’s Time Sync Mode is enabled so physics stay deterministic.
🎯 Conclusion
Cryptic Cabinet bundles room-aware placement, bulletproof networking, and theatrical Passthrough in a neat open-source bow. Steal the patterns, tweak the puzzles, and launch your own mixed-reality escape room—no magic incantations required.
Liked the breakdown? Press that Like, hit Subscribe, and swing by Patreon for full source access.
Support XR DEV ROB🐋
Thank you for following this article. Stay tuned for more in-depth and insightful content in the realm of XR development! 🌐 Did this article help you out? Consider supporting me on Patreon, where you can find all the source code, or simply subscribe to my YouTube channel!