如何在网站指定Div中嵌入多个PlayCanvas应用并实现事件控制?
Hey there! Let's walk through exactly how to embed two separate PlayCanvas apps into specific div containers on your website, and how to interact with them to trigger events like your btn_doSomething.addE... example.
Step 1: Set Up Your HTML Containers
First, create two unique divs in your website's HTML where you want each PlayCanvas app to live. Give them distinct IDs so you can target them later:
<!-- Container for first PlayCanvas app --> <div id="playcanvas-app-1" style="width: 800px; height: 600px; border: 1px solid #ccc;"></div> <!-- Container for second PlayCanvas app --> <div id="playcanvas-app-2" style="width: 800px; height: 600px; border: 1px solid #ccc; margin-top: 20px;"></div> <!-- Example buttons to trigger app events --> <button id="trigger-app1-action">Trigger App 1 Action</button> <button id="trigger-app2-action">Trigger App 2 Action</button>
Make sure to set explicit width/height for the containers—this ensures the PlayCanvas canvas renders correctly.
Step 2: Modify PlayCanvas Build Scripts
When you build a PlayCanvas app, you'll get a __start__.js file. We need to tweak this for each app to:
- Mount the canvas to your target div instead of the body
- Expose the app instance to the global scope so your website can access it
For App 1's __start__.js:
Replace the default canvas creation code with this:
// Target the first container const container = document.getElementById('playcanvas-app-1'); const canvas = document.createElement('canvas'); container.appendChild(canvas); // Create the app and expose it globally as app1 window.app1 = new pc.Application(canvas, { elementInput: new pc.ElementInput(canvas), mouse: new pc.Mouse(canvas), touch: 'ontouchstart' in window ? new pc.TouchDevice(canvas) : null, keyboard: new pc.Keyboard(window) }); // Keep the rest of the original build code (app.start(), asset loading, etc.)
For App 2's __start__.js:
Do the same, but target the second container and use a unique global name:
const container = document.getElementById('playcanvas-app-2'); const canvas = document.createElement('canvas'); container.appendChild(canvas); // Expose as app2 to avoid conflicts window.app2 = new pc.Application(canvas, { elementInput: new pc.ElementInput(canvas), mouse: new pc.Mouse(canvas), touch: 'ontouchstart' in window ? new pc.TouchDevice(canvas) : null, keyboard: new pc.Keyboard(window) }); // Keep the rest of the original build code
Step 3: Access App Instances & Trigger Events
Now you can interact with both apps from your website's custom JavaScript. For example, to trigger an event on a specific entity in either app:
// Trigger action in App 1 document.getElementById('trigger-app1-action').addEventListener('click', () => { // Find the target entity by name (use tags or IDs for more reliability) const targetEntity = app1.root.findByName('btn_doSomething'); if (targetEntity) { // Fire a custom event that the entity's script listens for targetEntity.fire('doSomething'); // Or call a method directly on the entity's script component const script = targetEntity.script.btn_doSomething; if (script) { script.yourCustomMethod(); } } }); // Trigger action in App 2 document.getElementById('trigger-app2-action').addEventListener('click', () => { const targetEntity = app2.root.findByName('anotherControlEntity'); if (targetEntity) { targetEntity.fire('app2-custom-event'); } });
Step 4: Ensure Apps Are Ready Before Interacting
Wait until each app finishes initializing before trying to access it. Add this to each app's __start__.js after app.start():
// For App 1 app1.once('initialize', () => { console.log('App 1 is fully ready!'); // Notify your website the app is ready window.dispatchEvent(new CustomEvent('app1-ready')); }); // For App 2 app2.once('initialize', () => { console.log('App 2 is fully ready!'); window.dispatchEvent(new CustomEvent('app2-ready')); });
Then in your website's JS, wait for these events:
window.addEventListener('app1-ready', () => { // Safe to interact with app1 now }); window.addEventListener('app2-ready', () => { // Safe to interact with app2 now });
Common Pitfalls to Avoid
- Global Variable Conflicts: Never use the same variable name (like
app) for both apps—stick to unique names likeapp1andapp2. - DOM Loading Order: Load your PlayCanvas scripts after the div containers exist in the DOM (put script tags at the end of the
<body>or wrap code inDOMContentLoaded). - CORS Issues: If your PlayCanvas assets are hosted externally, make sure CORS is enabled on the asset server.
内容的提问来源于stack exchange,提问作者Patrick Münster

