PageSourceSearch

https://engine.needle.tools/docs/assets/duplicatable.html-BNXR6BAq.js

js needle.tools collected 2026-10-02 11:05:39 UTC 40,019 bytes, 71 lines download raw bytes

1import{_ as t,c as n,a as s,g as e,i as l,h,o as p}from"./app-DqiSUqwL.js";const k={};function r(o,i){const a=h("video-embed");return p(),n("div",null,[i[0]||(i[0]=s("h1",{id:"duplicate-objects-by-dragging",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#duplicate-objects-by-dragging"},[s("span",null,"Duplicate Objects by Dragging")])],-1)),i[1]||(i[1]=s("p",null,"Create interactive experiences where users can spawn copies of objects by clicking and dragging.",-1)),e(a,{src:"/docs/videos/duplicatable.mp4",autoplay:"",muted:""}),i[2]||(i[2]=l(`<div class="hint-container tip"><p class="hint-container-title">Works with Unity and Blender</p><p>The Duplicatable component is available for both Unity and Blender integrations.</p></div><h2 id="what-you-can-do" tabindex="-1"><a class="header-anchor" href="#what-you-can-do"><span>What You Can Do</span></a></h2><ul><li><strong>Drag to Duplicate</strong> - Users click and drag to create a copy that follows their cursor</li><li><strong>Automatic Networking</strong> - Duplicated objects sync across all connected users</li><li><strong>Rate Limiting</strong> - Prevent spam by limiting how many objects can be created</li><li><strong>Custom Templates</strong> - Define what object gets duplicated</li><li><strong>Works with DragControls</strong> - Automatically integrates with object dragging</li></ul><p>Perfect for:</p><ul><li>Object placement tools</li><li>Building and construction games</li><li>Collaborative design spaces</li><li>Inventory systems where items spawn</li><li>Furniture configurators</li></ul><h2 id="quick-start" tabindex="-1"><a class="header-anchor" href="#quick-start"><span>Quick Start</span></a></h2><h3 id="basic-setup" tabindex="-1"><a class="header-anchor" href="#basic-setup"><span>Basic Setup</span></a></h3><p><strong>In Unity or Blender:</strong></p><ol><li>Create an object you want to duplicate (e.g., a cube)</li><li>Add a <code>Duplicatable</code> component to it</li><li>The component automatically sets up the object as a template</li><li>Export and open in browser</li><li>Click and drag the object - a copy spawns and follows your cursor!</li></ol><h3 id="with-multiplayer" tabindex="-1"><a class="header-anchor" href="#with-multiplayer"><span>With Multiplayer</span></a></h3><p>Share duplicated objects with other users:</p><ol><li>Add <code>SyncedRoom</code> component to your scene</li><li>The Duplicatable component automatically adds networking</li><li>When users click and create objects, everyone sees them</li></ol><h2 id="settings" tabindex="-1"><a class="header-anchor" href="#settings"><span>Settings</span></a></h2><table><thead><tr><th>Setting</th><th>What it does</th></tr></thead><tbody><tr><td><strong>Object</strong></td><td>The object to duplicate (leave empty to duplicate this object)</td></tr><tr><td><strong>Parent</strong></td><td>Where duplicates are parented (leave empty to use this object&#39;s parent)</td></tr><tr><td><strong>Limit Count</strong></td><td>Max objects that can be created per 60 seconds (prevents spam)</td></tr></tbody></table><h2 id="how-it-works" tabindex="-1"><a class="header-anchor" href="#how-it-works"><span>How It Works</span></a></h2><p>When you add Duplicatable to an object:</p><ol><li>The component creates a hidden template copy</li><li>When you click and drag, a new instance spawns from the template</li><li>The new object follows your cursor as you drag</li><li>If networking is enabled, the object syncs to other users</li><li>The template stays hidden and ready for the next duplication</li></ol><h2 id="examples" tabindex="-1"><a class="header-anchor" href="#examples"><span>Examples</span></a></h2><h3 id="furniture-spawner" tabindex="-1"><a class="header-anchor" href="#furniture-spawner"><span>Furniture Spawner</span></a></h3><p>Create a palette of furniture users can place:</p><ol><li>Create furniture objects (chair, table, lamp)</li><li>Add <code>Duplicatable</code> to each one</li><li>Arrange them in a palette/toolbar area</li><li>Set <strong>Limit Count</strong> to <code>10</code> to prevent spam</li><li>Users click and drag to create and place furniture</li></ol><h3 id="building-blocks" tabindex="-1"><a class="header-anchor" href="#building-blocks"><span>Building Blocks</span></a></h3><p>Let users build with blocks:</p><ol><li>Create a block object</li><li>Add <code>Duplicatable</code> component</li><li>Add <code>DragControls</code> (automatically configured)</li><li>Set drag mode to snap to grid</li><li>Users click and drag to create blocks and build structures</li></ol><h3 id="inventory-system" tabindex="-1"><a class="header-anchor" href="#inventory-system"><span>Inventory System</span></a></h3><p>Spawn items from an inventory:</p><ol><li>Create item templates (tools, equipment, etc.)</li><li>Add <code>Duplicatable</code> to each</li><li>Set <strong>Parent</strong> to a &quot;world items&quot; container</li><li>Display items in UI or palette</li><li>Click items to spawn them into the scene</li></ol><h3 id="collaborative-object-spawning" tabindex="-1"><a class="header-anchor" href="#collaborative-object-spawning"><span>Collaborative Object Spawning</span></a></h3><p>Multiple users adding objects together:</p><ol><li>Add <code>SyncedRoom</code> component</li><li>Create object templates with <code>Duplicatable</code></li><li>Each template automatically gets <code>SyncedTransform</code></li><li>Users spawn and place objects collaboratively</li><li>Everyone sees the same scene in real-time</li></ol><h2 id="scripting" tabindex="-1"><a class="header-anchor" href="#scripting"><span>Scripting</span></a></h2><h3 id="duplicate-programmatically" tabindex="-1"><a class="header-anchor" href="#duplicate-programmatically"><span>Duplicate Programmatically</span></a></h3><p>Trigger duplication from code without user click:</p><div class="language-ts" data-highlighter="shiki" data-ext="ts" style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;--shiki-light-bg:#FAFAFA;--shiki-dark-bg:#263238;"><pre class="shiki shiki-themes one-light material-theme vp-code"><code class="language-ts"><span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">
1import</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> GameObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> }</span><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;"> from</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;"> &quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">@needle-tools/engine</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
2<span class="line"></span>
3<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">export</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> class</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> ObjectSpawner</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> extends</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
4<span class="line"></span>
5<span class="line"><span style="--shiki-light:#4078F2;--shiki-dark:#F07178;">    start</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">()</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
6<span class="line"><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;">        const</span><span style="--shiki-light:#986801;--shiki-dark:#EEFFFF;"> duplicatable</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> =</span><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;"> this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">gameObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">getComponent</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">Duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
7<span class="line"></span>
8<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">        if</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;"> (</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">duplicatable</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> &amp;&amp;</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;"> duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">[</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">handleDuplication</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">]) </span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">{</span></span>
9<span class="line"><span style="--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;">            // Spawn a copy</span></span>
10<span class="line"><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;">            const</span><span style="--shiki-light:#986801;--shiki-dark:#EEFFFF;"> newObject</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> =</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;"> duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">[</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">handleDuplication</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">]()</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
11<span class="line"></span>
12<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">            if</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;"> (</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">newObject</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">) </span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">
12{</span></span>
13<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">                console</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">log</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">Spawned:</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;"> newObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">name</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
14<span class="line"></span>
15<span class="line"><span style="--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;">                // Customize the spawned object</span></span>
16<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">                newObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">position</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">set</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#986801;--shiki-dark:#F78C6C;">0</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#986801;--shiki-dark:#F78C6C;"> 1</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#986801;--shiki-dark:#F78C6C;"> 0</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
17<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">            }</span></span>
18<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">        }</span></span>
19<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">    }</span></span>
20<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">}</span></span></code></pre></div><div class="hint-container warning"><p class="hint-container-title">Private Method</p><p>The <code>handleDuplication</code> method is private. The recommended way is to let users click the object naturally. Use this approach only for advanced cases.</p></div><h3 id="custom-duplication-logic" tabindex="-1"><a class="header-anchor" href="#custom-duplication-logic"><span>Custom Duplication Logic</span></a></h3><p>Create your own duplication system:</p><div class="language-ts" data-highlighter="shiki" data-ext="ts" style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;--shiki-light-bg:#FAFAFA;--shiki-dark-bg:#263238;"><pre class="shiki shiki-themes one-light material-theme vp-code"><code class="language-ts"><span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">import</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> GameObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> serializable</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> }</span><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;"> from</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;"> &quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">@needle-tools/engine</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
21<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">
21import</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Object3D</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> }</span><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;"> from</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;"> &quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">three</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
22<span class="line"></span>
23<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">export</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> class</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> CustomDuplicator</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> extends</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
24<span class="line"></span>
25<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">    @</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">serializable</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">(Object3D)</span></span>
26<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">    template</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;">?:</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> Object3D</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
27<span class="line"></span>
28<span class="line"><span style="--shiki-light:#4078F2;--shiki-dark:#F07178;">    onPointerClick</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">()</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
29<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">        if</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;"> (</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;">!</span><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;">this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">template</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">) </span><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">return</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
30<span class="line"></span>
31<span class="line"><span style="--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;">        // Clone the template</span></span>
32<span class="line"><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;">        const</span><span style="--shiki-light:#986801;--shiki-dark:#EEFFFF;"> clone</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> =</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;"> GameObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">instantiateSynced</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;">this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">template</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
33<span class="line"><span style="--shiki-light:#E45649;--shiki-dark:#F07178;">            parent</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;">:</span><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;"> this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">gameObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span></span>
34<span class="line"><span style="--shiki-light:#E45649;--shiki-dark:#F07178;">            position</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;">:</span><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;"> this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">worldPosition</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span></span>
35<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">        }</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
36<span class="line"></span>
37<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">        if</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;"> (</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">clone</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">) </span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">
37{</span></span>
38<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">            console</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">log</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">Created custom duplicate:</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;"> clone</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">name</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
39<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">        }</span></span>
40<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">    }</span></span>
41<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">}</span></span></code></pre></div><h3 id="check-duplicate-count" tabindex="-1"><a class="header-anchor" href="#check-duplicate-count"><span>Check Duplicate Count</span></a></h3><p>Monitor how many objects have been created:</p><div class="language-ts" data-highlighter="shiki" data-ext="ts" style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;--shiki-light-bg:#FAFAFA;--shiki-dark-bg:#263238;"><pre class="shiki shiki-themes one-light material-theme vp-code"><code class="language-ts"><span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">import</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> }</span><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;"> from</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;"> &quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">@needle-tools/engine</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
42<span class="line"></span>
43<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">export</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> class</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> DuplicateMonitor</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> extends</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
44<span class="line"></span>
45<span class="line"><span style="--shiki-light:#4078F2;--shiki-dark:#F07178;">    update</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">()</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
46<span class="line"><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;">        const</span><span style="--shiki-light:#986801;--shiki-dark:#EEFFFF;"> duplicatable</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> =</span><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;"> this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">gameObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">getComponent</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">
46Duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
47<span class="line"></span>
48<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">        if</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;"> (</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">) </span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">{</span></span>
49<span class="line"><span style="--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;">            // Access internal counter (private, for debugging)</span></span>
50<span class="line"><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;">            const</span><span style="--shiki-light:#986801;--shiki-dark:#EEFFFF;"> count</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> =</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;"> duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">[</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">_currentCount</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">]</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
51<span class="line"><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;">            const</span><span style="--shiki-light:#986801;--shiki-dark:#EEFFFF;"> limit</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> =</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;"> duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">limitCount</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
52<span class="line"></span>
53<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">            console</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">log</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">\`</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">Created: </span><span style="--shiki-light:#CA1243;--shiki-dark:#89DDFF;">\${</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">count</span><span style="--shiki-light:#CA1243;--shiki-dark:#89DDFF;">}</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">/</span><span style="--shiki-light:#CA1243;--shiki-dark:#89DDFF;">\${</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">limit</span><span style="--shiki-light:#CA1243;--shiki-dark:#89DDFF;">}</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">\`</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
54<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">        }</span></span>
55<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">    }</span></span>
56<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">}</span></span></code></pre></div><h3 id="customize-spawned-objects" tabindex="-1"><a class="header-anchor" href="#customize-spawned-objects"><span>Customize Spawned Objects</span></a></h3><p>Modify objects right after they&#39;re created:</p><div class="language-ts" data-highlighter="shiki" data-ext="ts" style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;--shiki-light-bg:#FAFAFA;--shiki-dark-bg:#263238;"><pre class="shiki shiki-themes one-light material-theme vp-code"><code class="language-ts"><span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">
56import</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">,</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;"> Duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> }</span><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;"> from</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;"> &quot;</span><span style="--shiki-light:#50A14F;--shiki-dark:#C3E88D;">@needle-tools/engine</span><span style="--shiki-light:#50A14F;--shiki-dark:#89DDFF;">&quot;</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
57<span class="line"></span>
58<span class="line"><span style="--shiki-light:#A626A4;--shiki-light-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;">export</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> class</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> CustomizeSpawned</span><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;"> extends</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> Behaviour</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
59<span class="line"></span>
60<span class="line"><span style="--shiki-light:#A626A4;--shiki-dark:#C792EA;">    private</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;"> duplicatable</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;">?:</span><span style="--shiki-light:#C18401;--shiki-dark:#FFCB6B;"> Duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
61<span class="line"></span>
62<span class="line"><span style="--shiki-light:#4078F2;--shiki-dark:#F07178;">    awake</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">()</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
63<span class="line"><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;">        this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">duplicatable</span><span style="--shiki-light:#0184BC;--shiki-dark:#89DDFF;"> =</span><span style="--shiki-light:#E45649;--shiki-dark:#89DDFF;"> this</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#E45649;--shiki-dark:#EEFFFF;">gameObject</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">.</span><span style="--shiki-light:#4078F2;--shiki-dark:#82AAFF;">getComponent</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">(</span><span style="--shiki-light:#383A42;--shiki-dark:#EEFFFF;">Duplicatable</span><span style="--shiki-light:#383A42;--shiki-dark:#F07178;">)</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">;</span></span>
64<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">    }</span></span>
65<span class="line"></span>
66<span class="line"><span style="--shiki-light:#4078F2;--shiki-dark:#F07178;">    update</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">()</span><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;"> {</span></span>
67<span class="line"><span style="--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;">        // Watch for DragControls being created on new objects</span></span>
68<span class="line"><span style="--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;">        // This happens right after duplication</span></span>
69<span class="line"><span style="--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;">        // You can then customize the newly spawned object</span></span>
70<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">    }</span></span>
71<span class="line"><span style="--shiki-light:#383A42;--shiki-dark:#89DDFF;">}</span></span></code></pre></div><h2 id="advanced-features" tabindex="-1"><a class="header-anchor" href="#advanced-features"><span>Advanced Features</span></a></h2><h3 id="automatic-dragcontrols" tabindex="-1"><a class="header-anchor" href="#automatic-dragcontrols"><span>Automatic DragControls</span></a></h3><p>When Duplicatable creates an object:</p><ul><li>Automatically adds <code>DragControls</code> if not present</li><li>Sets drag mode to <code>SnapToSurfaces</code> by default</li><li>User can immediately drag the new object</li><li>No additional setup needed</li></ul><h3 id="automatic-networking" tabindex="-1"><a class="header-anchor" href="#automatic-networking"><span>Automatic Networking</span></a></h3><p>When <code>SyncedRoom</code> is present:</p><ul><li>Uses <code>GameObject.instantiateSynced()</code> automatically</li><li>Adds <code>SyncedTransform</code> to spawned objects</li><li>All users see duplicated objects</li><li>Position and rotation sync in real-time</li></ul><h3 id="rate-limiting" tabindex="-1"><a class="header-anchor" href="#rate-limiting"><span>Rate Limiting</span></a></h3><p>Prevents users from creating too many objects:</p><ul><li><strong>
71Limit Count</strong> controls max objects per minute</li><li>Counter decrements by 1 every second</li><li>When limit is reached, clicks are ignored</li><li>Warning logged to console</li><li>Automatically resets over time</li></ul><h3 id="template-system" tabindex="-1"><a class="header-anchor" href="#template-system"><span>Template System</span></a></h3><p>The object to duplicate becomes a hidden template:</p><ul><li>Original object is hidden (<code>visible = false</code>)</li><li>Template preserves initial position and rotation</li><li>Each click spawns from the template</li><li>Template never appears in the scene</li></ul><h2 id="common-questions" tabindex="-1"><a class="header-anchor" href="#common-questions"><span>Common Questions</span></a></h2><p><strong>What happens to the original object?</strong> The original becomes a hidden template. The first duplicate you see is actually a copy, not the original.</p><p><strong>Can I duplicate objects without DragControls?</strong> The component expects DragControls and adds it automatically. If you don&#39;t want dragging, disable DragControls on the spawned object via script.</p><p><strong>How do I change what object gets duplicated?</strong> Set the <strong>Object</strong> field to a different object. If left empty, the object with the Duplicatable component is used.</p><p><strong>Can I duplicate objects with animations or scripts?</strong> Yes! The entire hierarchy and all components are copied. Scripts, animations, materials - everything is duplicated.</p><p><strong>What&#39;s the difference between Duplicatable and instantiate?</strong> Duplicatable is for user interaction (clicking to spawn). <code>GameObject.instantiate()</code> is for programmatic spawning in code.</p><p><strong>How do I increase the spawn limit?</strong> Change <strong>Limit Count</strong> to a higher number. Default is 60 objects per minute. Set to 0 for unlimited (not recommended).</p><p><strong>Does it work with physics?</strong> Yes! Duplicated objects keep their Rigidbody components and physics properties.</p><h2 id="common-issues" tabindex="-1"><a class="header-anchor" href="#common-issues"><span>Common Issues</span></a></h2><p><strong>Objects spawn at wrong position:</strong> Make sure the template object starts at the correct position. The Duplicatable stores the initial position when the scene loads.</p><p><strong>Can&#39;t create any objects:</strong> Check if you&#39;ve hit the <strong>Limit Count</strong>. Wait a few seconds and try again, or increase the limit.</p><p><strong>Objects don&#39;t appear for other users:</strong> Ensure you have <code>SyncedRoom</code> in your scene for networking to work.</p><p><strong>Duplicated object is missing components:</strong> Check if components are being destroyed in <code>start()</code> or <code>awake()</code>. Some components remove themselves on instantiation.</p><h2 id="more-information" tabindex="-1"><a class="header-anchor" href="#more-information"><span>More Information</span></a></h2><p><strong>Live Example:</strong></p><ul><li><a href="https://engine.needle.tools/samples/collaborative-sandbox/" target="_blank" rel="noopener noreferrer">Collaborative Sandbox</a> - Multi-user building with duplication and dragging</li></ul><p><strong>API Documentation:</strong></p><ul><li><a href="https://engine.needle.tools/docs/api/Duplicatable" target="_blank" rel="noopener noreferrer">Duplicatable API</a> - Complete technical reference</li></ul><p><strong>Related Components:</strong></p><ul><li><a href="/docs/how-to-guides/components/drag-controls">DragControls</a> - Drag and move objects</li><li><a href="/docs/reference/components#deletable">Deletable</a> - Delete spawned objects</li><li><a href="/docs/reference/components#syncedtransform">SyncedTransform</a> - Network synchronization</li></ul>`,77))])}const c=t(k,[["render",r]]),F=JSON.parse('{"path":"/how-to-guides/components/duplicatable.html","title":"Duplicate Objects by Dragging (Duplicatable)","lang":"en-US","frontmatter":{"title":"Duplicate Objects by Dragging (Duplicatable)","description":"Let users create copies of objects by dragging them with the Duplicatable component. Works in Unity and Blender with multiplayer support.","head":[["link",{"rel":"canonical","href":"https://engine.needle.tools/docs/how-to-guides/components/duplicatable.html"}],["meta",{"name":"og:image","content":"https://engine.needle.tools/docs/imgs/default-unfurl-image-2.webp"}],["meta",{"name":"og:description","content":"Let users create copies of objects by dragging them with the Duplicatable component. Works in Unity and Blender with multiplayer support."}],["meta",{"property":"og:title","content":"Duplicate Objects by Dragging (Duplicatable) — Needle Engine"}]]}
71,"git":{"updatedTime":1769604971000,"contributors":[{"name":"Marcel Wiessler","username":"","email":"[email protected]","commits":1}],"changelog":[{"hash":"fc2e9a85ae5b565ab70d20b53454d6e7f5d166c3","time":1769604971000,"email":"[email protected]","author":"Marcel Wiessler","message":"add some component guides"}]},"filePathRelative":"how-to-guides/components/duplicatable.md"}');export{c as comp,F as data};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.