Drag and Drop Files into Your Scene
Let users drag and drop 3D models directly into your web experience.
Works with Unity and Blender
The DropListener component is available for both Unity and Blender integrations.
What You Can Do
- Drag Files - Users drag glTF, GLB, FBX, OBJ, USDZ, or VRM files into the browser
- Paste URLs - Users paste links to 3D models
- Auto-Place - Dropped objects appear where users drop them
- Auto-Scale - Make all dropped objects fit a consistent size
- Multiplayer - Share dropped files with other connected users
- Drop Zones - Only allow drops in specific areas
Quick Start
Basic Setup
In Unity or Blender:
- Add a
DropListenercomponent to an object in your scene - Export and open in browser
- Drag a 3D model file into the browser window
The model appears in your scene!
With Multiplayer
To share dropped files with other users:
- Add a
SyncedRoomcomponent to your scene - Enable Use Networking on the DropListener
- When someone drops a file, everyone sees it
Settings
| Setting | What it does |
|---|---|
| Drop Area | Only accept drops on this specific mesh (leave empty for anywhere) |
| Fit Into Volume | Automatically resize dropped objects to fit a size |
| Fit Volume Size | The size to fit objects into (like 2×2×2) |
| Place At Hit Position | Drop objects where the cursor hits, or at a fixed spot |
| Use Networking | Share dropped files with other users |
Examples
Product Viewer
Replace the current product when users drop a new model:
- Add your initial product as a child of the DropListener object
- When users drop a file, it replaces the current product
- Enable Fit Into Volume so all products appear at the same size
Perfect for furniture configurators, product showcases, or avatar try-ons.
Designated Drop Zone
Only allow drops on a specific surface (like a table or platform):
- Create a mesh object (cube, plane, etc.)
- Add the DropListener to a different object
- Assign the mesh to Drop Area
- Files only work when dropped on that mesh
Needs a Mesh
The Drop Area must have visible geometry for drag and drop detection to work.
Multiple Drop Zones
Create multiple independent drop zones, each with its own drop area:
How it works:
- Create two cylinders (or any meshes) as separate drop areas
- Create two DropListener components (can be on separate empty objects)
- Assign the left cylinder to DropListener 1's Drop Area field
- Assign the right cylinder to DropListener 2's Drop Area field
- Each DropListener only responds to drops on its assigned cylinder
In the video above:
- Left cylinder: Drop area for DropListener 1 (displays the helmet)
- Right cylinder: Drop area for DropListener 2 (displays the camera)
- Each has its own independent drop zone
Why this is useful:
- Compare different models side-by-side
- Collaborative review tool - team members drop their designs to compare
- Create before/after comparisons
- Build product comparison tools
- Each drop zone can have different settings (fit size, placement, etc.)
- Multiple independent display areas
Example Setup:
- DropListener 1: Assigned to left cylinder, fits to volume 1×2×1
- DropListener 2: Assigned to right cylinder, fits to volume 2×2×2
- Drop different files on each cylinder to compare them side-by-side
Each cylinder acts as a completely independent drop zone with its own content.
Collaborative Scene Builder
Let multiple users add objects to a shared scene:
- Add
SyncedRoomto your scene - Enable Use Networking on DropListener
- Disable Fit Into Volume if you want original sizes
- Users can drag files and everyone sees them appear
Scripting
React to Drops
Run code when someone drops a file:
import { Behaviour, DropListener, DropListenerEvents } from "@needle-tools/engine";
export class MyComponent extends Behaviour {
awake() {
const dropListener = this.gameObject.getComponent(DropListener);
// When a file is dropped
dropListener.addEventListener(DropListenerEvents.FileDropped, (evt) => {
const file = evt.detail as File;
console.log("User dropped:", file.name);
});
// When an object is added to the scene
dropListener.addEventListener(DropListenerEvents.ObjectAdded, (evt) => {
const object = evt.detail.object;
console.log("New object in scene:", object.name);
// You can modify the object here
// For example, add a glow effect or play a sound
});
}
}Load from Code
Load a model without user interaction:
import { Behaviour, DropListener } from "@needle-tools/engine";
export class ModelLoader extends Behaviour {
async start() {
const dropListener = this.gameObject.getComponent(DropListener);
// Load from URL
const url = "https://example.com/model.glb";
const object = await dropListener.loadFromURL(url);
if (object) {
console.log("Loaded:", object.name);
}
}
}Special Features
Smart URL Handling
DropListener automatically handles special URLs:
- GitHub files - Paste GitHub URLs and they're converted to raw content
- Polyhaven models - Paste Polyhaven asset pages and get the 3D model
Placeholder Behavior
Child objects under the DropListener are treated as placeholders:
- They stay visible until the first drop
- They're automatically removed when a file is dropped
- Perfect for "Drop model here" preview objects
Common Questions
Can users drop multiple files? Currently one file at a time. If multiple files are dropped, only the first 3D model is loaded.
What about images? Images are automatically ignored. The DropListener only accepts 3D model formats.
How does multiplayer work? When enabled, dropped files are uploaded to Needle's server and the URL is shared with other users. They download and see the same object.
Does it work offline? Yes for local file drops. URL pasting and multiplayer require internet connection.
More Information
Live Example:
- DropListener Sample - Try it yourself with multiplayer
API Documentation:
- DropListener API - Complete technical reference
Related Guides:
- Networking & Multiplayer - Set up multiplayer features
- Loading Scenes - Load content dynamically