Inspiration
In many virtual worlds, lighting is static and lifeless. We were inspired by real-world smart home technology (like Philips Hue) and professional stage lighting controls. We wanted to give creators and players the power to change the mood and atmosphere of a space in real-time, directly within VR. Instead of a light just being a prop, we wanted to turn it into a dynamic tool for expression and interaction.
What it does
The Interactive Lamp is a fully functional, grabbable, and highly customizable light source for Horizon Worlds. A player can pick up the lamp and use their controller to:
- Toggle Power: Turn the light on and off with a simple click of the index trigger.
- Live-Edit Properties: Cycle through a menu of settings—including Hue, Saturation, Value, Intensity, Falloff Distance, and Spread—using the A/X button.
- Fine-Tune Values: Adjust the currently selected setting by holding the B/Y button.
- Activate Auto-Mode: A long-press on the trigger activates a beautiful, color-cycling "Auto Mode" that smoothly animates every property of the light for a dynamic ambiance.
- Get Instant Feedback: All current settings are displayed on an attached Text Gizmo, which updates in real-time, serving as a user-friendly UI.
- Auto-Return: If dropped or left behind, the lamp will automatically return to its original position, making it a reliable world asset.
How we built it
The project was built entirely within the Horizon Worlds platform, combining in-world objects with a powerful TypeScript script.
- Core Components: The lamp is built from a parent
Entity(made grabbable and physical), a childDynamicLightGizmo(the light source), and a childTextGizmo(the UI panel). - The Brain (TypeScript): The
lamp.tsscript is the heart of the project. It usespropsDefinitionto create links to the light and text gizmos, allowing the code to control objects in the scene. - Event Handling: We used
connectCodeBlockEventto listen for player inputs likeOnIndexTriggerDown,OnButton1Down, etc. This allows the script to react to the player's actions. - The Update Loop: A central function,
onLight(), is responsible for taking all the script's internal variables (likeIntensity,Hue, etc.) and applying them to theDynamicLightGizmo's properties using the API. This function is called every time a setting is changed, ensuring the light instantly reflects the new state. - Animation: The "Auto Mode" is powered by an
async.setTimeoutloop that repeatedly calls itself, slightly changing the light's properties each time to create a smooth, continuous animation.
Challenges we ran into
- Complex Input Logic: Differentiating between a short press (toggle on/off) and a long press (toggle Auto Mode) on the same button required careful state management and the use of timers to detect how long the trigger was held.
- UI in VR: Creating an intuitive menu system without traditional UI elements was a challenge. We landed on the "cycle-and-adjust" method using two buttons, which proved to be very user-friendly in VR. The real-time text feedback was crucial for making this work.
- State Management: Juggling seven different editable properties and ensuring they looped correctly without going out of bounds required careful use of the modulo (
%) operator and clear variable management.
Accomplishments that we're proud of
- An Intuitive Control Scheme: We are proud of the single-trigger, dual-functionality (short vs. long press) that feels natural and easy to learn.
- Creating an In-World "Property Editor": We successfully built a tool that allows players to edit the properties of an object in real-time, effectively creating a mini-editor within the world itself.
- The "Auto Mode" Effect: The final color-cycling animation is visually stunning and demonstrates the power of simple, recursive functions for creating complex effects.
- Modularity: The final product is a completely self-contained, drag-and-drop asset that other creators can use in their own worlds with minimal setup.
What we learned
This project was a deep dive into the DynamicLightGizmo API. We learned how to manipulate every scriptable property of a light source, from its on/off state to its color and shape. We also gained significant experience in advanced event handling, creating intuitive VR user interfaces with limited tools, and managing complex states within a script. Most importantly, it solidified our understanding of how to bridge the gap between editor-placed objects and dynamic, scripted behavior.
What's next for the Interactive Lamp
We see a lot of potential for expanding this concept:
- Color Presets: Add a new setting to cycle through pre-saved color schemes like "Sunset," "Forest," "Cyberpunk," etc.
- Audio Reactivity: Integrate the lamp with the audio system so it can pulse or change color in time with world music.
- World Triggers: Allow the lamp to be controlled by other world events, such as a player entering a specific area or completing a task.
Built With
- horizonworlds
- typescript


Log in or sign up for Devpost to join the conversation.