# PlayCanvas Developer Documentation - Full Content > This file contains the complete text content of the PlayCanvas documentation. > It is designed for consumption by Large Language Models (LLMs) and AI assistants. Base URL: https://developer.playcanvas.com Total Documents: 484 Generated: 2026-08-03 ================================================================================ ## Welcome URL: https://developer.playcanvas.com/user-manual/ Welcome to the PlayCanvas User Manual. Your exciting journey learning PlayCanvas begins now! [Image: PlayCanvas Demos] Let's [get started](getting-started)! -------------------------------------------------------------------------------- ## 2D URL: https://developer.playcanvas.com/user-manual/2D/ The PlayCanvas Engine is designed to make creating 3D games and applications fast and simple. However, we also support a number of great features for creating 2D games. With PlayCanvas' 2D features you get all the benefits of a powerful 3D engine but for 2D games. ## Basic Features ### Sprites [Image: Sprite] 2D graphics are often known as **Sprites**. In PlayCanvas you can create [Sprite Assets](/user-manual/editor/assets/inspectors/sprite) and [Sprite Components](/user-manual/editor/scenes/components/sprite). The Sprite Component is attached to Entities in order to display 2D graphics in your scene. Sprite Assets in PlayCanvas store multiple image frames from a Texture Atlas in sequence. So you can use a Sprite Asset to create flip-book style animated graphics in your games. ### Texture Atlases [Image: Texture Atlas] A [Texture Atlas](/user-manual/editor/assets/inspectors/texture-atlas) is an enhanced version of the standard [Texture](/user-manual/editor/assets/inspectors/texture) asset. In addition to the regular texture features, a Texture Atlas includes the definitions of a set of "Frames". Each frame is a region of the texture which can be referenced in a Sprite Asset. ### Sprite Editor [Image: Sprite Editor] The [Sprite Editor](/user-manual/2D/sprite-editor) is the tool used to generate Texture Atlas frames and Sprite Assets. You can open the Sprite Editor by double-clicking on any Texture Atlas or Sprite Asset. [Read More](/user-manual/2D/sprite-editor). *Artwork created by [PixelBoy](https://twitter.com/2pblog1)* -------------------------------------------------------------------------------- ## 9-slicing URL: https://developer.playcanvas.com/user-manual/2D/9-slicing/ 9-slicing (sometimes called 9-patch) is a technique for 2D graphics that splits a single image into 9 areas which are scaled individually in order to prevent stretching when the image is displayed at different sizes and with different aspect ratios. [Image: 9 Sliced Button] In the image above you can see the 9 areas that a defined using the Texture Atlas editing features of the [Sprite Editor](/user-manual/2D/sprite-editor). When added to a scene using either a [Sprite Component](/user-manual/editor/scenes/components/sprite) or an [Image Element Component](/user-manual/editor/scenes/components/element), the image can be resized using the width and height properties of the component. Each area is scaled using the following rules: * **Center** - stretch or tile both horizontally and vertically * **Top, Bottom** - stretch or tile horizontally only * **Left, Right** - stretch or tile vertically only * **TopLeft, TopRight, BottomLeft, BottomRight** - Do not stretch or tile [Image: Button Resize Animation] ## Setting up 9-slicing [Image: Setup 9-slicing] To setup a 9-sliced sprite. Create a frame around the area that you wish to use 9-slicing on in the Sprite Editor. Then use the blue handles or the Border property in the Frame Inspector to set the borders to outline the center portion of the image that you wish to be the stretch part of your sprite. Finally click the **New Sliced Sprite From Selection** to create a new Sprite with the render mode set to *Sliced*. ## Render Modes Sprite Assets can have one of three Render Modes. ### Simple Sprites [Image: Simple Render Mode] *Simple* Render Mode has no 9-slicing. Use this mode for regular sprites. ### Sliced Sprites [Image: Sliced Render Mode] *Sliced* Render Mode stretches portions of the image. The center stretches horizontally and vertically; the left and right sections stretch vertically; the top and bottom sections stretch horizontally and the corners do not stretch at all. ### Tiled Sprites [Image: Tiled Render Mode] *Tiled* Render Mode is similar to *Sliced* mode except instead of stretching the sections repeat in a tiled manner. The center tiles horizontally and vertically; the left and right tile vertically; the top and bottom tile horizontally and the corners do not tile at all. -------------------------------------------------------------------------------- ## Sprite Editor URL: https://developer.playcanvas.com/user-manual/2D/sprite-editor/ The Sprite Editor is used to edit both Texture Atlas assets and Sprite assets. It is also used to create Sprite Assets. To open the Sprite Editor, double-click on any Texture Atlas or Sprite asset in the Editor asset panel. [Image: Sprite Editor] ## Viewport [Image: Viewport] The viewport in the Sprite Editor shows the currently selected Texture Atlas. Frames are shown as grey boxes on the texture atlas. The currently selected asset is shown with two sets of handles. green and blue. Green handles modify the frame's width and height, blue handles modify the frame's border property. ### Editing Texture Atlases Within the viewport use the mouse to drag the outline of a Frame, then use the green and blue handles to modify the frames extents and borders. #### Frames Frames are a defined region on a Texture Atlas. A frame has a name, a position and size and a border. The border is used to define the edges of the 9-slicing region. See the [9-slicing documentation](/user-manual/2D/slicing/) for more information. ## Inspector The inspector panel shows the properties of the currently selected item. The inspector changes depending on whether the selected item is a Texture Atlas, Frame or Sprite Asset. ### Texture Atlas Inspector [Image: Texture Atlas Inspector] The Texture Atlas Inspector allows you to automatically slice a texture atlas into a fixed grid. First choose what to do with existing frames. You can choose to *Delete Existing* frames or do not delete and *Only Append* frames. Then select the method of specifying the grid cells - Grid By Frame Count - Specify the number of grid cells horizontally and vertically to divide the texture into - Grid By Frame Size - Specify the size in pixels that each grid cell should be Then set the values for Offset and Spacing. Offset is the number of pixels to move in from the top left of the texture before starting the grid. Spacing is the number of pixels between each grid cell. Finally set the pivot for all newly generated frames, the pivot determines the position and rotation point of the sprite. It is specified as a proportion of the width and height. Once all your settings are chosen, click the **Generate Frames** button to create your frames. ### Frame Inspector [Image: Frame Inspector] The Frame Inspector lets you set the properties for an individual frame or group of frames. It is visible when you select one or more Frames. The Frame Inspector is also where you create a new Sprite from. The Inspector lets you modify the Position, Size and Border properties of the frame. #### Frame Inspector Actions - **New Sprite From Selection** - Create a new Sprite Asset and assign the frames that you have selected to the Sprite, in the order that they were selected. - **New Sliced Sprite From Selection** - Create a new Sprite Asset and set its type to *Sliced*. Assign the frames that you have selected to the Sprite, in the order that they were selected. - **Focus on Selection** - Focus the viewport on the selected Frames. [Keyboard Shortcut: F] - **Trim Selected Frames** - Reduce the size of the selected frames to remove any excess empty space around an image. [Keyboard Shortcut: T] - **Delete Selected Frames** - Delete the selected Frames [Keyboard Shortcut: Delete] ### Sprite Inspector [Image: Sprite Inspector] The Sprite Inspector is visible when a Sprite Asset is selected. This inspector is used to edit the properties of one or more Sprites. See the [Sprite Asset](/user-manual/editor/assets/inspectors/sprite/) for more details on the properties. Click the **Add Frames to Sprite Asset** button to enter the Sprite Edit Mode. In this mode, you can select multiple frames from the Frame Panel or Viewport and add them to the Sprite. Click the **Add Selected Frames** to add the frames to your Sprite. Using the Sprite Inspector you can also re-order the Frames in your Sprite, or delete individual Frames. ## Frames Panel The Frames Panel lets you select and delete Frames from the Texture Atlas ## Asset Panel The Asset Panel shows you all the Sprite Assets that have been created from the current Texture Atlas. You can select Sprite Assets from this panel. *Artwork created by [PixelBoy](https://twitter.com/2pblog1)* -------------------------------------------------------------------------------- ## Using Texture Packers URL: https://developer.playcanvas.com/user-manual/2D/texture-packing/ ## What is texture packing? It's common to find sprites or UI images bundled as separate images. Texture packing is combining those separate images into a single [texture atlas](/user-manual/editor/assets/inspectors/texture-atlas/). This has several advantages including: - Faster loading times as it's a single network request instead of many. - As it's a single texture, the sprites can be batched into a single draw call. ## Tools Here are some texture packing tools that are compatible with PlayCanvas. ### TexturePacker Online (free) ([Website](https://www.codeandweb.com/tp-online)) A free browser tool that is able to do the basics of texture packing. 1. Clear the texture atlas. 2. Add your sprites/UI images. 3. Data format should be kept as JSON hash. 4. Download .png for the texture atlas. 5. Download .json for the frame data. ### Texture Packer tool ([Website](https://www.codeandweb.com/texturepacker)) TexturePacker is a paid tool for download that has many more features and options for creating texture atlases. These include more control over the layout of the sprites/UI images and being able to set up [9 slicing](/user-manual/2D/slicing/). Basic steps: 1. Add your sprites/UI images. 2. Set Output files -> Framework as PlayCanvas. 3. Click on Publish sprite sheet to create the texture atlas and JSON frame data. ## Creating frames in Sprite Editor Once you have uploaded the texture atlas file into the Editor and created a [texture atlas asset](/user-manual/editor/assets/inspectors/texture-atlas/), open the Sprite Editor. Click on 'Upload Texture Packer JSON' and select the JSON frame data file to upload. This will create frames in the texture atlas that you can create sprite assets from. When updating the texture atlas later in development, as long as the sprite filenames and frame names remain the same, the following will happen when uploading the new frame data: - Sprites that have been removed on the atlas will have their frames removed. - Sprites that have been added on the atlas will have new frames added to the end of the list. - Existing sprites will have their frames updated. -------------------------------------------------------------------------------- ## Account Management URL: https://developer.playcanvas.com/user-manual/account-management/ Welcome to Account Management! This section covers everything you need to know about managing your PlayCanvas account, from initial setup to advanced Organization features. ## User Accounts New to PlayCanvas? Start here to create your account and get familiar with the basics: - [User Accounts Overview](user-accounts/) - Learn about User Accounts - [Creating Your Account](user-accounts/account-creation.md) - Sign up, log in, and initial setup - [User Home](user-accounts/user-home.md) - Your user home page - [Account Settings](user-accounts/settings.md) - Privacy and account preferences ## Organizations For teams and businesses working together: - [Organizations Overview](organizations/) - What are organizations and their benefits - [Creating Organizations](organizations/creating.md) - Set up team workspaces - [Managing Organizations](organizations/managing.md) - Administration and permissions ## Billing Understanding subscriptions and payments: - [Billing & Subscriptions](billing.md) - Plans, invoices, and payment management --- Whether you're an individual developer or part of a large team, this section will help you make the most of your PlayCanvas account. -------------------------------------------------------------------------------- ## Billing URL: https://developer.playcanvas.com/user-manual/account-management/billing/ This Billing FAQ answers common questions about your PlayCanvas subscription. For a summary of what each plan includes, see the [pricing page](https://playcanvas.com/plans); to learn how team accounts work, see [Organizations](/user-manual/account-management/organizations/). ## Plans and eligibility ### Can businesses sign up to the Personal plan? Yes, providing the annual revenue of that business is below $100,000. Otherwise, the Organization plan should be selected. :::note We don't verify company revenues, so there's an element of trust involved. We rely on our users to support the ongoing development of PlayCanvas by choosing the plan that best matches their circumstances. Thanks for helping us keep PlayCanvas sustainable! ::: ### Can I switch between the Personal and Organization plans? No, there's no in-app switch between the two plans. To move from the Personal plan to the Organization plan — or the other way around — cancel your current plan and then sign up to the other one. The Organization plan applies to an [Organization](/user-manual/account-management/organizations/), which is a separate account type, so [Creating Organizations](/user-manual/account-management/organizations/creating/) covers how to set one up and bring your existing projects across. ### Do you offer education or startup discounts? We don't have a formal education discount, but if you'd like to use PlayCanvas for teaching or study, email us at [sales@playcanvas.com](mailto:sales@playcanvas.com) with a proposal. We don't offer discounts for startups. ## Payments and renewals ### Does my subscription auto-renew? Yes. Once you subscribe to the Personal or Organization plan, payment will automatically be taken on a monthly basis, on the day of the month when you first subscribed. ### What payment methods and currency do you accept? PlayCanvas subscriptions are billed in US dollars (USD). Payment is by debit or credit card only — we don't support other methods such as PayPal or bank transfer. ### Can I pay in advance for my subscription? Yes, but only for Organization plan subscriptions with a minimum term of 1 year. If you'd like to pay in advance for an Organization plan, please contact us at [billing@playcanvas.com](mailto:billing@playcanvas.com) with the following information: * Number of Organization seats required * Term of the upgrade * Business name * Business address * Contact name * Contact email * VAT number (if applicable) We will generate an online invoice that can be settled by debit or credit card. Once payment is received, we'll provide you with an account upgrade code that you can apply on the [upgrade page](https://playcanvas.com/upgrade). Personal plan subscriptions are only available as monthly auto-renewing subscriptions. ### What happens if a payment fails? If a renewal payment fails, it's automatically retried up to 4 times over about three weeks. If the payment still can't be collected after the final attempt, the subscription is cancelled and your account returns to the Free plan, which locks any private projects until you resubscribe. ## Invoices ### How do I receive invoices? Invoices for monthly subscriptions are emailed to the owner of the subscribed account on the monthly billing date. The subject line for these emails begins with "Your receipt from PlayCanvas Ltd". :::tip If invoices are not reaching your inbox, please check your spam folder. ::: ### Where can I find my billing history? Your historical invoices are available to download on [playcanvas.com](https://playcanvas.com). Visit your account page and scroll to the **Invoices** section. You should see something similar to this: [Image: Billing History] ### How do I update my details on my invoices? You may want to edit certain details that appear on your invoices, such as: * Billing Name * Billing Address * Tax ID To do this, visit the account page for your subscribed account (remembering that Organizations have their own account page). Navigate to the **Billing Info** section and click **Edit**. Fill out the payment details form and click **UPDATE CARD**. ## Organization billing ### How is billing for Organization accounts calculated? {#how-is-billing-for-organization-accounts-calculated} In short, you're billed for your current number of seats each month (at $50 per seat), with a pro-rata adjustment on your next billing date for any seats you added or removed during the previous month. The day you subscribe to an Organization account is your monthly billing date. So if you subscribe on 10th July, you will be billed on that date with subsequent billing dates as 10th August, 10th September and so on. The Organization plan allows you to add and remove seats at any time. When seats are added or removed, it is important to understand that this will increase or decrease the cost of your plan. However, this change in cost is not accounted for immediately when the number of seats is changed. Instead, it is accounted for at the next billing date. #### Example Imagine the following sequence of events: * A user signs up for a 1-seat Organization plan on 10th May. * The user then adds 1 seat on 20th June. * The user removes 1 seat on 20th August. The billing events from May to October will be as follows: * 10th May: **$50** * 10th June: **$50**. The plan has 1 seat and no changes were made to the plan in the previous month. * 10th July: $100 + $50 x 20/30 = **$133.33**. The user has two seats on this billing date so is charged 2 x $50 for the upcoming month. One of these seats was added on 20th June and the use of that seat between 20th June and 10th July must now be accounted for. Since this period is 20 days of the 30 days between the two billing dates, $50 x 20/30 is added to the bill. In other words, seats that are added or removed are accounted for ‘pro-rata’ on the next billing date. * 10th August: **$100**. The plan has 2 seats and no changes were made to the plan in the previous month. * 10th September: $50 - $50 x 21/31 = **$16.13**. The users has one seat on this billing date so is charged $50 for the upcoming month. A seat was removed on 20th August so it was only used for 10 of the 31 days between billing dates. Since the user paid $50 for that seat on the previous billing date, they are due a refund for the unused 21 days. So $50 x 21/31 is subtracted from the bill. * 10th October: **$50**. The plan has 1 seat and no changes were made to the plan in the previous month. ## Cancelling your subscription ### How do I cancel my subscription? You can cancel your plan subscription at any time. 1. Visit your [Account page](https://playcanvas.com/account). 2. Scroll down to the **Current Plan** section. 3. If you have **Personal** showing here, click **Cancel** to cancel it. 4. Click **OK** in the **CANCEL PLAN** dialog. 5. Also in the **Current Plan** section, you will see a list of your Organizations. 6. For each Organization listed, click its icon to visit its Account page. 7. Scroll down to the **Current Plan** section. 8. If you have **Organization** showing here, click **Cancel** to cancel it. 9. Click **OK** in the **CANCEL PLAN** dialog. Once your subscription is cancelled, you will not be billed again unless you resubscribe. :::note When you cancel your subscription, it will not revert to the Free plan immediately. Instead, this will happen at your next billing date. If between the time you cancel and your next billing date you decide you would like to continue your subscription, just return to your Account page and click **Resume**. ::: ### What happens to my published apps when I cancel my subscription? Your published apps will be completely unaffected if you cancel your subscription. This is true regardless of whether your apps are hosted by us or by you. ### What happens to my private projects when I cancel my subscription? Your private projects will become locked (inaccessible) when you cancel your subscription. To unlock them, you have two options: 1. Resubscribe to a plan. 2. Make the projects public. ### Do you offer refunds? Subscription fees are non-refundable, with one exception: if you change your mind within 14 days of first subscribing to — or upgrading to — a Personal or Organization plan, you can request a full refund of what you paid for that subscription. After this cooling-off period, cancelling stops future renewals but the current period isn't refunded. For the full policy, see our [Terms of Service](https://playcanvas.com/terms). When you reduce the number of seats on an Organization plan, the unused portion of any seats you remove is automatically credited pro-rata on your next billing date — see [How is billing for Organization accounts calculated?](#how-is-billing-for-organization-accounts-calculated). ## Collaborators ### I have a Personal plan. Can I add a free user to my private project? No. You can only add users who also have a Personal plan to your private projects. If you want collaborators to work on private projects without each needing their own paid plan, use an [Organization](/user-manual/account-management/organizations/) instead, where members are covered by the Organization's seats. ## Contact ### How can I contact PlayCanvas about billing? If your question about billing is not answered on this page, please email [billing@playcanvas.com](mailto:billing@playcanvas.com). -------------------------------------------------------------------------------- ## Organizations URL: https://developer.playcanvas.com/user-manual/account-management/organizations/ An **Organization** is a shared account for teams. Instead of projects living under one person's personal account, they belong to the Organization, where an owner and any number of administrators manage projects, members, and permissions together. Organizations are available on the **Free plan**, with a paid plan when you need more. ## What is an Organization? An Organization is a team-owned workspace rather than an individual login. A few things set it apart from a personal account: - **It isn't tied to one person.** You never log in *as* the Organization. Instead, you manage it through your own user account as its **owner** or an **administrator**. - **It has multiple administrators.** The owner can appoint any number of administrators, who can create and delete projects and manage members. Only the owner can delete the Organization itself. - **Projects belong to the team.** Projects are owned by the Organization, not by an individual, so they outlast any single member's account. - **Ownership can be transferred.** If the owner leaves the team, ownership can be handed to another user without disrupting any projects. ## Organizations vs. personal accounts The difference is about **who owns and administers the account**, not which plan you're on — an Organization can run on the Free plan just like a personal account. | | Personal account | Organization | |---|---|---| | Owned by | One person (you) | The team or company | | Administrators | Just you | An owner plus any number of administrators | | Projects & members | You manage collaborators per project | Administrators manage projects and members centrally | | Best for | Individuals | Teams of any size | ## Plans Organizations work on the **Free plan**, which gives you the shared account and team administration described above, along with unlimited public projects. Upgrade to the paid **Organization plan** when your team needs **private projects**, more storage (50 GB), and per-seat billing on a single invoice. Seats cost $50 each per month, can be added or removed at any time, and are prorated on your next billing date — see the [worked example](/user-manual/account-management/billing/#how-is-billing-for-organization-accounts-calculated) in the Billing FAQ, and the [pricing page](https://playcanvas.com/plans) for the latest details. ## When to use an Organization An Organization is a good fit when: - Projects should belong to the team or company rather than an individual's personal account. - You want more than one administrator managing projects, members, and permissions. - You're working with others and want a shared workspace — even on the Free plan. ## Getting started 1. [Create an Organization](creating.md) — start a new Organization or convert an existing account. 2. [Manage your Organization](managing.md) — handle [roles and permissions](managing.md#permissions), [seats](managing.md#seats), and [projects](managing.md#projects). -------------------------------------------------------------------------------- ## Creating Organizations URL: https://developer.playcanvas.com/user-manual/account-management/organizations/creating/ There are two ways to create an Organization. Any Organizations you belong to appear next to your name on your profile: [Image: Profile Organizations] ## Create a new Organization Open the dropdown menu in the top-right corner and click **NEW ORGANIZATION**: [Image: Dropdown] This opens the following dialog: [Image: New Organization] Enter a **name** for the Organization and an **Organization ID** (a string containing only alphanumeric characters and dashes). The email address defaults to your own, but you can change it. Click **CREATE** to finish — you'll be taken to the Organization's profile page. ### Transfer existing projects into the Organization If you already have projects — for example, private projects on a Personal plan — you can move them into the new Organization: 1. From your user account, [transfer ownership of the projects](/user-manual/editor/projects/ownership-transfers#initiating-ownership-transfers) to the Organization. 2. From the Organization account, accept the transfer. 3. If you're on a Personal plan, cancel it to downgrade to Free. This takes effect immediately, regardless of when you last paid. 4. [Add yourself to the projects as an administrator](/user-manual/account-management/organizations/managing/#projects) of the Organization. Your projects are now owned by the Organization, with your user account as an administrator on each. ## Convert a user account into an Organization Alternatively, you can convert an existing user account into an Organization. Click **CONVERT** on your [account settings](/user-manual/account-management/user-accounts/settings/#convert-account-to-organization) page: [Image: Convert Organization] This opens the following dialog: [Image: Convert Popup] Because you can't log in *as* an Organization, converting an account means you'll no longer be able to log in with it. You must therefore nominate another user as the new **owner**. :::warning Make sure you can log in with the new owner's account before you convert. ::: If the account is on a paid plan, that plan is cancelled unless you choose to subscribe to an Organization plan in the dialog. The number of seats to purchase is calculated automatically from the number of users across your existing private projects. After converting, you'll be logged out. Log back in with the new owner's account to access the Organization and all its projects. -------------------------------------------------------------------------------- ## Managing Organizations URL: https://developer.playcanvas.com/user-manual/account-management/organizations/managing/ You manage an Organization from its account page. This is where the owner and administrators handle roles, seats, projects, and — if necessary — deleting the Organization. ## Roles and permissions {#permissions} [Image: permissions] The account page shows the Organization's **owner** and its **administrators**. From here, the owner can transfer ownership to another user and add or remove administrators. Administrators can do everything the owner can — including creating and deleting projects — *except* delete the Organization itself. Only the owner can do that. ## Seats {#seats} A **seat** is consumed when you add a user to one of the Organization's **private** projects. Public projects don't require seats, so you can have unlimited public collaborators at no cost. [Image: seats] This view lists every user with access to your private projects and the seats they occupy. Removing a user here removes them from all of the Organization's projects and frees up their seat. The owner doesn't need to occupy a seat if they aren't actively working on projects. We recommend giving a seat to at least one administrator, so that someone can always create and manage projects. ### Adding and removing seats [Image: upgrade] If you're subscribed to the Organization plan, you can increase or decrease the number of seats at any time. Seat changes are prorated on your next billing date — see the [worked example](/user-manual/account-management/billing/#how-is-billing-for-organization-accounts-calculated) in the Billing FAQ. ## Projects {#projects} Administrators can add themselves to any project the Organization owns. On the account page, click the dropdown arrow to the right of a project and choose **Add me as admin**: [Image: add to project] From there, you can add other users to the project as usual. ## Deleting an Organization {#delete} [Image: delete] Only the owner can delete the Organization, from its account page. :::danger Deleting an Organization permanently erases the account and **all** of its projects. This action cannot be undone. ::: -------------------------------------------------------------------------------- ## User Accounts URL: https://developer.playcanvas.com/user-manual/account-management/user-accounts/ Your user account is your personal space within PlayCanvas. This section covers creating, managing and configuring your account. ## Why Create a PlayCanvas User Account? Creating a free PlayCanvas account opens up a world of possibilities for building 3D web applications! Once you are signed up, you can: - 🛠️ **Access the [PlayCanvas Editor](../../editor/)** - Build 3D apps using a powerful, visual interface. But not everyone opts to use the PlayCanvas Editor - perhaps you prefer to use the [PlayCanvas Engine](../../engine/) directly, or [PlayCanvas Web Components](../../web-components/) or [PlayCanvas React](../../react/) instead. Does it still make sense to create a PlayCanvas account? Absolutely! And here's why: - 🔍 **Explore and learn** - Browse scripts and assets in thousands of public Editor projects to learn and find inspiration - ⚙️ **Generate Assets** - Use the Editor's asset processing capabilities to generate assets for use in any PlayCanvas-based project - ✨ **Publish, like, and comment on Gaussian Splats** - A PlayCanvas account is required to publish splats to [SuperSplat](/user-manual/supersplat/), like splats, and post comments. Browsing the public [Explore](/user-manual/supersplat/explore) gallery and viewing public scene pages is anonymous. - 👥 **Community participation** - Star, follow and comment on the projects of other PlayCanvas community members - 🔔 **Stay Informed** - Creating an account allows us to notify you of exciting updates related to the entire PlayCanvas platform So no matter how you use PlayCanvas, we strongly recommend you create an account on playcanvas.com! -------------------------------------------------------------------------------- ## Creating Your Account URL: https://developer.playcanvas.com/user-manual/account-management/user-accounts/account-creation/ To join the PlayCanvas community, we strongly recommend that you create a new account. Click **SIGN UP** at the top right of [https://playcanvas.com](https://playcanvas.com). [Image: Sign Up] At the sign up page, you have 3 options for account creation: 1. **Username and Password** - enter your email address and password. 2. **Sign in with Google** - authenticate using your Google account. 3. **Sign in with GitHub** - authenticate using your GitHub account. [Image: Sign Up Form] If you select the Username and Password option, you will be asked to confirm your email address: [Image: Confirm Email] Head to your email inbox and click the verification link. You will be taken to this page: [Image: Email Verified] On hitting continue, you'll be prompted to add some details about yourself: [Image: Details Form] - **Full Name** - A non-unique display name. We recommend setting this to your actual name. - **Username** - Your handle that is used to uniquely identify you on the platform. This is used to determine the URL of your PlayCanvas profile page. - **Skills** - Pick the skills you have related to building interactive graphics apps (options are 'Coder', 'Artist', 'Designer' and 'Musician'). These skills will be displayed on your public profile. - **Email Notifications** - Enable this to receive tips and news about PlayCanvas. Once you have completed the form, hit **Create Account**! You begin by being dropped straight into your first project in the PlayCanvas Editor. [Image: Roll Ball] It is a clone of a simple 'Roll a Ball' game. This is your playground for getting familiar with the Editor. A set of clickable hot-spots will guide you through some of the key elements of the Editor. Jump to the [Editor section](../../editor/index.md) to learn more about the PlayCanvas Editor. -------------------------------------------------------------------------------- ## Account Settings URL: https://developer.playcanvas.com/user-manual/account-management/user-accounts/settings/ Your account settings page provides access to all your personal account configuration options, from basic profile information to billing and security settings. To view your user account settings, navigate to [https://playcanvas.com/account](https://playcanvas.com/account). You should see something like this: [Image: Account Settings] ## Profile Picture Upload and manage your profile picture that appears across PlayCanvas. Click on your current profile picture to upload a new image. ## Account Info ### Username Your unique PlayCanvas username that appears in URLs and identifies you across the platform. You can change your username, providing that username has not already been taken. If it has, you will see the message **Already used**. ### Your Full Name The display name shown on your profile and in collaborations. You can edit this whenever you choose. ### Email Address Your primary email address for account notifications and login. Click "Edit" to change your email address. If you sign in with username+password, you'll need to verify the new email address before the change takes effect. ## Password Update your account password for security: - **Current Password** - Enter your existing password - **New Password** - Choose a new password of at least 8 characters - **Confirm Password** - Re-enter your new password to confirm :::tip Use a strong password with a mix of uppercase, lowercase, numbers, and special characters for better security. Consider using a password manager to make this process easier. ::: ## Skills Tag yourself with the skills that best match your experience: - **Coder** - Programming and scripting - **Artist** - 3D modeling, texturing, animation - **Designer** - UI/UX and game design - **Musician** - Audio and music composition These skills are displayed in your public profile header. ## Current Plan View your current subscription plan. For free accounts, this shows "Free $0 / month" with basic plan limitations. For accounts on the Personal plan, this shows "Personal $15 / month". :::tip To cancel your Personal plan, click the **Cancel** link and confirm. Your account will drop back to the free tier and the end of your current billing cycle. ::: ## Billing Info Users on the Free plan will see "No credit card stored in your account" until a paid plan is purchased. Users on the Personal plan will see something of the form "Card ending in - 0000". Click **Edit** to update billing info: - Card details - Billing address - VAT number (if supported in your country) ## Invoices Access your billing history and download invoices. By default, your 3 latest invoices are displayed. Keep clicking **Load More...** to load the next 10 invoices. ## Seats View and manage team members across your projects: - Lists all users who are team members on projects you own - Shows which specific projects each user has access to :::tip Click the `x` icon to the right of a listed user to remove them from all of your projects that they are on the team of. ::: ## Usage This section tracks your account resource consumption. The usage meter shows current consumption against your plan limits. ### Storage Breakdown - **Public Projects** - Number created vs. limit - **Private Projects** - Number created vs. limit (plan-dependent) - **Assets** - Storage used for 3D models, textures, audio - **Apps** - Published application data - **Code** - Script and code storage - **Checkpoints** - Version history storage - **Splats** - Gaussian splat data (uploaded from SuperSplat) ## API Tokens Manage programmatic access to your PlayCanvas account: - Generate new API tokens - View existing token permissions - Revoke access for unused tokens See the [API Documentation](/user-manual/api/) for details on using API tokens. ## Email Preferences Configure which notifications you receive: - **My Projects** - Updates about your own projects - **Watched Projects** - Notifications from projects you follow - **New Comments** - Comments on your projects or posts - **New Stars** - When users star your projects - **My Organizations** - Organization-related updates - **Exciting PlayCanvas Stuff** - Platform news and updates Uncheck any categories you don't want to receive emails about. ## Organizations ### Convert Account to Organization {#convert-account-to-organization} Transform your personal account into an [organization](../organizations/index.md) account: - Allows team collaboration - Enables advanced permission management - Requires designating a new owner :::warning Converting to an organization means you can no longer log in with this account. Make sure you have another account ready to become the organization owner. ::: :::tip You cannot convert a user account into an organization if it currently manages other organizations. Transfer those organizations to be owned by another user account first. ::: ## Delete Account Permanently remove your PlayCanvas account: - All projects and data will be deleted - This action cannot be undone - Consider downloading important projects first :::danger Account deletion is permanent and irreversible. Make sure to backup any important work before proceeding. ::: :::tip You can't delete a user account if it currently manages any organizations. Please delete the organizations first or transfer their ownership to another user account. ::: --- For billing-specific questions and detailed subscription management, see [Billing](../billing.md). -------------------------------------------------------------------------------- ## User Home URL: https://developer.playcanvas.com/user-manual/account-management/user-accounts/user-home/ Once you have created your user account, you can visit your User Home page. The URL for this page will be of the form: ```none https://playcanvas.com/user/ ``` :::tip Assuming you are logged in, simply visiting [https://playcanvas.com/](https://playcanvas.com/) will redirect you to your User Home page. ::: Here's what a new User Home page should look like: [Image: User Home Page] It defaults to showing your list of [Editor Projects](../../editor/projects/index.md). -------------------------------------------------------------------------------- ## Animation URL: https://developer.playcanvas.com/user-manual/animation/ PlayCanvas provides a powerful state-based animation system which can be used to animate character models and other arbitrary scene object models. Users can work with any of their .FBX animation assets. These can be organized using animation state machines to easily control the animated behavior of scene models at runtime. ## System Overview The animation system touches on three main areas of the PlayCanvas platform. This section will walk through how these areas can be used together to create complex animation behavior for your models. The following sections of the animation user manual then will explore each area in more detail. ### Animating in PlayCanvas In order to begin animating a PlayCanvas entity, you must have a set of animation assets available and imported into your PlayCanvas project. These animation assets will drive the animation of a given model you wish to animate. For example a humanoid character may have a set of animations; Idle, Walk, Jump. [Image: Animations] These three animations can be organized into a single animation system to create a simple locomotion system for that character. The way this is achieved in PlayCanvas is through the use of an animstategraph asset. These assets can be thought of as state machines for an entity’s animation behavior. With each state in this asset relating to an animation, the state machine can be set up to define the complex animation behavior of an entity’s model. This includes defining when the system should stop one animation and start another and how the transition between these animations should be blended. The anim component is then used to assign an animstategraph asset to a particular entity in your scene. Once an entity has been assigned an animstategraph asset, each state in the graph can have an actual animation asset assigned to it. Once all states have been assigned animations, the anim component will become playable. At this point the animation system is complete and the defined animation behavior will be viewable in the PlayCanvas launcher. -------------------------------------------------------------------------------- ## Animation Assets URL: https://developer.playcanvas.com/user-manual/animation/anim-animation-assets/ [Image: Animation Assets] Animation assets are the animation keyframe data that’s used to drive animations of a model in PlayCanvas. They are linked to an animstategraph asset via an entity's anim component. The anim component currently supports animation assets that have been imported into a PlayCanvas project from .FBX files using the `Convert to GLB` setting in Project Settings > Asset Import. [Image: Asset Import] -------------------------------------------------------------------------------- ## Anim Component URL: https://developer.playcanvas.com/user-manual/animation/anim-component/ Click here to learn how to use the [Anim Component](/user-manual/editor/scenes/components/anim/). [Image: New Anim Component] -------------------------------------------------------------------------------- ## Anim Events URL: https://developer.playcanvas.com/user-manual/animation/anim-events/ Anim events can be used to trigger event listeners during the playback of an animation. Each event is associated with a specified frame of the animation asset it is attached to. When the playback of the animation reaches that frame, the event will fire and the associated event listener is called. ### Creating Events To create a new event, select the animation asset in the asset panel which you'd like to create an event for. You should then see the `+ EVENT` button in the asset inspector as shown below: [Image: Animation Asset With Event] Each event has the following modifiable properties: | Variable | Description | |----------|-------------| | time | Defines the specific time during the playback of the animation when the event should trigger. Given in seconds. | | name | The name of the event is used to identify the event when attaching an event listener to the anim component. | | number | An additional property which can be set to any number. Used to pass additional details to the event listener. | | string | An additional property which can be set to any string. Used to pass additional details to the event listener. | ### Event Listeners After creating an event for an animation asset, the event will be fired whenever that asset is played back by an anim component. You can therefore attach listeners to the anim component to handle the event. The following example shows how to attach event listeners to the anim component: Any number of animation events can be attached to a single animation asset and used by any number of anim components. Making use of the additional `number` and `string` properties of an event allows you to differentiate between events that are passed to the same event listener. :::ai When one effect spans several animations, ask an AI assistant through the **[Editor MCP Server](/user-manual/editor/mcp-server/)** to check event names and payloads against script listeners, then reproduce the animations in Launcher to find missing or mistimed effects. ::: -------------------------------------------------------------------------------- ## Anim Layer Masks URL: https://developer.playcanvas.com/user-manual/animation/anim-layer-masking/ When creating complex animation behavior for your game objects, it is often necessary to isolate the playback of certain animations to specific bones in each object's model. This is particularly useful when animating characters that need to carry out multiple actions at the same time. This can be achieved in PlayCanvas by creating a mask for a given [animation layer](/user-manual/animation/anim-state-graph-assets/#layers) in your anim component. ### Creating a mask After creating an Anim State Graph asset and attaching it to an anim component, you'll be presented with a list of layers contained in your graph. You can create a mask for any of these layers by clicking the **Create Mask** button under each layer panel: [Image: Anim Component Create Mask] This will open up the mask inspector for that layer which is shown below: [Image: Mask Inspector] The mask inspector displays the full hierarchy which the anim component is driving, starting at the `root bone` specified in the anim component. Each bone in the hierarchy can be selected to be included in the mask. You can also right-click specific bones to include or exclude whole sections of the hierarchy. Any bones which are not selected in this mask will not be driven by any of the animations which play in this mask's layer. After creating masks, you can use [layer blending](/user-manual/animation/anim-state-graph-assets/#layer-blending) to smoothly blend the masked animations of multiple layers together. -------------------------------------------------------------------------------- ## Animstategraph Assets URL: https://developer.playcanvas.com/user-manual/animation/anim-state-graph-assets/ Animstategraph assets are used to organize a set of different animation states, which are all the various ways in which a model might animate. It can be used to define each of these animation states, determine when each state should play and how states transition and therefore blend between one another. Animstategraph assets do not store or link to any real animation assets themselves, but rather act as a template for how animation assets should be organized. Actual animation assets are linked to the animstategraphs animation states through the [Anim Component](/user-manual/editor/scenes/components/anim/). The system was designed so that a single animstategraph can be used on many different entities, each with their own set of animation assets. An example being an animstategraph asset which manages the animations of humanoid character locomotion. This single asset could be used on a human entity, an elf entity and a dwarf entity. Each of these entities would be able to link their own character animation assets, all the while maintaining the same animation behavior as each other. These assets are therefore state machines for a model's animation behavior and they control the flow of animation sequences over the lifecycle of an entity. A simple animstategraph asset used to define the behavior of a wheel may define only two animation states; static and spinning. This asset can be defined to control when the wheel starts and stops spinning, for how long it will spin, the speed of the wheel spin and how sharply it starts / stops spinning. More advanced assets can be used to combine a multitude of animation states to create complex humanoid character animation behavior. When selecting an animstategraph asset in the editors asset panel, you’ll open up the anim state graph editor view: [Image: Initial Editor] Within this view you can edit your animation state graph. The following sections will highlight how different elements of the animstategraph asset can be used to define specific animation behavior. :::ai For complex graphs, ask an AI assistant through the **[Editor MCP Server](/user-manual/editor/mcp-server/)** to trace a failing transition across its conditions, parameters, scripts, and Anim mappings, then reproduce it in Launcher. ::: ## States {#states} In essence, states are used to specify which animations should play at a given point in time. An anim state graph can only be in one of these states at a given time. There are four types of states present in state graphs. Animation states, along with the START state, END state and ANY state. Only animation states can be created and deleted by the user and only these will be linked to animation assets. The other states are used to control the flow through the state machine. ### Animation States {#animation-states} [Image: State] Animation states define a playable animation such as ‘Idle’, ‘Jump’ or ‘Walk’. New animation states can be created by right clicking on the blank canvas behind the state graph and selecting ‘Add new state’ from the menu. The editor will target your newly created state and show its inspector panel on the right hand side. Within this inspector the following state variables can be modified: | Variable | Description | |----------|-------------| | Name | The name that this state should be called by. This is used to find and edit and play states via script. Names must be unique per state graph layer. | | Speed | The playback speed for animations that are linked to this state. | | Loop | Whether animations linked to this state should loop during playback. If set to false the animation will pause on its last keyframe until this state is exited. | ### START state {#start-state} [Image: Start State] The START state is the entry point of every state graph. When an anim component begins playing its assigned anim state graph, it will first enter this state and transition directly to the animation state it’s connected to. This animation state is called the default state and it can be selected via the layers panel here: [Image: Layers] It is not possible to create any other transitions to or from the START state. It can only be entered again by transitioning to the END state. ### END state {#end-state} [Image: End State] The end state marks an exit out of the current state graph. If your animation state is set up to transition to the END state, the system will move directly to the default animation state which is connected to the START state. This is useful to create cyclical flows through the graph while still laying out your graph in a linear fashion. It is not possible to create transitions from the END state to any other state. It will always transition directly to the START state. ### ANY state {#any-state} [Image: Any State] This state is used to create transitions which can be activated while the system is currently in any of the other animation states. Any transitions that trigger from this state will blend as if they had been connected directly from the currently active animation state. You can create transitions from the ANY state but not to it. This is useful to set up transitions which you want to activate, no matter which state you’re currently in. For example you could have a jump state which should be reachable from both an idle and walk state. Instead of setting up transitions from both the idle and walk states to the jump state, a transition can be set up between the ANY state and the jump state. ### Transitions {#transitions} Transitions define how the anim state graph can move from one animation state to another. They can be created by right clicking an animation state and selecting `Add transition` from the context menu. By setting the variables of a given transition you can also control how the animations of the transitioning states will blend together. The available transition variables are: | Variable | Description | |---------------------|-------------| | Duration | The duration of the transition in seconds. | | Exit Time | The time at which to exit the source state and enter the destination state. Given in normalized time based on the source state's duration. Providing no value allows the source state to exit with this transition at any time. A value of less than 1 will make the transition available for exit at that time during every loop of the source state. | | Offset | If provided, the destination state will begin playing its animation at this time. Given in normalized time based on the destination state's duration. Must be between 0 and 1. | | Interruption Source | Defines whether another transition can interrupt this one and which of the current or previous states' transitions can do so. | It is possible to create multiple transitions between two animation states, which have different values and conditions set. The priority of these transitions can be reordered in the transition inspector after selecting a transition's arrow in the graph. The priority order determines which transition will be used by the state graph if multiple transitions have their conditions met. ### Parameters {#parameters} The parameters of an anim state graph are variables which are used to control the flow of animations during runtime. These variables can be accessed via scripts and set to new values at any time. They are then the way in which users can control the behavior of an entity's animation during its lifecycle. New parameters can be added to a state graph via the parameters panel on the left inspector: [Image: Parameters] Each parameter has three variables which can be set: | Variable | Description | |---------------|-------------| | Name | The name that this parameter should be called by. This is used to find and set the parameter via script. Names must be unique per state graph. | | Type | The type of variable that the parameter contains. One of: Boolean, Float, Integer or Trigger. The Trigger type acts as a Boolean but with the special property that its value is set back to false after it has been used to successfully activate a transition. | | Default Value | The value of the parameters variable when the state graph launches. | The way in which they control the state graph is through the use of transition conditions. Each transition in the graph can have a list of conditions which define when a transition is usable by the system. A state will not be able to pass to another state through a given transition unless all of its conditions are met. Each condition consists of a conditional statement which compares the current value of a parameters variable to the given value in the condition using the designated operator. For example, the following condition: [Image: Condition] Can be used in the transition between the Idle and Jump animation states to ensure that a character only jumps when the ‘Jump’ parameter has been set to true via a script. ### Layers {#layers} So far, animstategraph assets have been discussed in the context of editing a single animation state graph. It may sometimes be necessary however to have the animations of a single model driven by multiple separate state graphs, each with their own defined behavior. An example could be animating a main character's movement and locomotion on a single layer, while animating its facial expressions on a separate layer that’s driven by its own state graph and parameters. When an animstategraph is created, it comes with a single base layer. This layer is not deletable and for many scenarios will be the only one necessary. However if you wish to create another layer you can do so by selecting the new layer button on the layers panel to the left of the state graph view: [Image: Layers] It is then possible to switch to editing this layer by selecting it from the layer select dropdown which is present at the top right of the graph view: [Image: Select Layer] ### Layer Blending {#layer-blending} By default, layers animate a model in the order that they’re created in the layers panel. Any animation values they set on a model's bones will be overwritten by subsequent layers. If instead you wish to blend the animation values of the layers together, you can set the `blend type` of your layers to `Additive` rather than the default `Override`: [Image: Layer Blend] The blend weight value of each layer is used when blending multiple layers to determine how much each layer should contribute to the final animation. These blend weights can be adjusted at runtime in your game scripts to update the blends of your layers in real time: If you [mask your layers](anim-layer-masking.md), you can set the `blend type` of your layers to `Additive` to blend in an animation which only controls part of your model's bones. Updating the `blend weight` in real time as described above can allow you to create smooth blends between animations on different layers. This is particularly useful when animating characters that need to carry out different actions using their upper and lower body. For example, you could have a `shooting` animation that is blended in and out on a characters upper body, while freeing up the lower body for various locomotion animations such as `walking` and `running`. Any layers that are set to `Overwrite` will completely replace the animation values of the model's bones that are animated in that layer. In these instances, previous layers will not be taken into consideration when producing the final animation. -------------------------------------------------------------------------------- ## REST API URL: https://developer.playcanvas.com/user-manual/api/ :::warning The REST API is currently in beta. This means we may change certain endpoints and API responses. ::: ## Authorization {#authorization} You can only access the REST API via https. In order to access the REST API you need to use an Access Token. You can generate an Access Token by going to your Organization's Account page. [Image: Account Tab] In the API Tokens section click on Generate Token. [Image: Generate Token] Give your token a name and click the button to create your new token. A new window will appear showing you your new access token. Make sure you note that down because you will not be able to see the token once you close this window. This token is meant to be kept secret so do not share it with anyone other than your team (for example do not post this on forums). [Image: New Token] From your Account page you can also Revoke all the tokens you have generated or a specific one. You can also edit the name of a token. [Image: Remove Token] When you make calls to the API you must set the 'Authorization' header in your HTTP request to this value: ```none Bearer [access_token] ``` Replace `[access_token]` with an Access Token you generated in your Account page. For example: ```none curl -H "Authorization: Bearer nesgdxhiqe7hylfilr6ss1rds0gq1uj8" https://playcanvas.com/api/... ``` ## Parameters {#parameters} Various routes accept a number of parameters. For GET requests if the parameter is not part of the URL, you can pass it as an HTTP query string parameter. For POST, PUT and DELETE requests parameters not included in the URL should be encoded as JSON with a Content-Type of 'application/json'. There are several common parameters that are used in each endpoint: ### project_id {#project_id} This can be found in the URL on the project overview page. [Image: Project ID] ### scenes {#scenes} When opening a scene in the Editor, the scene id is in the URL. [Image: Scene ID] ### branch_id {#branch_id} This is found in the [version control](/user-manual/editor/version-control/) panel and can be selected and copied. [Image: Branch ID] ## Response Format {#response-format} Our REST API is following some generic guidelines when it comes to the response format of each API call. ### GET resource {#get-resource} If you are trying to GET a single resource the response will be a JSON object with the resource you requested. ### GET multiple resources {#get-multiple-resources} If you are trying to GET multiple resources like for example listing the Apps of a Project you will get a JSON object with this format: ```none { "result": [ resource_1, resource_2, ..., resource_N ], "pagination": { "limit": number, "skip": number, "total": number } } ``` As you can notice the response in this case also contains pagination data. To control the pagination of the response you can pass the following URL parameters: | Name | Description | | ------- | -------------------------------------------------------------------------------------------------------------------------------- | | `limit` | The maximum number of items to include in the response. | | `skip` | The number of items to skip from the original result set. | | `sort` | The name of the field to use to sort the result set. See the documentation of each request to see which values are allowed here. | | `order` | If you want results in ascending order pass 1 otherwise pass -1 for descending order. | So for example to get 32 items after the first 16 items you would send this request: ```none https://playcanvas.com/api/items?limit=32&skip=16 ``` ### Errors {#errors} When an error is raised you will get a JSON object with this format: ```json { "error": "This is the error message" } ``` Also the status code of the response will be the appropriate HTTP error code. ## Rate Limiting {#rate-limiting} Calls to the REST API have a rate limit. Check your actual limits by querying [this endpoint](https://playcanvas.com/api/ratelimits). There are different rate limits depending on the request: | Rate Limit Type | Description | Limit for free accounts | Limit for personal/org accounts | | --------------- | ------------------------- | ----------------------- | ------------------------------- | | Normal | The normal rate limit | 120 requests/minute | 240 requests/minute | | Strict | The strict rate limit | 5 requests/minute | 10 requests/minute | | Assets | The assets rate limit | 60 requests/minute | 120 requests/minute | The response will contain the following headers to help you regulate how often you call the API: | Name | Description | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | | `X-RateLimit-Limit` | The number of requests allowed in a minute. | | `X-RateLimit-Remaining` | The remaining number of requests that you are allowed to make this minute. | | `X-RateLimit-Reset` | The time at which the current rate limit window resets in [UTC epoch seconds](https://en.wikipedia.org/wiki/Unix_time). | If you exceed the rate limit you will get a `429 Too Many Requests` status code. You will have to wait for the current window to reset in order to continue making requests. -------------------------------------------------------------------------------- ## Apps - Download app URL: https://developer.playcanvas.com/user-manual/api/app-download/ ## Route URL ```none POST https://playcanvas.com/api/apps/download ``` ## Description This will allow you to download an app which you can self host on your own server. The request will start a download job and the job details will be returned in the response. You can [poll the job by id](/user-manual/api/job-get) until its status is either 'complete' or 'error'. When the job is done, its data will contain a URL to download the app package. Use `format` to choose the package type. Omit it or set it to `static` for the standard self-hostable package, or set it to `npm` for a Vite-based npm project. See [Downloading Projects](/user-manual/editor/projects/downloading#download-formats) for details on the available download formats and [NPM project structure](/user-manual/editor/projects/downloading#npm-project-structure). ## Example ```none curl -H "Authorization: Bearer {accessToken}" -H "Content-Type: application/json" -X POST -d '{"project_id": 9999999, "scenes": [9999999], "name": "My App", "format": "npm"}' "https://playcanvas.com/api/apps/download" ``` ## Parameters | Name | Type | Required | Description | | ----------------------- | ---------- | :------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `project_id` | `number` | ✔️ | The id of the project. | | `name` | `string` | ✔️ | The name of the app. Must be less than 1000 characters. | | `scenes` | `number[]` | ✔️ | A list of scene ids to be included in the app. When you specify scenes then the first scene in the list will be used as the initial scene of the application. | | `branch_id` | `string` | | The id of the branch. If no id is specified the main branch will be used. | | `description` | `string` | | The description of the app. Must be less than 10,000 characters. | | `version` | `string` | | The version of the app. Can be a string up to 20 characters. | | `release_notes` | `string` | | Release notes for the app. Can be a string up to 10,000 characters. | | `scripts_concatenate` | `boolean` | | Set it to true if you want scripts to be concatenated. | | `scripts_minify` | `boolean` | | Set it to true if you want scripts to be minified. Defaults to true. | | `scripts_sourcemaps` | `boolean` | | Set it to true if you want script sourcemaps to be generated. Defaults to false. | | `optimize_scene_format` | `boolean` | | Set it to true if you want scenes to be in an optimized format (see [Optimize Scene Format](/user-manual/optimization/optimizing-scene-format) for more information). | | `format` | `string` | | Download package type: `static` or `npm`. Defaults to `static`. See [Downloading Projects](/user-manual/editor/projects/downloading#download-formats). | | `engine_version` | `string` | | Set it to a Engine version string ([full list of releases](https://github.com/playcanvas/engine/releases)) if a specific version is needed for the app. Defaults to the latest Editor supported major version depending on your project. | ## Response Schema ```none Status: 201 Created ``` ```json { "status": "running" | "complete" | "error", "messages": list of strings, "created_at": date, "modified_at": date, "data": { "concatenate": boolean, "branch_id": string, "optimize_scene_format": boolean, "format": "static" | "npm", "minify": boolean, "name": string, "sourcemaps": boolean, "scenes": list of int scene ids, "engineVersion": string, "preload_bundle": boolean, "project_id": int, "owner_id": int }, "id": int } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 404 | Owner not found | | 404 | Scene not found | | 429 | Too many requests | ## Rate Limiting This route uses a [strict](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Apps - Get primary app URL: https://developer.playcanvas.com/user-manual/api/app-get-primary/ ## Route URL ```none GET https://playcanvas.com/api/projects/:projectId/app ``` ## Description Gets the Primary App of a Project. ## Example ```none curl -H "Authorization: Bearer {accessToken}" https://playcanvas.com/api/projects/{projectId}/app ``` ## Parameters | Name | Type | Description | | ----------- | -------- | ---------------------- | | `projectId` | `number` | The id of the project. | ## Response Schema ```none Status: 200 ``` ```json { "id": int, "project_id": int, "owner_id": int, "name": string, "description": string, "version": string, "release_notes": string, "thumbnails": { "s": string, "m": string, "l": string, "xl": string }, "size": int, "views": int, "completed_at": date, "created_at": date, "modified_at": date, "url": string } ``` ## Errors | Code | Description | | ---- | ----------------------------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 404 | Project does not have a primary app | | 404 | App not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Apps - Get project apps URL: https://developer.playcanvas.com/user-manual/api/app-get-project/ ## Route URL ```none GET https://playcanvas.com/api/projects/:projectId/apps ``` ## Description Lists all the published Apps of a Project. ## Example ```none curl -H "Authorization: Bearer {accessToken}" https://playcanvas.com/api/projects/{projectId}/apps ``` ## Parameters | Name | Type | Description | | ----------- | -------- | ---------------------- | | `projectId` | `number` | The id of the project. | ## Response Schema ```none Status: 200 ``` ```json { "result": [{ "id": int, "project_id": int, "owner_id": int, "name": string, "description": string, "version": string, "release_notes": string, "thumbnails": { "s": string, "m": string, "l": string, "xl": string }, "size": int, "views": int, "completed_at": date, "created_at": date, "modified_at": date, "url": string }, ... ], "pagination": { ... } } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Apps - Get app URL: https://developer.playcanvas.com/user-manual/api/app-get/ ## Route URL ```none GET https://playcanvas.com/api/apps/:id ``` ## Description Gets a published App by id. ## Example ```none curl -H "Authorization: Bearer {accessToken}" https://playcanvas.com/api/apps/{id} ``` ## Parameters | Name | Type | Description | | ---- | -------- | ------------------ | | `id` | `number` | The id of the app. | ## Response Schema ```none Status: 200 ``` ```json { "id": int, "project_id": int, "owner_id": int, "name": string, "description": string, "version": string, "release_notes": string, "thumbnails": { "s": string, "m": string, "l": string, "xl": string }, "size": int, "views": int, "completed_at": date, "created_at": date, "modified_at": date, "url": string } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | App not found | | 404 | Project not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Assets - Create asset URL: https://developer.playcanvas.com/user-manual/api/asset-create/ ## Route URL ```none POST https://playcanvas.com/api/assets ``` ## Description Create a new asset. :::note This endpoint currently only supports creating `script`, `html`, `css`, `text`, `shader` and `json` type assets. ::: **Unlike other REST API endpoints. The Create Asset endpoint expects data to be sent in `multipart/form-data`** ## Example ```none curl -H "Authorization: Bearer {accessToken}" -X POST -F 'name={name}' -F 'projectId={projectId}' -F 'parent={parent}' -F 'preload={preload}' -F 'pow2={pow2}' -F 'file=@./script.js' "https://playcanvas.com/api/assets" ``` HTTP Request ```text POST https://playcanvas.com/api/assets Authorization: Bearer {accessToken} Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryTdsfsfT ------WebKitFormBoundaryTdsfsfT Content-Disposition: form-data; name="projectId" {projectId} ------WebKitFormBoundaryTdsfsfT Content-Disposition: form-data; name="branchId" {branchId} ------WebKitFormBoundaryTdsfsfT Content-Disposition: form-data; name="parent" {parent} ------WebKitFormBoundaryTdsfsfT Content-Disposition: form-data; name="preload" {preload} ------WebKitFormBoundaryTdsfsfT Content-Disposition: form-data; name=""; filename="script.js" Content-Type: application/javascript {fileContent} ------WebKitFormBoundaryTdsfsfT-- ``` ## Parameters | Name | Type | Required | Description | | ----------- | --------- | :------: | ----------------------------------------------------------------------------------------------------------- | | `name` | `string` | ✔️ | The name of the asset. | | `projectId` | `number` | ✔️ | The id of the project. | | `branchId` | `string` | ✔️ | The id of the branch. | | `parent` | `number` | | Parent asset's id. | | `preload` | `boolean` | | Preload the asset (true / false). | | `file` | `file` | | Data to store as the asset file. | | `pow2` | `boolean` | | Only used for textures and defaults to false. Resize the texture to power of two dimensions (true / false). | ## Response Schema ```none Status: 201 ``` ```json { "id": int, "modifiedAt": date, "createdAt": date, "state": "ready" | "processing" | "error", "name": string, "type": string, "scope":{ "type": string, "id": int }, "source": bool, "sourceId": bool, "tags": list of strings, "preload": bool, "data": { ... asset data }, "file": { "hash": string, "filename": string, "size": int, "url": string }, "parent": int } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 429 | Too many requests | ## Rate Limiting This route uses an [assets](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Assets - Delete asset URL: https://developer.playcanvas.com/user-manual/api/asset-delete/ ## Route URL ```none GET https://playcanvas.com/api/assets/:assetId?branchId=:branchId ``` ## Description Permanently delete an asset from a branch of your project. :::warning Deleting an asset is permanent and unrecoverable unless you have taken a checkpoint of it. ::: ## Example ```none curl -H "Authorization: Bearer {accessToken}" -X DELETE "https://playcanvas.com/api/assets/{assetId}?branchId={branchId}" ``` HTTP Request ```text DELETE https://playcanvas.com/api/assets/{assetId}?branchId={branchId} Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Required | Description | | ---------- | -------- | :------: | ---------------------------------------------- | | `assetId` | `number` | ✔️ | The id of the asset to delete. | | `branchId` | `string` | ✔️ | The id of the branch to delete the asset from. | ## Response Schema ```none Status: 200 ``` ## Errors | Code | Description | | ---- | -------------------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project or Asset not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Assets - Get Asset File URL: https://developer.playcanvas.com/user-manual/api/asset-file/ ## Route URL ```none GET https://playcanvas.com/api/assets/:assetId/file/:filename?branchId=:branchId ``` ## Description Get the details of a single asset ## Example ```none curl -H "Authorization: Bearer {accessToken}" "https://playcanvas.com/api/assets/{assetId}/file/{filename}?branchId={branchId}" ``` HTTP Request ```text GET https://playcanvas.com/api/assets/{assetId}/file/{filename}?branchId={branchId} Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Required | Description | | ---------- | -------- | :------: | -------------------------- | | `assetId` | `number` | ✔️ | The id of the asset. | | `branchId` | `string` | ✔️ | The id of the branch. | | `filename` | `string` | ✔️ | The filename of the asset. | ## Response Schema ```none Status: 200 ``` ```none {fileContents} ``` ## Errors | Code | Description | | ---- | -------------------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project or Asset not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Assets - Get Asset URL: https://developer.playcanvas.com/user-manual/api/asset-get/ ## Route URL ```none GET https://playcanvas.com/api/assets/:assetId?branchId=:branchId ``` ## Description Get the details of a single asset ## Example ```none curl -H "Authorization: Bearer {accessToken}" https://playcanvas.com/api/assets/{assetId}?branchId={branchId} ``` HTTP Request ```text GET https://playcanvas.com/api/assets/{assetId}?branchId={branchId} Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Required | Description | | ---------- | -------- | :------: | --------------------- | | `assetId` | `number` | ✔️ | The id of the asset. | | `branchId` | `string` | ✔️ | The id of the branch. | ## Response Schema ```none Status: 200 ``` ```json { "id": int, "modifiedAt": date, "createdAt": date, "state": "ready" | "processing" | "error", "name": string, "type": string, "scope":{ "type": string, "id": int }, "source": bool, "sourceId": bool, "tags": list of strings, "preload": bool, "file": { "hash": string, "filename": string, "size": int, "url": string }, "parent": int } ``` ## Errors | Code | Description | | ---- | -------------------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project or Asset not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Assets - List assets URL: https://developer.playcanvas.com/user-manual/api/asset-list/ ## Route URL ```none GET https://playcanvas.com/api/projects/:projectId/assets?branchId=:branchId&skip=:skip&limit=:limit ``` ## Description Get the details of all assets in a project for a specific branch ## Example ```none curl -H "Authorization: Bearer {accessToken}" "https://playcanvas.com/api/projects/{projectId}/assets?branchId={branchId}&skip={number}&limit={number}" ``` HTTP Request ```text GET https://playcanvas.com/api/projects/{projectId}/assets?branchId={branchId}&skip={number}&limit={number} Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Required | Description | | ----------- | ---------- | :------: | ---------------------------------------------------------------------------- | | `projectId` | `number` | ✔️ | The id of the project. | | `branchId` | `string` | ✔️ | The id of the branch. | | `skip` | `number` | | Number of assets to skip before listing. Used for pagination. Defaults to 0. | | `limit` | `number` | | Maximum number of assets to list. Defaults to 16. Maximum 100000. | ## Response Schema ```none Status: 200 ``` ```json { "result": [{ "id": int, "modifiedAt": date, "createdAt": date, "state": "ready" | "processing" | "error", "name": string, "type": string, "scope":{ "type": string, "id": int }, "source": bool, "sourceId": bool, "tags": list of strings, "preload": bool, "file": { "hash": string, "filename": string, "size": int, "url": string }, "parent": int }, ...], "pagination": { "skip": int, "limit": int, "total": int, } } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Assets - Update asset URL: https://developer.playcanvas.com/user-manual/api/asset-update/ ## Route URL ```none PUT https://playcanvas.com/api/assets/:assetId ``` ## Description Update an existing asset's file. :::note This endpoint currently only supports updating `script`, `html`, `css`, `text`, `shader` and `json` type assets. ::: **Unlike other REST API endpoints. The Update Asset endpoint expects data to be sent in `multipart/form-data`** ## Example ```none curl -H "Authorization: Bearer {accessToken}" -X PUT -F 'pow2={pow2}' -F 'file=@./script.js' "https://playcanvas.com/api/assets/{assetId}" ``` ## Parameters | Name | Type | Required | Description | | ---------- | --------- | :------: | ----------------------------------------------------------------------------------------------------------- | | `assetId` | `number` | ✔️ | The id of the asset. | | `file` | `file` | ✔️ | Data to update asset file with. | | `pow2` | `boolean` | | Only used for textures and defaults to false. Resize the texture to power of two dimensions (true / false). | ## Response Schema ```none Status: 200 ``` ```json { "id": int, "modifiedAt": date, "createdAt": date, "state": "ready" | "processing" | "error", "name": string, "type": string, "scope":{ "type": string, "id": int }, "source": bool, "sourceId": bool, "tags": list of strings, "preload": bool, "data": { ... asset data }, "file": { "hash": string, "filename": string, "size": int, "url": string }, "parent": int } ``` ## Errors | Code | Description | | ---- | -------------------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project or Asset not found | | 429 | Too many requests | ## Rate Limiting This route uses an [assets](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Branches - Create branch URL: https://developer.playcanvas.com/user-manual/api/branch-create/ ## Route URL ```none POST https://playcanvas.com/api/branches ``` ## Description Create a new branch from an existing branch and optionally from a specific checkpoint. ## Example ```none curl -H "Authorization: Bearer {accessToken}" -H "Content-Type: application/json" -X POST -d '{"projectId": {projectId}, "name": "My New Branch", "sourceBranchId": "{sourceBranchId}"}' "https://playcanvas.com/api/branches" ``` HTTP Request ```text POST https://playcanvas.com/api/branches Authorization: Bearer {accessToken} Content-Type: application/json { "projectId": {projectId}, "name": "My New Branch", "sourceBranchId": "{sourceBranchId}" } ``` ## Parameters | Name | Type | Required | Description | | ---------------------- | -------- | :------: | -------------------------------------------------------------------------------------------------------------------- | | `name` | `string` | ✔️ | The name of the new branch. Must be non-empty and cannot exceed 1000 characters. | | `projectId` | `number` | ✔️ | The id of the project. | | `sourceBranchId` | `string` | ✔️ | The id of the branch to create the new branch from. | | `sourceCheckpointId` | `string` | | The id of the checkpoint to create the new branch from. Must belong to the source branch. If not specified, the latest checkpoint of the source branch will be used. | ## Response Schema ```none Status: 201 Created ``` ```json { "id": string, "projectId": int, "name": string, "createdAt": date, "closed": bool, "permanent": bool, "latestCheckpointId": string, "user": { "id": int, "fullName": string, "username": string } } ``` ## Errors | Code | Description | | ---- | -------------------------------------------------- | | 400 | Invalid request / branch name already exists | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found / Branch not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Branches - List branches URL: https://developer.playcanvas.com/user-manual/api/branch-list/ ## Route URL ```none GET https://playcanvas.com/api/projects/:projectId/branches ``` ## Description Get a list of all open branches for a project ## Example ```none curl -H "Authorization: Bearer {accessToken}" "https://playcanvas.com/api/projects/{projectId}/branches" ``` HTTP Request ```text GET https://playcanvas.com/api/projects/{projectId}/branches Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Description | | ----------- | -------- | ---------------------- | | `projectId` | `number` | The id of the project. | ## Response Schema ```none Status: 200 ``` ```json { "result": [ { "id": string, "projectId": int, "name": "Branch Name", "createdAt": date, "closed": bool, "latestCheckpointId": string, "user": { "id": int, "fullName": string, "username": string } },, ...], "pagination": { "hasMore": bool } } ``` This endpoint uses a slightly different pagination method. If a response contains the value `hasMore: true` then additional results are available. Use `?skip=branchId` query parameter with the last received branch id to receive more branches in alphabetical order. ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Checkpoints - Create checkpoint URL: https://developer.playcanvas.com/user-manual/api/checkpoint-create/ ## Route URL ```none POST https://playcanvas.com/api/checkpoints ``` ## Description Start a job to create a new checkpoint for a branch. A checkpoint captures the current state of a branch so that it can be restored later. The request will return job details immediately. You can [poll the job by id](/user-manual/api/job-get) until its status is either `complete` or `error`. When the job is complete, its data will contain the created checkpoint. ## Example ```none curl -H "Authorization: Bearer {accessToken}" -H "Content-Type: application/json" -X POST -d '{"projectId": {projectId}, "branchId": "{branchId}", "description": "My checkpoint"}' "https://playcanvas.com/api/checkpoints" ``` HTTP Request ```text POST https://playcanvas.com/api/checkpoints Authorization: Bearer {accessToken} Content-Type: application/json { "projectId": {projectId}, "branchId": "{branchId}", "description": "My checkpoint" } ``` ## Parameters | Name | Type | Required | Description | | ------------- | -------- | :------: | -------------------------------------------------------------------------------- | | `projectId` | `number` | ✔️ | The id of the project. | | `branchId` | `string` | ✔️ | The id of the branch. | | `description` | `string` | ✔️ | A description for the checkpoint. Must be non-empty and cannot exceed 10,000 characters. | ## Response Schema ```none Status: 201 Created ``` ```json { "id": int, "created_at": date, "modified_at": date, "status": "running" | "complete" | "error", "messages": list of strings, "data": { "type": "checkpoint_create", "project_id": int, "branch_id": string, "user_id": int, "user": { "id": int, "fullName": string, "username": string }, "description": string } } ``` When the job is complete, the `data` field contains the created checkpoint: ```json { "id": string, "user": { "id": int, "fullName": string, "username": string }, "createdAt": date, "description": string } ``` ## Errors | Code | Description | | ---- | ------------------ | | 400 | Invalid request | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found / Branch not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Checkpoints - Get checkpoint URL: https://developer.playcanvas.com/user-manual/api/checkpoint-get/ ## Route URL ```none GET https://playcanvas.com/api/checkpoints/:id ``` ## Description Get a checkpoint by its id. ## Example ```none curl -H "Authorization: Bearer {accessToken}" "https://playcanvas.com/api/checkpoints/{id}" ``` HTTP Request ```text GET https://playcanvas.com/api/checkpoints/{id} Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Description | | ---- | -------- | ------------------------ | | `id` | `string` | The id of the checkpoint. | ## Response Schema ```none Status: 200 ``` ```json { "id": string, "user": { "id": int, "fullName": string, "username": string }, "createdAt": date, "description": string } ``` ## Errors | Code | Description | | ---- | -------------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Checkpoint not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Checkpoints - List checkpoints URL: https://developer.playcanvas.com/user-manual/api/checkpoint-list/ ## Route URL ```none GET https://playcanvas.com/api/branches/:branchId/checkpoints ``` ## Description Get a list of checkpoints for a branch, sorted by newest first. ## Example ```none curl -H "Authorization: Bearer {accessToken}" "https://playcanvas.com/api/branches/{branchId}/checkpoints" ``` HTTP Request ```text GET https://playcanvas.com/api/branches/{branchId}/checkpoints Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Required | Description | | ---------- | -------- | :------: | ----------------------------------------------------------------------------------------------------- | | `branchId` | `string` | ✔️ | The id of the branch. | | `limit` | `number` | | The maximum number of checkpoints to return. Cannot exceed 50. | | `skip` | `string` | | A checkpoint id. The result will only contain checkpoints that were created before this checkpoint. | ## Response Schema ```none Status: 200 ``` ```json { "result": [{ "id": string, "user": { "id": int, "fullName": string, "username": string }, "createdAt": date, "description": string }, ...], "pagination": { "hasMore": bool } } ``` This endpoint uses a slightly different pagination method. If a response contains the value `hasMore: true` then additional results are available. Use the `skip` query parameter with the id of the last received checkpoint to receive more results. ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Branch not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Jobs - Get job URL: https://developer.playcanvas.com/user-manual/api/job-get/ ## Route URL ```none GET https://playcanvas.com/api/jobs/:id ``` ## Description Gets a Job by id. ## Example ```none curl -H "Authorization: Bearer {accessToken}" "https://playcanvas.com/api/jobs/{id}" ``` ## Parameters | Name | Type | Description | | ---- | -------- | ------------------ | | `id` | `number` | The id of the job. | ## Response Schema ```none Status: 200 ``` ```json { "id": int, "created_at": date, "modified_at": date, "status": "running" | "complete" | "error", "messages": list of strings, "data": object - contents depend on the job } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Job not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Projects - Export project URL: https://developer.playcanvas.com/user-manual/api/project-export/ ## Route URL ```none POST https://playcanvas.com/api/projects/:id/export ``` ## Description This will allow you to download a zip export of your entire project. You can import that export from your Projects Dashboard to create a new project from it. More about importing projects [here](/user-manual/editor/projects/backup-and-export#restoring-projects). The request will start an export job and the job details will be returned in the response. You can [poll the job by id](/user-manual/api/job-get) until its status is either 'complete' or 'error'. When the job is done, its data will contain a URL to download the project export. ## Example ```none curl -H "Authorization: Bearer {accessToken}" -H "Content-Type: application/json" -X POST -d '{"branch_id": "99999999-9999-9999-9999-999999999999"}' "https://playcanvas.com/api/projects/{projectId}/export" ``` ## Parameters | Name | Type | Required | Description | | ----------- | -------- | :------: | -------------------------------------------------------------------------- | | `projectId` | `number` | ✔️ | The id of the project. | | `branch_id` | `string` | | The id of the branch. If no id is specified, the main branch will be used. | ## Response Schema ```none Status: 201 Created ``` ```json { "id": int, "created_at": date, "modified_at": date, "status": "running" | "complete" | "error", "messages": [ list of strings ], "data": { "project": { 'id': int }, "url": string } } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 404 | Owner not found | | 429 | Too many requests | ## Rate Limiting This route uses a [strict](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Scenes - List scenes URL: https://developer.playcanvas.com/user-manual/api/scene-list/ ## Route URL ```none GET https://playcanvas.com/api/projects/:projectId/scenes?branchId=:branchId ``` ## Description Get a list of all scenes for a project ## Example ```none curl -H "Authorization: Bearer {accessToken}" "https://playcanvas.com/api/projects/{projectId}/scenes?branchId={branchId}" ``` HTTP Request ```text GET https://playcanvas.com/api/projects/{projectId}/scenes?branchId={branchId} Authorization: Bearer {accessToken} ``` ## Parameters | Name | Type | Required | Description | | ----------- | -------- | :------: | -------------------------------------------------------------------------- | | `projectId` | `number` | ✔️ | The id of the project. | | `branchId` | `string` | | The id of the branch. If no id is specified, the main branch will be used. | ## Response Schema ```none Status: 200 ``` ```json { "result": [{ "id": int, "projectId": int, "name": string, "created": date, "modified": date }, ...] } ``` ## Errors | Code | Description | | ---- | ----------------- | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Project not found | | 429 | Too many requests | ## Rate Limiting This route uses a [normal](/user-manual/api#rate-limiting) rate limit. -------------------------------------------------------------------------------- ## Splat Publishing URL: https://developer.playcanvas.com/user-manual/api/splat-publish/ #### Overview Publish a splat (e.g., .ply or .sog) to the [SuperSplat platform](/user-manual/supersplat/) programmatically — the same backend used by the [Editor's Publish dialog](/user-manual/supersplat/editor/publishing) and the [Direct Upload](/user-manual/supersplat/upload) flow on superspl.at. Once published, the splat appears on the user's [Manage page](/user-manual/supersplat/manage) and can be opened in [Studio](/user-manual/supersplat/studio/) to curate its viewing experience. The `settings` field on the publish call carries the [Experience Settings](/user-manual/supersplat/studio/experience-settings) JSON — the same contract Studio writes and the [SuperSplat Viewer](/user-manual/supersplat/viewer/) reads. See that reference for the full schema. The flow consists of three main steps: 1. **Request a signed upload URL** from the backend. 2. **Upload the file** directly to S3 using that signed URL. 3. **Start the processing job** by calling the backend API. All API requests must include a valid Bearer token in the `Authorization` header. Check [this document](https://developer.playcanvas.com/user-manual/api/#:~:text=You%20can%20generate%20an%20Access,you%20your%20new%20access%20token) to read about allocating a token. ### Routes #### Get Signed URL for AWS S3 upload ```none POST https://playcanvas.com/api/upload/signed-url Body { "fileName": "scene.ply" } Response { "signedUrl": "string", "s3Key": "string" } ``` Example: ```javascript const response = await fetch(`https://playcanvas.com/api/upload/signed-url`, { method: 'POST', body: JSON.stringify({ fileName: filename }), headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); ``` #### Upload to AWS S3 using signed url ```none PUT "signedUrl" Response { "signedUrl": "string", "s3Key": "string" } ``` Example: ```javascript const uploadResponse = await fetch(signedUrl, { method: 'PUT', body: fileData, headers: { 'Content-Type': 'binary/octet-stream' } }); ``` #### Start processing ```none POST https://playcanvas.com/api/splats/publish Body { "s3Key": "string", "title": "string", "description": "string", "listed": boolean, "settings": { /* Settings */ }, "format": "compressed.ply" // or "sog" } Settings: const settings = { camera: { fov: 65, // field of view position: [1,1,-1], target: [-0.1,0.6,-0.2], startAnim: 'none', animTrack:null }, background: { color: [0.4,0.4,0.4] }, animTracks:[] }; Response (Splat data) { "id": "string", "hash": "string", "title": "string", "description": "string", "format": "compressed.ply | sog", "version": "string", "release_notes": "string", "thumbnails": number, "size": number, "views": number, "comments": number, "starred": number, "listed": boolean, "completedAt": DateTime, "createdAt": DateTime, "modifiedAt": DateTime } ``` Example: ```javascript const response = await fetch(`https://playcanvas.com/api/splats/publish`, { method: 'POST', body: JSON.stringify({ s3Key: s3Key, title: 'Some Title', description: 'Some Description', listed: true, settings: settings, format: format }), headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); ``` Sample response ```json { "comments": 0, "completedAt": null, "createdAt": "2025-10-21T12:42:13.331Z", "currentVersion": 1, "description": "Some Description", "featuredWeight": 0, "format": "", "hash": "982a2820", "hasThumbnails": false, "id": 50, "listed": true, "modifiedAt": "2025-10-21T12:42:13.331Z", "releaseNotes": null, "size": 0, "starred": 0, "tags": [], "task": { "status": "running", "message": "" }, "title": "Some Title", "url": "https://superspl.at/view?id=982a2820", "userId": 7, "version": 0, "views": 0 } ``` Status - 201 Success #### Check the status of uploaded splat ```none GET https://playcanvas.com/api/splats/{ID} Response (Splat) { "id": "string", "hash": "string", "title": "string", "description": "string", "format": "compressed.ply | sog" } ``` Example: ```javascript const response = await fetch(`https://playcanvas.com/api/splats/1000`) ``` Errors | Code | Description | |------|-------------| | 400 | Bad request / invalid payload / over storage allowance | | 401 | Unauthorized (missing/invalid token) | | 403 | Forbidden | | 404 | Resource not found (e.g., sceneId) | | 5xx | Server/S3 error during upload or finalize | -------------------------------------------------------------------------------- ## Assets URL: https://developer.playcanvas.com/user-manual/assets/ Assets are the building blocks of your PlayCanvas application. They represent all the external resources your application needs, such as 3D models, textures, audio files, and scripts. ## Assets vs Resources In PlayCanvas, there's an important distinction between **Assets** and **Resources**: - **Asset** - A record in the asset registry that contains metadata about a resource, including its name, type, tags, and a reference to the underlying resource data. Assets are managed by the [`AssetRegistry`](asset-registry). - **Resource** - The actual runtime data that gets loaded into memory and used by the engine. For example, a texture asset's resource is the actual image data that can be applied to materials. When you load an asset, PlayCanvas downloads and parses the underlying file to create the resource. The asset object then holds a reference to this resource via its `resource` property. ```javascript const asset = this.app.assets.find('my-texture'); asset.ready((asset) => { const texture = asset.resource; // The actual Texture object }); this.app.assets.load(asset); ``` ## Asset Lifecycle Assets go through several stages during the lifetime of your application: 1. **Registry** - Assets are registered in the [`AssetRegistry`](asset-registry), making them discoverable by ID, name, or tags 2. **Loading** - Asset data is downloaded from the server 3. **Ready** - The resource is parsed and available for use 4. **Unloading** - Resources can be unloaded to free memory For details on controlling when assets load, see [Preloading](preloading) and [Loading and Unloading](loading-unloading). ## Supported Formats PlayCanvas supports a wide variety of file formats for different asset types. See [Supported Formats](supported-formats) for a complete list. ## Working with Assets ### In the Editor If you're using the PlayCanvas Editor, see the [Editor Assets Guide](/user-manual/editor/assets/) for information on: - Importing and organizing assets - Configuring asset properties - Using the Asset Store ### Programmatically For working with assets in code: - **[Asset Registry](asset-registry)** - Find and manage assets at runtime - **[Preloading](preloading)** - Control which assets load before your app starts - **[Loading and Unloading](loading-unloading)** - Dynamically load assets during runtime ## Finding Assets Looking for 3D models, textures, or audio for your project? See [Finding Assets](finding) for a list of asset marketplaces and resources. -------------------------------------------------------------------------------- ## Asset Registry URL: https://developer.playcanvas.com/user-manual/assets/asset-registry/ The [`AssetRegistry`](https://api.playcanvas.com/engine/classes/AssetRegistry.html) is the central system for managing assets in PlayCanvas. It maintains a collection of all assets available to your application and provides methods to find, load, and manage them. ## Accessing the Registry The asset registry is available via the application object: ```javascript const assets = this.app.assets; ``` ## Finding Assets ### By ID Every asset has a unique numeric ID. This is the most reliable way to reference an asset: ```javascript const asset = this.app.assets.get(123456); ``` ### By Name Find an asset by its name. Returns the first matching asset: ```javascript const asset = this.app.assets.find('My Texture'); ``` Find all assets with a given name: ```javascript const assets = this.app.assets.findAll('Enemy'); ``` ### By Tag Assets can be tagged for easy grouping. Find all assets with a specific tag: ```javascript const levelAssets = this.app.assets.findByTag('level-1'); ``` Find assets matching multiple tags (AND logic): ```javascript // Assets tagged with BOTH 'level-1' AND 'enemy' const enemies = this.app.assets.findByTag('level-1', 'enemy'); ``` Find assets matching any of several tags (OR logic): ```javascript // Assets tagged with 'level-1' OR 'level-2' const assets = this.app.assets.findByTag(['level-1', 'level-2']); ``` ## Asset Events The registry emits events when assets are added, removed, or loaded: ### Registry Events ```javascript // Asset added to registry this.app.assets.on('add', (asset) => { console.log('Asset added:', asset.name); }); // Asset removed from registry this.app.assets.on('remove', (asset) => { console.log('Asset removed:', asset.name); }); // Asset loaded this.app.assets.on('load', (asset) => { console.log('Asset loaded:', asset.name); }); // Asset failed to load this.app.assets.on('error', (err, asset) => { console.error('Failed to load:', asset.name, err); }); ``` ### Individual Asset Events You can also listen for events on specific assets: ```javascript const asset = this.app.assets.find('My Texture'); // Called when the asset's resource is ready asset.on('load', (asset) => { console.log('Texture loaded:', asset.resource); }); // Called if loading fails asset.on('error', (err, asset) => { console.error('Failed:', err); }); // Called when the asset is removed from the registry asset.on('remove', (asset) => { console.log('Asset removed'); }); // Called when any property changes asset.on('change', (asset, property, newValue, oldValue) => { console.log(`${property} changed from ${oldValue} to ${newValue}`); }); ``` ### Using ready() The `ready()` method is a convenient way to execute code when an asset is loaded. If the asset is already loaded, the callback fires immediately: ```javascript const asset = this.app.assets.find('My Texture'); asset.ready((asset) => { // Asset is guaranteed to be loaded here const texture = asset.resource; material.diffuseMap = texture; }); // Make sure to trigger loading if not already loaded this.app.assets.load(asset); ``` ## Adding Assets at Runtime You can create and add new assets to the registry at runtime: ```javascript const asset = new pc.Asset('New Texture', 'texture', { url: 'path/to/texture.png' }); this.app.assets.add(asset); this.app.assets.load(asset); ``` ## See Also - [Preloading](preloading.md) - Control which assets load before your app starts - [Loading and Unloading](loading-unloading.md) - Dynamically manage asset loading - [`AssetRegistry` API Reference](https://api.playcanvas.com/engine/classes/AssetRegistry.html) -------------------------------------------------------------------------------- ## Custom Asset Parsers URL: https://developer.playcanvas.com/user-manual/assets/custom-parsers/ Every asset type in PlayCanvas is loaded by a **resource handler** — one per asset type (`'texture'`, `'model'`, `'audio'` and so on). Within a handler, the individual file formats are handled by **parsers**: the texture handler, for example, has parsers for browser images, DDS, KTX2 and Basis. Handlers expose a public registry for these parsers, so you can add support for a new file format — or override a built-in one — without modifying the engine. :::note Custom parsers are available from **engine v2.21.0**. They are an engine runtime API: parsers run in your application at load time and do not affect the Editor's asset import pipeline. ::: ## How asset loading works When an asset is loaded, the [`ResourceLoader`](https://api.playcanvas.com/engine/classes/ResourceLoader.html) looks up the [`ResourceHandler`](https://api.playcanvas.com/engine/classes/ResourceHandler.html) registered for the asset's type. The handler then selects a parser by asking each registered parser, **newest-first**, whether it recognizes the resource: 1. The handler builds a context describing the resource (its URL, file extension and so on) 2. The most recently registered parser whose `canParse(context)` returns `true` is selected 3. The parser's `load()` fetches the file and delivers its data 4. The parser's `open()` converts that data into the runtime resource (a `Texture`, a `Model`, ...) Because selection is newest-first, a parser you register later takes precedence over the built-in ones for any resource it claims. ## The parser contract A parser is a plain object or class instance with the following methods: ```javascript class MyParser { // return true if this parser handles the described resource canParse(context) { return context.ext === 'myformat'; } // fetch the resource and deliver its raw data via callback(err, data) load(url, callback, asset) { this.handler.fetch(url, pc.Http.ResponseType.ARRAY_BUFFER, callback, asset); } // optional: convert the loaded data into the runtime resource open(url, data, asset) { return data; } } ``` The `context` passed to `canParse` describes the resource being loaded: | Property | Description | | ---------- | ---------------------------------------------------------------------------- | | `url` | The original resource URL, with any query string removed (or `null`) | | `ext` | The lower-cased file extension without the leading dot, for example `'tga'` | | `basename` | The lower-cased file name, for example `'lod-meta.json'` | | `asset` | The [`Asset`](https://api.playcanvas.com/engine/classes/Asset.html) being loaded, if any | | `app` | The running [`AppBase`](https://api.playcanvas.com/engine/classes/AppBase.html) | When a parser is registered, the handler assigns itself to the parser's `handler` property. This gives `load()` access to `this.handler.fetch(url, responseType, callback, asset)` — a helper that downloads the resource with the handler's retry settings and reuses pre-fetched data when available — as well as any handler state (for example `this.handler.app`). ## Registering a parser Parsers are registered on the handler for their asset type: ```javascript app.loader.getHandler('texture').addParser(new TgaParser()); ``` Register parsers before starting any loads for that asset type. A registered parser can be removed again with `removeParser(parser)`, and the currently registered parsers can be inspected via the read-only `parsers` property. Since selection is newest-first, registering a parser that claims a format already covered by a built-in parser overrides the built-in — this works for specific extensions as well as for catch-all parsers. ## Example: a TGA texture parser The engine does not load `.tga` files at runtime. A custom parser adds support: ```javascript class TgaParser { canParse(context) { return context.ext === 'tga'; } load(url, callback, asset) { this.handler.fetch(url, pc.Http.ResponseType.ARRAY_BUFFER, callback, asset); } // texture parsers use an extended open signature: the handler passes the graphics // device and the texture options derived from the asset's data open(url, data, device, textureOptions) { // decode the TGA file into RGBA8 pixels (using your decoder of choice) const { width, height, pixels } = decodeTga(data); const texture = new pc.Texture(device, { name: url, width: width, height: height, format: pc.PIXELFORMAT_RGBA8, levels: [pixels], // spread the asset-derived options last, so that asset settings // (srgb, filtering, mipmaps, ...) override the defaults above ...textureOptions }); texture.upload(); return texture; } } app.loader.getHandler('texture').addParser(new TgaParser()); ``` With the parser registered, `.tga` files load like any other texture: ```javascript const asset = new pc.Asset('picture', 'texture', { url: 'images/picture.tga' }, { srgb: true }); app.assets.add(asset); app.assets.load(asset); ``` For a complete, runnable example of a custom **model** parser, see the engine's [OBJ parser](https://github.com/playcanvas/engine/blob/main/scripts/parsers/obj-model.js) and the [OBJ loader example](https://playcanvas.github.io/#/loaders/obj) that uses it. ## Handler notes Most format-bearing handlers participate in the parser registry: `model`, `texture`, `material`, `gsplat`, `container`, `animation`, `animclip`, `animstategraph`, `template`, `audio`, `json`, `css`, `html`, `text`, `shader` and `binary`. A few details vary by asset type: - **texture** — parsers implement the extended `open(url, data, device, textureOptions)` shown above. The built-in browser image parser is a catch-all, so unknown extensions fall back to it unless your parser claims them. - **material** — the handler's asset binding (assigning texture assets referenced by the material data) applies to `StandardMaterial` produced by the built-in JSON parser; materials produced by custom parsers manage their own asset references. - **audio** — the sound manager is available to parsers as `this.handler.manager`; a custom parser can decode to an `AudioBuffer` and return it wrapped in a `pc.Sound`. - Handlers that compose other assets rather than parse file formats (`cubemap`, `font`, `sprite`, `textureatlas`) and special-purpose handlers (`bundle`, `script`, `folder`) do not consult registered parsers. ## See Also - [`ResourceHandler` API Reference](https://api.playcanvas.com/engine/classes/ResourceHandler.html) - [`ResourceLoader` API Reference](https://api.playcanvas.com/engine/classes/ResourceLoader.html) - [Supported Formats](supported-formats.md) - [Loading and Unloading](loading-unloading.md) -------------------------------------------------------------------------------- ## Third-party Asset Sites URL: https://developer.playcanvas.com/user-manual/assets/finding/ ## Where can I get 3D models/Sound FX/Music for PlayCanvas? Sometimes it's important to make your own unique assets, but sometimes a completely bespoke asset is too expensive or time-consuming to make. So we've gathered together a list of links and resources for places that you can get free or paid-for assets of all types. If you've got other suggestions for this page. Then let us know on the [forum](https://forum.playcanvas.com/). ## Asset Marketplaces Asset marketplaces are online libraries of content that you can download, either for free or for a fee, and add to your PlayCanvas game. | Provider | 2D Art | 3D Art | Audio | |--------------------------------------------------------------------------|----------|----------|----------| | [3D Models Textures](https://www.3dmodels-textures.com/) | | ✓ | ✓ | | [BlendSwap](https://www.blendswap.com/) | | ✓ | | | [CGTrader](https://www.cgtrader.com/) | | ✓ | | | [Game Dev Market](https://www.gamedevmarket.net?ally=O0I9alFp) | ✓ | ✓ | ✓ | | [GameSounds.xyz](https://gamesounds.xyz/) | | | ✓ | | [Kenney](https://kenney.nl/) | ✓ | ✓ | ✓ | | [Mixamo](https://www.mixamo.com/) | | ✓ | | | [PlayOnLoop](https://www.playonloop.com/music-loops-category/videogame/) | | | ✓ | | [Open Game Art](https://opengameart.org/) | ✓ | ✓ | ✓ | | [Sound Bible](https://soundbible.com/) | | | ✓ | | [Turbosquid](https://www.turbosquid.com/) | ✓ | ✓ | ✓ | ## Procedural Generation Tools There are tools available that can generate game assets procedurally. Here are some good examples: * [Sound FX Generator](https://www.bfxr.net/) * [Spacescape Skybox Generator](http://alexcpeterson.com/spacescape) * [Sloyd 3D Model Generator](https://sloyd.ai) -------------------------------------------------------------------------------- ## Loading and Unloading URL: https://developer.playcanvas.com/user-manual/assets/loading-unloading/ PlayCanvas provides APIs to dynamically load and unload assets at runtime. This gives you fine-grained control over memory usage and allows you to stream content as needed. ## Loading Assets ### Loading Registered Assets For assets that are already in the asset registry (e.g., assets added in the Editor), use `app.assets.load()`: ```javascript const asset = this.app.assets.find('My Texture'); asset.ready((asset) => { // Asset is loaded and ready to use const texture = asset.resource; }); this.app.assets.load(asset); ``` ### Loading from URL To load an asset from a URL at runtime, use `app.assets.loadFromUrl()`: ```javascript this.app.assets.loadFromUrl('path/to/texture.png', 'texture', (err, asset) => { if (err) { console.error('Failed to load texture:', err); return; } // Asset is loaded and added to the registry const texture = asset.resource; }); ``` The second parameter specifies the asset type. Common types include: - `texture` - Images (PNG, JPG, WebP, etc.) - `model` - 3D models (GLB) - `audio` - Sound files (MP3, OGG, WAV) - `json` - JSON data - `binary` - Binary data - `css` - Stylesheets - `html` - HTML documents - `script` - JavaScript files - `shader` - Shader code ### Loading with Options You can pass additional options when loading from URL: ```javascript this.app.assets.loadFromUrlAndFilename( 'path/to/model.glb', 'model.glb', 'container', (err, asset) => { if (err) { console.error('Failed to load model:', err); return; } // Create an entity from the loaded model const entity = asset.resource.instantiateRenderEntity(); this.app.root.addChild(entity); } ); ``` ## Handling Load Events ### Using ready() The `ready()` method executes a callback when an asset is loaded. If the asset is already loaded, the callback fires immediately: ```javascript const asset = this.app.assets.find('My Model'); asset.ready((asset) => { // Safe to use asset.resource here }); // Trigger loading if not already loaded if (!asset.loaded) { this.app.assets.load(asset); } ``` ### Using Events You can listen for load events on individual assets or the registry: ```javascript // Listen on a specific asset asset.on('load', (asset) => { console.log('Asset loaded:', asset.name); }); asset.on('error', (err, asset) => { console.error('Load failed:', asset.name, err); }); // Listen on the registry for any asset this.app.assets.on('load', (asset) => { console.log('Some asset loaded:', asset.name); }); ``` ## Configuring Retries Asset loads are automatically retried on failure to make applications more resilient to transient network errors (e.g. slow CDNs, brief connectivity drops). By default, the engine retries each failed request up to **5 times** with exponential backoff (200ms, 400ms, 800ms, 1600ms, 3200ms, capped at 5000ms). You can change this globally for all asset types: ```javascript // Override the default retry count this.app.loader.enableRetry(3); // Disable retries entirely - load failures are reported immediately this.app.loader.disableRetry(); ``` Or configure retries per asset type: ```javascript // Only retry texture loads more aggressively this.app.loader.getHandler('texture').maxRetries = 10; ``` Editor projects can also override the default count via the [Network Settings](../editor/interface/settings/network.md) panel. ## Limiting Concurrent Requests When an application loads a large number of assets at once, browsers can reject requests with `net::ERR_INSUFFICIENT_RESOURCES` once too many are in flight simultaneously. To guard against this, the engine limits the number of concurrent asset requests, queuing any beyond the limit and dispatching them as earlier requests complete. The default limit is **128**, which is safe across browsers while still saturating typical CDN throughput. You can change it globally: ```javascript // Allow at most 50 asset requests to be in flight at once this.app.loader.maxConcurrentRequests = 50; // Disable throttling entirely - every request is sent immediately this.app.loader.maxConcurrentRequests = 0; ``` :::note This is a process-global limit (it applies to the shared HTTP layer, matching the browser's per-process resource limit), so with multiple applications on a page the last value set wins. It applies to all `XMLHttpRequest`-based loads, which covers the large majority of assets. ::: Editor projects can also configure this via the [Network Settings](../editor/interface/settings/network.md) panel. ## Loading with Credentials By default, asset requests are sent without credentials. If your assets are served from an authenticated cross-origin host - one that requires cookies, client TLS certificates or HTTP authentication - enable credentials globally: ```javascript // Send all asset requests with credentials this.app.loader.withCredentials = true; ``` Set this **before** preloading or loading any assets, so the requests pick it up. The server must respond with a non-wildcard `Access-Control-Allow-Origin` and `Access-Control-Allow-Credentials: true`, otherwise the browser blocks the response. :::note This is a process-global setting (it applies to the shared HTTP layer), so with multiple applications on a page the last value set wins. It applies to all `XMLHttpRequest`-based loads, which covers the large majority of assets. ::: ## Unloading Assets To free memory, you can unload assets that are no longer needed: ```javascript const asset = this.app.assets.find('Large Texture'); // Unload the resource but keep the asset in the registry asset.unload(); // The asset can be loaded again later this.app.assets.load(asset); ``` ### Removing Assets To completely remove an asset from the registry: ```javascript const asset = this.app.assets.find('Temporary Asset'); // Remove from registry (also unloads the resource) this.app.assets.remove(asset); ``` ## Loading Multiple Assets To load multiple assets and wait for all of them: ```javascript const assetNames = ['texture1', 'texture2', 'model1']; const assets = assetNames.map(name => this.app.assets.find(name)); let loaded = 0; const total = assets.length; const onAssetLoad = () => { loaded++; if (loaded === total) { // All assets loaded this.onAllAssetsReady(); } }; for (const asset of assets) { asset.ready(onAssetLoad); if (!asset.loaded) { this.app.assets.load(asset); } } ``` ## Best Practices - **Unload unused assets** - Free memory by unloading assets when changing levels or scenes - **Use ready()** - It handles both loaded and not-yet-loaded cases - **Handle errors** - Always provide error handling for dynamic loads - **Batch loads** - Load related assets together to avoid visual inconsistencies ## See Also - [Asset Registry](asset-registry.md) - Finding and managing assets - [Preloading](preloading.md) - Loading assets before your app starts -------------------------------------------------------------------------------- ## Importing 3D Models URL: https://developer.playcanvas.com/user-manual/assets/models/ 3D models and animations are imported into PlayCanvas by uploading scene files from a [3D modeling application](/user-manual/assets/models/building) such as [Blender](https://www.blender.org/), 3D Studio Max or Maya. PlayCanvas supports a wide variety of formats, such as glTF binary (GLB), FBX, COLLADA and obj. We recommend using the GLB format for best results. Uploading one of these files will create a [Source Asset](/user-manual/glossary#source-asset) of type 'Model' and will produce several [Target Assets](/user-manual/glossary#target-asset) including a '[Template](/user-manual/editor/assets/inspectors/template/)' with the model hierarchy and 'Render' assets. You can add an instance of the 'Template' in your game. Learn more about: * [Building Models](/user-manual/assets/models/building) * [Exporting Models](/user-manual/assets/models/exporting) * [Importing Models](/user-manual/editor/assets/import-pipeline/import-hierarchy/) * [Using Templates](/user-manual/editor/templates/) -------------------------------------------------------------------------------- ## Building Models URL: https://developer.playcanvas.com/user-manual/assets/models/building/ Building art and animations for PlayCanvas can be done using almost any of the many 3D modeling programs available. For example: Blender, SketchUp, Autodesk 3D Studio Max or Autodesk Maya. PlayCanvas is designed to import content most faithfully via the open source glTF binary (GLB) format so, in general, if your modeling application supports GLB, PlayCanvas supports it too. The import of GLBs supports the following glTF features for incredibly fast scene creation: - Node hierarchy - Standard material - Ratified material extensions - Animated skeletons and skinning data - Morph targets - Cameras - Draco compressed models - Punctual light support As such, to target PlayCanvas, you do not have to use any special art tool plugins and there are no PlayCanvas-specific workflows you must follow. [Image: GLB Import Example] *Model by Loïc Norgeot and mosquito scan by Geoffrey Marchal for [Sketchfab](https://sketchfab.com/3d-models/real-time-refraction-demo-mosquito-in-amber-37233d6ed84844fea1ebe88069ea58d1) licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)* PlayCanvas also supports the importing of FBX files which is another common interchange format. However, FBX materials are not imported as faithfully as glTF materials and might require some editing after import. We recommend using GLBs whenever possible for the best experience and highest compatibility. Some modeling and animation programs to consider: - Free options: Blender\*, Wings3D, Voidworld, SketchUp, Sculptris, Daz Studio\*. - Lower-cost paid options: 3D-Coat, NVIL, Hexagon. - Higher-cost paid options: ZBrush, Autodesk 3D Studio Max\*, Autodesk Maya\*, Luxology Modo\*. \* *this program can create animations too.* For generating textures, consider these programs: - Free: Blender, Pixexix Free, xNormal, MaPZone, GIMP, Krita desktop, MyPaint. - Paid: Substance Designer (as well as Substance Painter and Bitmap2Material), Photoshop, Quixel NDO and DDO, CrazyBump, Pixexix Pro, Clip Studio Paint/Manga Studio, SERIF DrawPlus/PhotoPlus. Note many of the programs listed above for modeling also allow texture painting. If you would like more options, this [external wiki](http://wiki.polycount.com/wiki/Tools) page can help. Please note that some of the information may be out-of-date. ## General Considerations for Mesh Construction Regardless which modeling application you are using, there are a number of things to be aware of when building 3D scenes intended for PlayCanvas. - Meshes can be skinned to up to 256 bones. - NURBS meshes will be converted to triangle meshes on conversion to the PlayCanvas native format. --- ## Blender [Image: Blender Logo] [Blender](https://www.blender.org/) is a fantastic free tool for 3D modeling and it is perfect for generating 3D assets for PlayCanvas. Blender supports exporting to GLB, FBX and COLLADA but the built-in exporters do have some limitations. ### **Map Types** As of Blender 2.71, both diffuse and normal maps of your material will be exported to the FBX file. If other map types are lost on export you have to set-up these maps in the Material Editor within the Editor. ### **Embedding Textures** Embedded Textures make importing much easier. The Blender COLLADA exporter does not have the ability to embed textures into the exported model file. The 2.71 release of Blender features a revamped FBX export module that enables multiple embedded textures directly from Blender. First make sure the object is rendered correctly within Blender. When exporting to FBX, set the 'Path Mode' to Copy and check the 'Embed Textures' box. Alternatively, use the [Autodesk FBX Converter](https://www.autodesk.com/developer-network/platform-technologies/fbx-converter-archives) to convert an export from Blender into one with embedded media. Just open the file in the FBX Converter and re-save with the *Embedded Media* checkbox set. :::warning There seems to be an issue with Blender 2.71's FBX export generating emissivity despite no emissive properties being set in Blender - this is not an issue with the PlayCanvas engine. To avoid this from within Blender, you can change the material's Diffuse color setting to 0 (under the 'Material' tab in the 'Properties Editor'). Or simply reduce emissivity from within the PlayCanvas Editor. ::: ### **Animations** As of Blender 2.71: Animations included within the blend file are exported with the default fbx exporter settings and are compatible with the PlayCanvas asset import pipeline. Note that for multiple animations for the same model you will need to upload multiple fbx files - one for each animation. To save memory you can delete models and textures from the blend file before exporting, choose to export only armatures in the fbx exporter settings, or simply delete the duplicate 'model' target assets from the assets page on your project dashboard (select 'target' from the drop-down menu on the assets page to view target assets). ### **Learning Blender** There are plenty of resources for learning how to use Blender on the web. A couple that we recommend are: - [Blender Cookie](https://cgcookie.com/learn-blender) - [Blender Guru](https://www.blenderguru.com/) --- ## Autodesk 3D Studio Max ### Max Materials You should use the Standard material type in Max, or the Multi/Sub-Object material type providing the materials it references are Standard materials. The highlighted areas in the screenshot below show the settings that are respected when you export to PlayCanvas: [Image: Max material editor] ### Supported Map Slots PlayCanvas interprets a subset of the 3DS Max material map types on export. Note that maps can be in any format that 3DS Max supports, but if the maps are not in a web format (namely JPEG, GIF or PNG) then they will be converted to these formats on export. #### Diffuse Color Assigning a Bitmap map to this slot enables diffuse mapping on the PlayCanvas material. This essentially overrides whatever diffuse color has been set on the material (via the color picker). If the diffuse map has an alpha channel, it will be used as the per pixel alpha value in the PlayCanvas runtime. Additionally, it is possible to assign an RGB Multiply map to the Diffuse Color slot. This has the effect of enabling lightmapping, where Map 1 is the diffuse map and Map 2 is the lightmap. #### Specular Color Assigning a Bitmap map to this slot enables specular mapping in the PlayCanvas material. This essentially overrides whatever specular color has been set on the material (via the color picker). This allows you to mask out areas of specularity on a surface, or tinge specular highlights different colors in different areas. If the specular map has an alpha channel, it will be used to set per-pixel shininess. #### Specular Level Assigning a Bitmap map to this slot activates per-pixel attenuation of the material's specular color. This essentially overrides whatever specular level has been set on the material. #### Glossiness Assigning a Bitmap map to this slot activates per-pixel glossiness on the material. This essentially overrides whatever glossiness has been set on the material. #### Self-Illumination Assigning a Bitmap map to this slot enables emissive mapping in the PlayCanvas material. An emissive map can be full RGB (you are not limited to greyscale) and will essentially be added to the result of lighting a surface. So a black pixel in an emissive map will add nothing to a pixel's value. Anything else will increase a pixel's luminosity. #### Opacity Assigning a Bitmap map to this slot enables opacity mapping on the PlayCanvas material. A black pixel in the opacity map will be fully transparent, a white pixel will be fully opaque and any grey pixel will correspond to some equivalent intermediate alpha value. If the material has an opacity map, it will override any alpha channel that may have been set in the diffuse map. It is less efficient to use the opacity map slot over the alpha channel of the diffuse map since two textures are generated in the PlayCanvas runtime instead of one and the default shader must do a little more work. However, if performance is not a concern and it is convenient to use an opacity map, the functionality is supported. #### Bump Assigning a Normal Bump map to this slot enables normal mapping. Note that, by default, the 'Amount' value for the Bump slot is set to 30. PlayCanvas effectively ignores this value and treats it as if it were set to 100, so it is recommended that you set this to 100 in Max also in order to make a render match the real-time rendering more closely. There are different ways to author normal maps, the main two differing in the format of the green component. For example, by default, 3DS Max would expect a normal map for a brick wall to appear as follows: [Image: Normal map] Notice lighter areas at the bottom edge of raised areas. PlayCanvas expects the green component (or the Y component of each normal in the normal map) to be flipped. Loading the file into Photoshop, selecting the green channel and pressing Ctrl+I to invert the channel gives: [Image: Normal map with Y component flipped] Now, lighting in PlayCanvas will be consistent. If the assigned normal map has an alpha channel, it will be treated as a parallax map with the alpha channel interpreted as a height map. Lighter areas of the height map are treated as 'higher' than the darker areas. #### Reflection Assigning a Bitmap map to this slot enables sphere mapping in the PlayCanvas material. The bitmap would look something like this: [Image: Sphere map] Sphere mapping is one of the cheapest, least 'convincing' forms of reflection mapping, but in many scenarios it is sufficient to provide a pleasing glossy sheen to surfaces. --- ## Autodesk Maya ### Maya Materials You should use the standard material types in Maya: lambert, blinn and phong. The highlighted areas in the screenshot below show the material settings that are respected when you export to PlayCanvas: [Image: Maya material editor] -------------------------------------------------------------------------------- ## Exporting Assets URL: https://developer.playcanvas.com/user-manual/assets/models/exporting/ PlayCanvas can import 3D content in the following formats: glTF binary (GLB), FBX, OBJ, 3DS and COLLADA (DAE). We strongly recommend you use GLB as it's an open source industry standard and very well supported in the Editor. [Image: GLB Import Example] *Model by Loïc Norgeot and mosquito scan by Geoffrey Marchal for [Sketchfab](https://sketchfab.com/3d-models/real-time-refraction-demo-mosquito-in-amber-37233d6ed84844fea1ebe88069ea58d1) licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)* If GLB is not available, then please use FBX as it is a robust and well tested interchange industry format. ## General export tips * Only export what you need from your scene. For example, if your scene contains a red car and a blue car but you only want to import the red car, export only the red car. Your modeling application should have an 'Export Selected' or similar option. ## Tips for Exporting to GLB * Set the format to glTF Binary (GLB). * Ensure that materials and images are set to be exported and embedded in the GLB. Otherwise, you must upload all scene textures separately and relink all textures to materials and re-configure the materials parameters. ## Tips for Exporting to FBX * Ensure you have the latest available FBX exporter for your modelling application installed. * Select the 'Embed Media' option in the FBX exporter panel. This packages the scene's textures in the exported FBX. This preserves material to textures links during import into PlayCanvas. Otherwise, you must upload all scene textures separately and relink all textures to materials. * Select the 'Binary' file format option in the FBX exporter panel. This reduces FBX file size considerably. -------------------------------------------------------------------------------- ## Units URL: https://developer.playcanvas.com/user-manual/assets/models/units/ PlayCanvas scenes generally treat 1 unit as 1 meter. When authoring artwork for PlayCanvas, it is important to ensure you do so to the desired scale. To do this, you should check the working units for your scene in your modelling application of choice. You can choose whatever working units you like, but just ensure you respect them. For example, to make a cube that is 1 meter in dimension, you could set your working units to meters and create a 1x1x1 cube. Alternatively, you could set working units to centimeters and create a 100x100x100 cube. Exporting either scene to FBX and importing it to PlayCanvas will result in a cube which is 1x1x1. ### Blender To ensure units are exported correctly from Blender, check that Scene Properties unit system is set to metric and that scale is set to 1.0: [Image: Blender units] In addition, when exporting to FBX format, check that "Apply Scaling" is set to "FBX All": [Image: Blender FBX Export] ### Autodesk 3D Studio Max To check or set working units in 3D Studio Max, open the Units Setup dialog and click the System Unit Setup button: [Image: 3DS Max units] ### Autodesk Maya To check or set working units in Maya, open the Preferences dialog: [Image: Maya units] -------------------------------------------------------------------------------- ## Preloading URL: https://developer.playcanvas.com/user-manual/assets/preloading/ On the web, it's critical to get users into your application as soon as possible. The PlayCanvas asset system provides preloading to ensure essential assets are ready before your application starts. ## The Preload Flag Every asset has a `preload` property. When set to `true`, the asset will be downloaded and its resource created before the application's `initialize` phase begins. You should use preloading for assets that are needed immediately when your application starts. This prevents assets from "popping in" after the application is already running. :::tip In the PlayCanvas Editor, you can set the preload flag in the asset's properties panel. By default, new assets have preload enabled. ::: ## When Are Assets Loaded? Assets are loaded according to these rules: 1. **Preloaded assets** (`preload = true`) are loaded before the application starts 2. **Referenced assets** are loaded when an enabled component references them. For entities enabled in the scene, this happens immediately after preloading completes 3. **Dependent assets** are loaded when their parent asset loads. For example, when a model loads, its referenced materials load, which in turn load their referenced textures ## Streaming vs Preloading If an asset is not preloaded, it will be streamed in when needed. Components handle this gracefully and begin operating once their assets are ready. However, you may see visual "popup" as models appear before their textures finish loading. ## Loading Asset Groups with Tags To avoid popup, you can load groups of assets before displaying them. Use asset tags to organize assets into logical groups: ```javascript // Find all assets tagged for level 1 const assets = this.app.assets.findByTag('level-1'); let loadedCount = 0; // Load each asset for (const asset of assets) { asset.once('load', () => { loadedCount++; if (loadedCount === assets.length) { // All level-1 assets are loaded this.startLevel(); } }); this.app.assets.load(asset); } ``` You can also use more complex tag queries: ```javascript // Assets tagged with BOTH 'level-1' AND 'enemy' const enemies = this.app.assets.findByTag('level-1', 'enemy'); // Assets tagged with 'level-1' OR 'level-2' const assets = this.app.assets.findByTag(['level-1', 'level-2']); ``` ## Best Practices - **Preload essential assets** - UI elements, player models, and anything needed immediately - **Stream large assets** - Background music, distant scenery, optional content - **Use tags for levels** - Group assets by level or area to load them together - **Show loading progress** - For streamed content, display a loading indicator ## See Also - [Asset Registry](asset-registry.md) - Finding and managing assets - [Loading and Unloading](loading-unloading.md) - Dynamic asset management -------------------------------------------------------------------------------- ## Supported Formats URL: https://developer.playcanvas.com/user-manual/assets/supported-formats/ PlayCanvas supports a wide variety of file formats for different asset types. This page lists the formats that can be used in your projects. ## 3D Models | Format | Extension | Notes | |--------|-----------|-------| | glTF Binary | `.glb` | Recommended format. Efficient, widely supported | | glTF | `.gltf` | JSON-based with external files | | FBX | `.fbx` | Converted to GLB on import in Editor | | COLLADA | `.dae` | Converted to GLB on import in Editor | | OBJ | `.obj` | Basic mesh format, no animations | :::tip GLB is the recommended format for 3D models. It's compact, loads quickly, and supports all PlayCanvas features including animations, materials, and morph targets. ::: ## Textures | Format | Extension | Notes | |--------|-----------|-------| | PNG | `.png` | Lossless, supports transparency | | JPEG | `.jpg`, `.jpeg` | Lossy compression, no transparency | | WebP | `.webp` | Modern format, good compression | | AVIF | `.avif` | Next-gen format, excellent compression | | GIF | `.gif` | Converted to PNG/JPG on import | | TGA | `.tga` | Converted to PNG/JPG on import | | BMP | `.bmp` | Converted to PNG/JPG on import | | TIFF | `.tif`, `.tiff` | Converted to PNG/JPG on import | | HDR | `.hdr` | High dynamic range, for environment maps | | EXR | `.exr` | High dynamic range, converted to RGBM PNG | ### Texture Compression For optimized delivery, textures can be compressed to GPU-native formats: | Format | Platform | Notes | |--------|----------|-------| | Basis | All | Universal compressed format | | DXT/BC | Desktop | Windows/Mac/Linux | | PVRTC | iOS | Apple devices | | ETC | Android | Most Android devices | | ASTC | Modern mobile | iOS 8+, Android with ASTC support | ## Audio | Format | Extension | Notes | |--------|-----------|-------| | MP3 | `.mp3` | Widely supported, good compression | | OGG Vorbis | `.ogg` | Open format, good quality | | WAV | `.wav` | Uncompressed, large files | | M4A | `.m4a` | AAC audio | :::note For best browser compatibility, provide both MP3 and OGG versions of audio files. PlayCanvas will use the format supported by the user's browser. ::: ## Fonts | Format | Extension | Notes | |--------|-----------|-------| | TrueType | `.ttf` | Converted to bitmap font on import | | WOFF | `.woff` | Web font format | ## Scripts | Format | Extension | Notes | |--------|-----------|-------| | JavaScript | `.js` | Classic scripts | | ES Module | `.mjs` | ESM scripts (recommended) | ## Data Files | Format | Extension | Notes | |--------|-----------|-------| | JSON | `.json` | Structured data | | Text | `.txt` | Plain text | | CSV | `.csv` | Tabular data (as text) | | XML | `.xml` | Markup data (as text) | | HTML | `.html` | HTML documents | | CSS | `.css` | Stylesheets | ## Shaders | Format | Extension | Notes | |--------|-----------|-------| | GLSL | `.glsl` | OpenGL shading language | | Vertex Shader | `.vert` | Vertex shader source | | Fragment Shader | `.frag` | Fragment shader source | ## Other | Format | Extension | Notes | |--------|-----------|-------| | WebAssembly | `.wasm` | Compiled binary modules | | Binary | `.bin` | Raw binary data | | PLY | `.ply` | 3D Gaussian Splat data | | glTF Binary | `.glb` | 3D Gaussian Splat data using the [KHR_gaussian_splatting](/user-manual/gaussian-splatting/formats/glb) extension | | SPZ | `.spz` | Compressed 3D Gaussian Splat data ([Niantic SPZ format](/user-manual/gaussian-splatting/formats/spz)), loaded via a parser script | ## Custom Formats The lists above cover the engine's built-in loaders, but they are not fixed: at runtime, custom parsers can add support for new file formats — or override the built-in ones — for most asset types. See [Custom Asset Parsers](custom-parsers.md). ## See Also - [Models](models/index.md) - Preparing 3D models for PlayCanvas - [Asset Inspectors](/user-manual/editor/assets/inspectors/) - Configure asset properties in the Editor - [Custom Asset Parsers](custom-parsers.md) - Load custom file formats at runtime -------------------------------------------------------------------------------- ## Entity Component System (ECS) URL: https://developer.playcanvas.com/user-manual/ecs/ PlayCanvas uses an **Entity Component System (ECS)** to organize and manage the objects in your application. In this design pattern: - **[Entities](https://api.playcanvas.com/engine/classes/Entity.html)** are containers — they hold components but have no behavior of their own. - **[Components](https://api.playcanvas.com/engine/classes/Component.html)** add functionality or data to an Entity. - **[Systems](https://api.playcanvas.com/engine/classes/ComponentSystem.html)** manage all instances of a given Component type. This approach provides: - **Flexibility** — you can mix and match components to build complex behaviors. - **Modularity** — logic is encapsulated within components. - **Performance** — systems process components in efficient batches. -------------------------------------------------------------------------------- ## Components URL: https://developer.playcanvas.com/user-manual/ecs/components/ A **[`Component`](https://api.playcanvas.com/engine/classes/Component.html)** adds data and behavior to an Entity. ## Examples - [`CameraComponent`](https://api.playcanvas.com/engine/classes/CameraComponent.html) - [`LightComponent`](https://api.playcanvas.com/engine/classes/LightComponent.html) - [`RenderComponent`](https://api.playcanvas.com/engine/classes/RenderComponent.html) - [`RigidBodyComponent`](https://api.playcanvas.com/engine/classes/RigidBodyComponent.html) & [`CollisionComponent`](https://api.playcanvas.com/engine/classes/CollisionComponent.html) - [`ScriptComponent`](https://api.playcanvas.com/engine/classes/ScriptComponent.html) :::tip Only add components you actually need, and remove unused ones to keep Entities lean. ::: ## Adding a Component in code ```javascript entity.addComponent('camera', { nearClip: 1, farClip: 100, fov: 55 }); ``` See [`addComponent`](https://api.playcanvas.com/engine/classes/Entity.html#addcomponent). ## Accessing a Component ```javascript const camera = entity.camera; ``` ## Removing a Component ```javascript entity.removeComponent('camera'); ``` See [`removeComponent`](https://api.playcanvas.com/engine/classes/Entity.html#removecomponent). ## Enabling / Disabling Components ```javascript entity.model.enabled = false; ``` See [`enabled`](https://api.playcanvas.com/engine/classes/Component.html#enabled). :::tip If a component is temporarily not needed, consider disabling it instead of removing it. ::: -------------------------------------------------------------------------------- ## Entities URL: https://developer.playcanvas.com/user-manual/ecs/entities/ An **Entity** is the basic building block of your PlayCanvas scene ([`Entity`](https://api.playcanvas.com/engine/classes/Entity.html)). ## Key characteristics - An Entity can have **zero or more components**. - Entities can be **parented** to form a hierarchy ([`addChild`](https://api.playcanvas.com/engine/classes/GraphNode.html#addchild), [`removeChild`](https://api.playcanvas.com/engine/classes/GraphNode.html#removechild)). - Entities can be **enabled** or **disabled** ([`enabled`](https://api.playcanvas.com/engine/classes/GraphNode.html#enabled)). :::tip Keep Entities lightweight — avoid adding unnecessary components. ::: ## Creating an Entity in code ```javascript const entity = new pc.Entity("MyEntity"); app.root.addChild(entity); ``` ## Enabling / Disabling Entities ```javascript entity.enabled = false; // Disables the Entity and all its components ``` :::tip Disable Entities when not in use to reduce processing and improve performance. ::: ## Lifecycle - **Creation** — [`Entity constructor`](https://api.playcanvas.com/engine/classes/Entity.html#constructor). - **Parenting** — [`addChild`](https://api.playcanvas.com/engine/classes/GraphNode.html#addchild) / [`removeChild`](https://api.playcanvas.com/engine/classes/GraphNode.html#removechild). - **Destruction** — [`destroy`](https://api.playcanvas.com/engine/classes/GraphNode.html#destroy). :::tip When an Entity is no longer needed, call `destroy` to free resources and detach it from the hierarchy. ::: -------------------------------------------------------------------------------- ## Hierarchy and Transformations URL: https://developer.playcanvas.com/user-manual/ecs/hierarchy-and-transformations/ Entities can be arranged in a **parent-child hierarchy**. The `Entity` class inherits its transform capabilities from the [`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.html) superclass. ## Key points - **Transforms are relative** to the parent. - **World transforms** are calculated by combining local transforms through the hierarchy. - Moving a parent affects all its children. :::tip Minimize deep hierarchies. Shallower hierarchies are easier to manage and can perform better. ::: ## Example ```javascript childEntity.setLocalPosition(1, 0, 0); // relative to parent console.log(childEntity.getWorldPosition()); // global position ``` See [`setLocalPosition`](https://api.playcanvas.com/engine/classes/GraphNode.html#setlocalposition) and [`getWorldPosition`](https://api.playcanvas.com/engine/classes/GraphNode.html#getworldposition). ## Re-parenting ```javascript newParent.addChild(childEntity); ``` ## Scaling considerations - Non-uniform scaling can cause visual or physics issues. - Avoid scaling physics-enabled entities unless necessary. -------------------------------------------------------------------------------- ## Searching the Hierarchy URL: https://developer.playcanvas.com/user-manual/ecs/searching-the-hierarchy/ ## By Name ```javascript const found = app.root.findByName("Player"); ``` See [`findByName`](https://api.playcanvas.com/engine/classes/GraphNode.html#findbyname). ## By Tag Tags are string labels you can assign to Entities ([`Tags`](https://api.playcanvas.com/engine/classes/Tags.html)). ```javascript entity.tags.add("enemy"); const enemies = app.root.findByTag("enemy"); ``` See [`tags`](https://api.playcanvas.com/engine/classes/Entity.html#tags) and [`findByTag`](https://api.playcanvas.com/engine/classes/Entity.html#findbytag). :::tip Use tags for grouping related Entities. Tag-based searches are typically faster and more flexible than deep name-based searches. ::: ## By Component ```javascript const lights = app.root.findComponents("light"); ``` See [`findComponents`](https://api.playcanvas.com/engine/classes/Entity.html#findcomponents). ## Recursion and Scope - Searches can be started from any Entity, not just `app.root`. - Searching from a smaller subtree is faster than searching the whole scene. -------------------------------------------------------------------------------- ## PlayCanvas Editor URL: https://developer.playcanvas.com/user-manual/editor/ The PlayCanvas Editor is a powerful, browser-based development environment for creating stunning 3D applications. No downloads, no installations—just open your browser and start building. [Image: PlayCanvas Editor Interface] ## Why Choose the PlayCanvas Editor? ### 🌐 Accessible Anywhere The entire Editor runs in your web browser. Whether you're at your desk, on a laptop, or borrowing a friend's computer, your projects are just a login away. Your work is automatically saved to the cloud, so you never lose progress. ### 👁️ What You See Is What You Get The Editor uses the same [PlayCanvas Engine](../engine) that powers your published applications. Every material, every light, every shadow you see in the Editor is exactly what your users will experience. No surprises at runtime. ### ⚡ Instant Iteration Make a change, see it instantly. With [live editing](scripting/hot-reloading), you can tweak materials, adjust positions, and even modify scripts while your application runs. Hit the [Launch](interface/launch-page) button and your project opens in a new tab, ready to test. The feedback loop between idea and implementation has never been shorter. ## Built for Teams ### Real-time Collaboration [Image: Collaboration in the Viewport] Work together with your team in real-time. See where others are looking, what they're selecting, and chat directly within the Editor. Multiple developers, artists, and designers can build the same scene simultaneously—no merge conflicts, no stepping on each other's toes. [Learn more about collaboration →](realtime-collaboration) ### Professional Version Control [Image: Version Control Graph] PlayCanvas includes a complete [version control system](version-control) designed specifically for 3D projects: - **Checkpoints** — Snapshot your project at any point and roll back if needed - **Branches** — Develop features in isolation without affecting the main project - **Merging** — Combine work from multiple branches with visual conflict resolution - **History** — Track every change to every asset and entity over time ## Complete Development Toolkit ### Visual Scene Building Construct your 3D worlds using intuitive [transform gizmos](interface/viewport), a hierarchical [entity tree](interface/hierarchy), and a comprehensive [property inspector](interface/inspector). Drag and drop assets directly into your scene, parent entities with a click, and fine-tune every detail. ### Integrated Code Editor Write scripts without leaving your browser. The built-in [code editor](scripting/code-editor) features syntax highlighting, intelligent autocomplete, and real-time error checking. For larger projects, use the [VS Code extension](scripting/vscode-extension) and develop locally with full IDE power. ### Powerful Asset Pipeline Import models, textures, audio, and more with a streamlined [asset pipeline](assets/import-pipeline). The Editor automatically optimizes your assets and handles format conversions. Organize everything in the [Assets Panel](assets/asset-panel) with folders, search, and filtering. ### Component-Based Architecture Build complex behaviors by combining [components](scenes/components)—camera, light, physics, audio, scripts, and more. This modular approach keeps your project organized and your code reusable. ## Publish Everywhere When you're ready to share your creation, PlayCanvas has you covered: | Platform | Description | |----------|-------------| | [Web](publishing/web) | Deploy to PlayCanvas hosting or self-host anywhere | | [Mobile](publishing/mobile) | Package as native iOS and Android apps | | [Desktop](publishing/desktop) | Build standalone applications for Windows, macOS, and Linux | | [Playable Ads](publishing/playable-ads) | Export optimized builds for Facebook, Snapchat, and more | ## Getting Started Ready to dive in? Here's your path forward: 1. **[Create Your First App](getting-started/your-first-app)** — Build a simple 3D scene in minutes 2. **[Explore the Interface](interface)** — Master the Editor's tools and panels 3. **[Learn Scripting](scripting)** — Add interactivity with JavaScript 4. **[Publish Your Project](publishing)** — Share your creation with the world ## Extend and Customize For advanced workflows, the [Editor API](editor-api) lets you build custom tools, automate repetitive tasks, and integrate with external systems. If you can imagine it, you can build it. --- :::info[Engine Compatibility] The Editor evolves alongside the PlayCanvas Engine. If you're upgrading an older project or experiencing issues, check the [engine compatibility](engine-compatibility) guide or visit [troubleshooting](troubleshooting) for solutions. ::: -------------------------------------------------------------------------------- ## Assets URL: https://developer.playcanvas.com/user-manual/editor/assets/ The PlayCanvas Editor provides a complete asset management system for your project. This section covers how to work with assets in the Editor, including importing, organizing, and configuring them. ## What You'll Learn - **[Assets Panel](asset-panel)** - Navigate and manage your project's assets using the Assets Panel - **[Importing Assets](importing)** - Upload and import assets into your project - **[Import Pipeline](import-pipeline/)** - Configure how assets are processed during import - **[Asset Inspectors](inspectors/)** - Configure asset properties using the Inspector - **[Asset Store](asset-store/)** - Browse and import assets from the PlayCanvas Asset Store - **[Asset Viewers](viewers)** - Inspect models and textures in dedicated viewer tools ## Overview Assets in the Editor are managed through the [Assets Panel](asset-panel), which provides a visual interface for: - Organizing assets into folders - Uploading new assets via drag-and-drop - Searching and filtering assets - Inspecting and editing asset properties - Copying assets between projects When you upload a file, the Editor runs it through the [import pipeline](import-pipeline/) to convert and optimize it for use in your application. The resulting asset can then be configured using the appropriate [asset inspector](inspectors/). For conceptual information about assets and how to work with them programmatically, see the [Assets](/user-manual/assets/) section in Common Topics. :::ai Before replacing a widely used asset, ask an AI assistant through the **[Editor MCP Server](/user-manual/editor/mcp-server/)** to trace dependencies and summarize the impact. Approve the references it updates, then inspect affected scenes. ::: -------------------------------------------------------------------------------- ## Assets Panel URL: https://developer.playcanvas.com/user-manual/editor/assets/asset-panel/ The Assets Panel manages all of the Assets that are available in your project. From here, you can create, upload, delete, inspect and edit any Asset. [Image: Assets Panel] ## Folder Hierarchy {#folder-hierarchy} The folder panel allows you to organize your assets into a tree of folders. To create a new Folder, select the Add Asset (+) button and select 'Folder'. Alternatively, right click the folder where you would like a new folder to be created and select 'New Asset' > 'Folder'. To rename a folder, double click it in the hierarchy panel and edit the Name field in the Inspector. To delete a folder, double click it in the hierarchy and hit delete. Alternatively, right click the folder you want to delete and select 'Delete' from the context menu. Folders can be drag and dropped into each other if you want to reorganize your folder structure. :::note Folders are essentially meta assets, exclusively designed to facilitate the organization of assets within the Editor. Folder assets are excluded from builds and are not used when building the folder structure of a published build. ::: ## Creating and Uploading Assets {#creating-and-uploading-assets} You can create new assets by dragging a file from you computer's file system into the Assets Panel. The Editor will upload and import the asset for you. You can also create certain assets types using the Add Asset (+) icon. You can delete assets by selecting them and clicking the Delete Asset icon. ## Editing Assets {#editing-assets} Certain text-based assets can be opened and edited in the PlayCanvas Script Editor: text, json, shader, html, css and script assets. To do this, simply double click on the asset's thumbnail. ## Inspecting Assets {#inspecting-assets} To inspect the details of any given asset, select its thumbnail in the Assets Panel. The asset's details will be displayed in the Inspector. ## Filtering {#filtering} Filter which assets are visible using the filter drop down to select the type of asset to view. ## Searching {#searching} You can perform a global search for assets in your project using the Search box. Simply start typing into the box and the Editor will show matching results dynamically in the Assets Panel. **ID** - Specific asset can be found by its unique ID, by simply typing ID in search field it will recognize exact match and only show one asset with that ID. **RegExp** - It is possible to search using regular expressions. Add `*` at the beginning of search field and type regexp query after. To search for all assets use `*.` (any character) regexp query. **Tags** - To search by tags and their combinations type tags in square brackets `[ ]`. Simple query operators: AND, OR are allowed by expressing query as array of strings or other arrays with strings. Logic of query is same as for [`findByTag`](https://api.playcanvas.com/engine/classes/AssetRegistry.html#findbytag) from `AssetsRegistry`. Here are some examples: - `[ level-1 ]` - returns all assets that are tagged by `level-1`. - `[ level-1, level-2 ]` - returns all assets that are tagged by `level-1 OR level-2`. - `[ [ level-1, monster ] ]` - returns all assets that are tagged by `level-1 AND monster`. Notice extra brackets. - `[ [ level-1, monster ], [ level-2, monster ] ]` - returns all assets that are tagged by `(level-1 AND monster) OR (level-2 AND monster)`. ## Drag and Drop {#drag-and-drop} Assets can be moved to different folders by dragging them from the main panel to a folder in the folder hierarchy. Note that assets support multi-selection. Pressing CTRL+A will select all assets in the currently selected folder. You can also drag Assets from the Asset Panel to highlighted slots in the [Inspector](/user-manual/editor/interface/inspector). Slots in the Inspector will either be asset attributes of components or asset-type script attributes. You can also drag model, material, and cubemap assets directly into the [Viewport](/user-manual/editor/interface/viewport) - If you drag a model asset into the Viewport, a new entity will be created with a model component with the model asset assigned. The viewport camera will automatically zoom to the newly created entity. - If you drag a material over a particular mesh instance in the Viewport, its material will be switched (as a preview) to the material being dragged. To make the material change stick, simply drop the material. - If you drag a cubemap over the background of a scene in the Viewport, the cubemap will be assigned as the skybox cubemap of the scene. This property can also be set in the [Project Settings](/user-manual/editor/interface/settings/rendering/). ## Copy and Paste between Projects {#copy-and-paste-between-projects} To copy an asset or a selection of assets between projects, select the asset(s) and right-click to bring up the context menu to select 'Copy'. You can also use the hotkey Ctrl/Cmd + C instead if the context menu is not available due to being a read-only project. Right click copy menu In the project that you want to copy the asset(s) to, right click in the assets panel and select 'Paste'. Ctrl/Cmd + V hotkey can be used instead. Right click paste menu Copy and pasting an asset will also copy its asset dependencies too. For example, here we have a model which references two materials and they reference a set of textures. Model example If you copy and paste just the model asset into a different project, those asset dependencies are copied too. Pasted referenced assets By default, it is pasted as a flat hierarchy. If you want keep the folder structure, hold Shift when the context menu is opened and an option will appear called 'Paste (keep folders)'. This will attempt to keep the folder structure using the folder you are pasting into as the root folder. Right click paste (keep folders) menu Will result in the following where the folder structure is preserved: Pasted referenced assets with folders We generally recommend that if you will be using this feature for reusable libraries and assets, to keep it contained to a root level folder that can be easily copied and pasted to other projects. This will keep the folder structure of projects simpler and cleaner. :::note Note that copy and pasting assets does not overwrite existing assets with the same name and will create a new asset. ::: ## Checking References {#checking-references} Sometimes it's useful to know where assets are being used (or referenced) within a particular scene. If the Editor cannot detect any references for an asset, a small dot will be displayed on its thumbnail: [Image: Unreferenced Asset] :::warning Note that the Editor cannot detect references to assets that are made in code. So think carefully before you delete an asset based on this indicator! ::: If an asset does have references, you can check them via the References content menu item: [Image: Asset References] Selecting a reference will load it into the Inspector panel. -------------------------------------------------------------------------------- ## Asset Store URL: https://developer.playcanvas.com/user-manual/editor/assets/asset-store/ The PlayCanvas Asset Store is a library of free assets that you can use in your projects. It contains 3D models, fonts, scripts and more. ## Accessing the Asset Store You can access the Asset Store from within the Editor by clicking the ASSET STORE button in the top-right of the [Assets Panel](../../interface/assets.md). [Image: Asset Store Button] The Asset Store will then open: [Image: Asset Store] ## Selecting a Store There are three top-level Stores to choose from: | Store | Description | | ----- | ----------- | | PLAYCANVAS | Assets curated and supplied by PlayCanvas and selected partner creators. This store contains: 3D models, fonts, scripts, sky boxes, templates and textures. | | SKETCHFAB | Assets curated and supplied by [Sketchfab](https://sketchfab.com/). This store contains 3D models only. [Learn more](sketchfab) about the Sketchfab Store. | | MY ASSETS | Assets imported by you and stored in your user account. This store is currently in a closed beta. | ## Searching the Store To search the Store, simply enter a search term in the Search bar at the top. You can then filter and sort the search results using the Search Options: [Image: Asset Store Search] ## Importing Assets into your Project Select any store item in the search results to open its details page: [Image: Asset Store Details] On the details page you can: * Read a description of the store item. * Inspect the files included in the store item. * View statistics related to the store item (file size, last updated date, etc). * Preview the item in the Model Viewer (only applies to 3D model assets). * View author and license information. :::note Please respect the license terms for the store items you use in your projects. For example, the [Oldsmobile Cutlass Supreme Sedan '71](https://sketchfab.com/3d-models/oldsmobile-cutlass-supreme-sedan-71-78f76d386a4341b0b71745bdc50fd5ab) in the screenshot above was authored by [Barbo](https://sketchfab.com/barbo-autos) and has CC BY 4.0 license. This means that you must give the author appropriate credit for using their works. ::: :::ai Give an AI assistant your style, license, and file-size constraints. Through the **[Editor MCP Server](/user-manual/editor/mcp-server/)**, it can compare PlayCanvas, Sketchfab, and My Assets results and shortlist suitable items. ::: -------------------------------------------------------------------------------- ## Sketchfab URL: https://developer.playcanvas.com/user-manual/editor/assets/asset-store/sketchfab/ The Asset Store is integrated with [Sketchfab](https://sketchfab.com/), the popular online platform for publishing, sharing, and discovering 3D, VR, and AR content. This integration gives you access to thousands of free, high-quality 3D models without having to leave the Editor. [Image: Sketchfab Store] ## Logging in to Sketchfab The first time you attempt to import a model from Sketchfab, you will be asked to either sign up or log in to Sketchfab: [Image: Sketchfab Authentication] This will take you to `sketchfab.com` to authenticate. Once you are signed in to Sketchfab, you need to accept Sketchfab's authorization request: [Image: Sketchfab Authorization] You should then receive a message that you have successfully connected your Sketchfab account to PlayCanvas! 🎉 -------------------------------------------------------------------------------- ## Asset Import Pipeline URL: https://developer.playcanvas.com/user-manual/editor/assets/import-pipeline/ Some assets are uploaded in source format and need to be converted into a "target" format before they can be used in a game at runtime. This process is called *Importing*. For example, a 3D model can be uploaded as an FBX file, but must be converted into a PlayCanvas compatible model file before it can be loaded in the game. Some assets don't need to be imported before they can be used. For example a PNG image can be used as a texture immediately. ## Asset Import {#asset-import} When a source asset is uploaded, PlayCanvas starts an asset import task to perform this import process on our server. There are a variety of options available to tune the behavior of the import pipeline to suit your needs. ### Search related assets {#search-related-assets} When you update an source asset by uploading a new version of the file. There are two possible behaviors for how we update the target assets that are created by the import pipeline. * If **Search related assets** is enabled, the pipeline will update target assets no matter what folder they are located in. * If **Search related assets** is not enabled, the pipeline will only look for the target assets in the same folder as the source asset. So, if you leave this enabled, you are able to organize your source and target assets into folders and be sure that when you update a source assets it will update all related assets. ### Assets default to preload {#assets-default-to-preload} Newly created assets will automatically be set to [preload](/user-manual/assets/preloading/) or not depending on whether this option is enabled or not. The exception to this are JavaScript script files which will always be set to preloaded when created. ## Texture Import Settings {#texture-import-settings} These options only affect the importing of images and textures. ### Texture POT (Power of Two) {#texture-pot-power-of-two} When this option is enabled textures that are not a power of two will be converted to the nearest power of two resolution when they are imported. ### Create Atlases {#create-atlases} Images that are uploaded will be imported as a texture atlas instead of a normal texture asset. This is a useful time saver when uploading many spritesheets or UI assets. ## Model Import Settings {#model-import-settings} These options only affect the importing of model or scene files (e.g. FBX, Collada, obj, etc) ### Preserve material mappings {#preserve-material-mappings} When a model file is updated or reimported, the Editor will try to preserve the material mappings that were set on it. ### Overwrite Models {#overwrite-models} When a model file is updated or reimported this option determines whether or not the target model file is overwritten. The default behavior is to overwrite with the new model. ### Overwrite Animations {#overwrite-animations} When a model file is updated or reimported this option determines whether or not a animations created from the model are overwritten. The default behavior is to overwrite with the new animations. ### Overwrite Materials {#overwrite-materials} When a model file is updated or reimported this option determines whether or not materials created from the model are overwritten. The default behavior is to leave existing materials. ### Overwrite Textures {#overwrite-textures} When a model file is updated or reimported this option determines whether or not textures created from the model are overwritten. The default behavior is to overwrite with the new textures. ### Convert to GLB {#convert-to-glb} Enabled by default on new projects, imported models and animations will create GLB model and animation assets instead of the older, deprecated JSON format. ### Import Hierarchy {#import-hierarchy} Only available if using [Convert to GLB](#convert-to-glb) option. When a model file is imported, a template asset is created that contains the full hierarchy of the model as entities allowing you to manipulate them directly in the Editor. See more information about this feature [here](/user-manual/editor/assets/import-pipeline/import-hierarchy/). ### Mesh Compression {#mesh-compression} Only available if using [Convert to GLB](#convert-to-glb) option. Setting this to a compression format will automatically compress mesh data when importing or re-importing model files. This can drastically reduce the size of GLB files at the cost of some runtime decompression cost. If using Draco compression, remember to import the Draco WASM module into the project otherwise the models will not load. ### Create FBX Folder {#create-fbx-folder} When importing a model file (e.g a GLB or FBX), the Editor will create a folder for the assets created by the import such as render, template and material assets. If there is already a Model (Source) file in the current folder or a folder with the same name as the file being imported, it will overwrite the existing assets instead of creating a new folder. ## Animation Import Settings {#animation-import-settings} Please refer to the [Animation section](/user-manual/editor/assets/inspectors/animation/) for more details. -------------------------------------------------------------------------------- ## Import Hierarchy URL: https://developer.playcanvas.com/user-manual/editor/assets/import-pipeline/import-hierarchy/ PlayCanvas supports importing models with their meshes as a hierarchy of entities in the scene. This allows you to edit the different meshes directly in the Editor. Components can be added, attach other entities, move/rotate/scale entities in the hierarchy etc. [Image: Edit model hierarchy in the Editor] ## How to enable :::note This is now enabled by default for new projects. ::: Open the 'Project Settings' Scroll down to 'Asset Import' and enable 'Import Hierarchy': ## Importing models A full tutorial on importing your first model and animation can be found [here](/tutorials/importing-first-model-and-animation/). As an overview, when you drag the model file into the 'Assets Panel': [Image: Drag Model into Assets Panel] The following assets will be created when imported: [Image: Created Assets] | Asset Type | Description | |------------|-------------| | **[Materials](/user-manual/editor/assets/inspectors/material/)** | Materials used by the imported model, mapped to the mesh instance. | | **[Textures](/user-manual/editor/assets/inspectors/texture/)** | Embedded textures in the model file (if any). These will automatically be mapped to the associated materials. | | **[Template](/user-manual/editor/templates/)** | The template stores the scene hierarchy of the model. Create an instance of the template to bring the model into the scene. | | **Container** | The GLB that stores all the meshes of the model. | | **Render** | Render assets reference a mesh in the container asset and are used by the [Render Component](https://api.playcanvas.com/engine/classes/RenderComponent.html) to render the mesh in the scene. They can also be used with the [Collision Component](https://api.playcanvas.com/engine/classes/CollisionComponent.html) as a mesh for physics. | ## Updating models As the hierarchy is created as part of a template, when a model is updated it may affect the template instances in the scenes. Added components to entities in the template will be kept during the update unless the mesh instance that the entity represents no longer exists in the updated model. The exception to this is if a script component is added to an entity in the template and the mesh instance it represents is no longer part of the updated model, it will be moved under the root entity in the template so there is no data loss. Any entities that were under it before the update will be kept as well. How the Editor decides what is a new or removed mesh instance is done by the following: - If in the update, a mesh instance's name and its parent mesh's instance name matches an existing mesh instance and its parent, they are assumed to be the same mesh instance in the hierarchy and is updated. - If in the update, a mesh instance's name does not exist, it's assumed to be a new mesh instance and a new entity is added to the template. - If in the update, an existing entity of the template does not have a matching mesh instance given the rules above, it's assumed that this mesh instance has been removed and the entity will be removed from the template. The exception being mentioned above, if there was a script component added to it on the template, those entities are preserved on the root. If there were no script components added, those are deleted from the template. -------------------------------------------------------------------------------- ## Uploading and Importing URL: https://developer.playcanvas.com/user-manual/editor/assets/importing/ ## Creating New Assets To upload an asset to PlayCanvas, follow these steps: ### In the Editor * Drag and drop your asset file into the Asset panel in the Editor window. * A progress bar will appear along the bottom. * When the progress bar disappears, your new Asset will appear in the Asset panel. Now, when you attempt to choose an asset via the asset picker attribute control (for the Model component or the Animation component for example), your asset will be available for assignment. :::note There is a file size limit of 340MB. ::: ## Updating Existing Assets To update an Asset that you have already uploaded. Upload the asset again, ensuring that you have the same filename as the existing asset. PlayCanvas will update the existing asset with the new upload. ## Migrating from JSON to glTF GLB As of Wed 14 Oct 2020, PlayCanvas will be creating GLBs for model and animation imports instead of JSON. This gives a large reduction in parsing times which means lower load times and more responsive applications. For projects created prior to this date, they will still create JSON assets by default for consistency. If you would like to migrate assets to the GLB format, please go to 'Project Settings'. Project settings Open 'Asset Import' and tick 'Convert to GLB'. Asset Import settings And finally reimport the model and/or animation file (via drag and drop or the 'Upload' menu option) to create the GLB asset. Drag and drop file Once created, this can be referenced to Entities in place of the existing JSON asset. -------------------------------------------------------------------------------- ## Asset Inspectors URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/ When you select an asset in the [Assets Panel](/user-manual/editor/assets/asset-panel), its properties are displayed in the Inspector. Each asset type has its own set of configurable properties. ## Common Properties All asset inspectors display a common set of properties in the header section: [Image: Common Asset Inspector Properties] | Property | Description | |----------|-------------| | ID | The unique identifier for the asset. Useful for referencing the asset in scripts. | | Name | The display name of the asset. This can be edited to rename the asset. | | Tags | Tags assigned to the asset for organization and filtering, both in the [Assets Panel](/user-manual/editor/assets/asset-panel#searching) and at runtime via the [Engine API](/user-manual/assets/asset-registry#by-tag). | | Type | The [asset type](#asset-types) (read-only). | | Exclude | When enabled, the asset is excluded from the published build. Useful for development-only assets such as test scripts or READMEs. | | Preload | When enabled, the asset is loaded at application startup. When disabled, referenced assets load asynchronously after the app starts, while unreferenced assets must be loaded manually via script. | | Size | The file size of the asset (read-only). | | Source | A reference to the source asset from which this asset was derived, if applicable (read-only). | | Created | The date and time the asset was created (read-only). | ### Script Assets Script assets display additional properties: [Image: Script Asset Inspector Properties] | Property | Description | |----------|-------------| | Loading Order | Opens the [script loading order manager](/user-manual/editor/scripting/loading-order) to control the order scripts are loaded. | | Loading Type | Controls when the script is loaded: | ### Asset Store Assets Assets imported from the [Asset Store](/user-manual/editor/assets/asset-store) display additional attribution properties: [Image: Asset Store Inspector Properties] | Property | Description | |----------|-------------| | License | The license under which the asset is provided, with a link to license details. | | Author | The original author of the asset, with a link to their profile. | ## Asset Types | Type | Imported From | Resource Extensions | Description | | -------------------------------- | -------------------------------- | -------------------------------- | ---------------------------------- | | [`animation`](animation) | `.glb`, `.fbx` | `.glb` | Animation keyframe data | | [`audio`](audio) | `.mp3`, `.wav`, `.ogg` | `.mp3`, `.wav`, `.ogg` | Sound data | | `binary` | `.bin` | `.bin` | Binary data | | `bundle` | Created in the Editor | `.tar` | Bundled assets | | [`css`](css) | `.css` | `.css` | Stylesheets for HTML | | [`cubemap`](cubemap) | `.png`, `.jpg`, `.webp`, `.avif` | `.png`, `.jpg`, `.webp`, `.avif` | Environment lighting data | | [`font`](font) | `.ttf`, `.woff` | `.json`, `.png` | Font data for rendering text | | [`gsplat`](gsplat) | `.ply` | `.ply` | 3D Gaussian Splat data | | [`html`](html) | `.html` | `.html` | HTML documents | | [`json`](json) | `.json` | `.json` | JSON documents | | [`material`](material) | `.glb`, `.fbx` | None | Material definitions for 3D models | | [`render`](render) | `.glb`, `.fbx` | `.glb` | 3D mesh data | | [`script`](../../scripting/index.md) | `.js`, `.mjs` | `.js`, `.mjs` | Scripts | | [`shader`](shader) | `.glsl`, `.vert`, `.frag` | `.glsl`, `.vert`, `.frag` | Custom shaders for rendering | | [`sprite`](sprite) | Created in the Editor | None | 2D images for UIs or textures | | [`template`](template) | `.glb` | None | Templates for entity hierarchy | | [`text`](text) | `.txt` | `.txt` | Text documents | | [`texture-atlas`](texture-atlas) | `.png`, `.jpg`, `.webp`, `.avif` | `.png`, `.jpg`, `.webp`, `.avif` | Sprite sheet image data | | [`texture`](texture) | `.png`, `.jpg`, `.webp`, `.avif` | `.png`, `.jpg`, `.webp`, `.avif` | Image data for 3D models or UIs | | [`wasm`](wasm) | `.wasm` | `.wasm` | WebAssembly modules | -------------------------------------------------------------------------------- ## Animation URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/animation/ An Animation asset is used to play a single animation on a 3D model. Animations are imported by uploading 3D scenes (such as FBX files) which contain animation data. The animation data is extracted from the uploaded file by the [asset pipeline](/user-manual/glossary#asset-pipeline) and a [Target Asset](/user-manual/glossary#target-asset) is created to use in game. ## Animation Preview The inspector has a viewer that can be used to preview the animation with any Template or Model asset. This is useful if you have a single animation that can be applied to different character rigs. [Image: Asset Inspector Preview] There is also a viewer in the [Anim State Graph Editor](/user-manual/animation/anim-state-graph-assets/) when you select a state in the graph. When selected, all Entities in the scene that are using the graph will show in a list and can be selected for preview. [Image: Anim State Graph Preview] ## Animation Import Settings :::warning This is an experimental feature. Please let us know your feedback in the [forums](https://forum.playcanvas.com/). ::: When importing animations, there are settings that can be tweaked to adjust the animation quality against the file size. They can be found in the Project Settings under Asset Import. [Image: Animation Import Settings] ### Naming Strategy Only available for GLB export format. When importing an animation, the generated asset name can either be set from the 'Take Name' in the animation file, or use the animation filename instead. This is useful with assets that are brought/taken from a store such as [Mixamo](https://www.mixamo.com/) where all the take names are 'mixamo.com' and using the filename as the asset name is clearer. ### Sample rate Available for both JSON and GLB export formats. The higher the rate, the higher detail and fidelity the animation at the cost of size. If you would like to keep the keyframes that have been set and defined in the original animation, select Disabled. ### Curve tolerance Available for both JSON and GLB export formats. Curve tolerance controls a lossy compression setting of the animation import with the idea that a saving in file size can be made with little or no noticeable difference. This is a value between 0 and 100 where the higher number, the smaller the file size but at cost of losing information in the animation. 0 would be no compression and 100 would lose all information. 1 or 2 is considered to be good starting point. ### Cubic curves Only available for GLB export formats. Enable this option if you wish to keep the easing in the animation curves from the original animation. However, this will mean that the file will have extra information per keyframe and increase the size. If enabling this option, it is recommended that Sample Rate is disabled and Curve Tolerance is set to 0. -------------------------------------------------------------------------------- ## Audio URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/audio/ Audio assets are sound files which can be played back using the [Sound Component](/user-manual/editor/scenes/components/sound/). Any audio format that is supported by the web browser is supported by PlayCanvas. No processing is done to the audio file on import. Common formats like MP3, AAC, Ogg Vorbis, and WAV are supported across all modern browsers. :::tip MP3 is recommended as it offers good compression and [universal compatibility](https://caniuse.com/mp3). ::: ## Inspector [Image: Audio Asset Inspector] The Audio asset inspector displays audio information and provides playback controls to preview the sound. ## Properties | Property | Description | |----------|-------------| | Duration | The length of the audio file in seconds (read-only). | The inspector also includes playback controls (play/pause button and timeline) to preview the audio. :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## CSS URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/css/ A CSS asset contains CSS code. You can create a new CSS asset in the Editor or by uploading a file with a `.css` extension. To edit a CSS asset, right click on it in the Editor and select Edit. ## Inspector [Image: CSS Asset Inspector] The CSS asset inspector displays a preview of the CSS code contained in the asset. ## Properties This asset type has no configurable properties in the Inspector. It displays a read-only preview of the CSS code. :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Cubemap URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/cubemap/ Cubemaps are a special type of texture asset. They are formed from 6 texture assets where each texture represents the face of a cube. They typically have two uses: 1. A cubemap can define your scene's sky box. A sky box contains imagery of the distant visuals of your scene such as hills, mountains, the sky and so on. 2. A cubemap can add reflections to any material. Imagine a shiny, chrome ball bearing in your scene. The ball reflects the surrounding scene. For open environments, you would normally set the scene's sky box cubemap as the cubemap on a reflective object's materials. [Interactive Demo] ## Importing Cubemap Textures A cubemap is an asset that requires six texture assets as input. Therefore, in order to fully configure a new cubemap asset, you must first import 6 images into your project. To do this, simply drag 6 images from your file system into the Assets panel (or select the Asset panel's Upload option). Once uploaded and processed, the images will appear in the Assets panel where they are now ready to be assigned to a cubemap asset. ## Creating Cubemaps You can create new cubemap assets directly from the PlayCanvas Editor interface. Use the Create Asset menu in the Asset panel. [Image: Cubemap Creation] This creates a new cubemap Asset and opens up the Cubemap Editor on the right-hand side of the screen. ## Selecting Cubemaps To select a cubemap in order to edit it, select it in the Asset Panel. The easiest way to do this is to select the cubemap filter to narrow down the options for selection. Cubemaps are identified by cross-shaped thumbnails: [Image: Cubemap Thumbnails] When a cubemap is selected, it will be loaded into the Inspector panel on the right of the Editor. ## Cubemap Properties Once you have a cubemap selected, you can edit its properties. [Image: Cubemap Properties] ### Filtering This setting determines how the pixels of the cubemaps are interpolated as they are magnified. Magnification is when the texel to screen pixel ratio is less than one. Linear gives the best results visually, followed by Nearest. ### Anisotropy Anisotropy is a value between 1 and 16 that gives control over the quality of texture sampling as the camera's view vector becomes more closely aligned with the plane of a textured surface. ## Assigning Textures to Cubemaps [Image: Cubemap Preview] The cubemap Preview panel displays the six faces of a cubemap flattened into the shape of a cross. Imagine a cardboard box that has been unfolded to lay flat. To construct a cubemap, simply drag texture assets from the Assets panel to the face slots in the Preview panel. You can also select a cubemap face slot and then select a texture asset from the Assets panel. Cubemap faces must be: - Square (the same resolution in width and height) - Power of two in dimension (1x1, 2x2, 4x4, 8x8, 16x16, 32x32 and so on) - All faces must be the same resolution To assist you, the Editor attempts to figure out how to auto-assign textures to faces intelligently. It does this when you drag the first face to a slot by trying to match commonly used naming conventions for cubemap faces, such as: - negx, posx, negy, posy, negz, posz - left, right, top|up, bottom|down, front|forward, back|backward - 0-5|1-6 An example of a texture set that would match is: - face_posx.jpg - face_negx.jpg - face_posy.jpg - face_negy.jpg - face_posz.jpg - face_negz.jpg ## Image Based Lighting This technique allows you to use Environment Map such as CubeMap in order to simulate physically based ambient light and reflection on materials. [Read more](/user-manual/graphics/physical-rendering/image-based-lighting/) on how it works and how to author CubeMaps for IBL. ## Assigning Cubemaps to Materials The default Phong and Physical material types both have reflection properties. If you expand the Environment property section, you see the following: [Image: Cubemap Material] You can click the Empty slot to select a cubemap or drag and drop a cubemap asset from the asset panel into the cubemap slot. :::note A Physical material will use the scene's skybox as a default environment map if it is assigned and prefiltered. ::: ## Converting Equirectangular or Octahedral HDRIs to Cubemaps Environment textures often are in a equirectangular or Octahedral format ([Poly Haven](https://polyhaven.com/hdris) for example) and will need to be converted to cubemaps before they can be used in PlayCanvas. This can be done via [PlayCanvas Texture Tool](https://playcanvas.com/texture-tool), available in the browser. 1. Download the HDR version of environment texture and press 'Add Files' button in PlayCanvas Texture Tool to load the file. 2. Select the loaded texture on the left. 3. Under 'Reproject' section, change the 'source' to the format of texture. 4. Change 'target' to 'cube'. 5. Change 'encoding' to the desired format: - 'rgbe' for exporting to 'HDR' - 'rgbm' for exporting to 'PNG' 6. Set the width to the desired size per face texture. 512 is a good balance between quality and file size. 7. Press 'Reproject' button to do the conversion to a cubemap. 8. Press 'Export to PNG' or 'Export to HDR' to download the 6 individual cubemap face textures that are ready to be uploaded to PlayCanvas. [Image: PlayCanvas Texture Tool] Other tools that can also do this conversion include: - Mateusz Wisniowski's [HDRI-to-CubeMap tool](https://matheowis.github.io/HDRI-to-CubeMap/) (browser) - [cmftStudio](https://github.com/dariomanesku/cmftStudio) (desktop) with [guide](https://jamie-white.com/webgl/equirectangular-hdr-image-to-face-list/) -------------------------------------------------------------------------------- ## Font URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/font/ A Font asset contains an image with all the characters of the font that the user chose to include, and data related to how each character should be displayed. Font assets are used to render text using an [Element](/user-manual/editor/scenes/components/element/) component of type Text. To render text, add an Element Component to an Entity set its type to Text and drag and drop the Font asset to the Font slot of the Element Component. You can create a Font asset by uploading a font file ending in `.ttf`, `.ttc`, `.otf` or `.dfont`. We convert the uploaded font to a multi-channel signed distance field. This makes a font keep its details at various sizes so you only need to upload one font and use the same one for every size you want to display. The technique might work better for some fonts than others. :::tip Not using the Editor? Engine, React and Web Components projects can generate the same Font asset without the Editor using [font-tools](/user-manual/user-interface/fonts). ::: Here are the properties that you can edit for a Font asset in the Editor: [Image: Font Asset] ## Properties ### Intensity Intensity is used to boost the value read from the signed distance field, 0 is no boost, 1 is max boost. This can be useful if the font does not render with clean smooth edges with the default intensity or if you are rendering the font at small font sizes. ## Character Presets Click on a preset to include its characters to the Font asset. Clicking on a preset will add the characters to the existing selection. ## Custom Character Range If you want to include a specific range of characters to the Font asset, enter the range in Hex and click the Plus icon to add the range to the character selection. ## Font ### Characters The characters that should be included in the Font asset. If you only need numbers for example, there is no need to include all the other characters of the Font. This is useful to keep Font assets small. Please note that some characters may not exist in the uploaded font. ## Process Font Click on the Process Font button after you make changes to the Font asset in order to generate a new version. -------------------------------------------------------------------------------- ## GSplat URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/gsplat/ A GSplat asset contains 3D Gaussian Splat data. PlayCanvas supports the import of GSplat data from [PLY](/user-manual/gaussian-splatting/formats/ply) files (including compressed PLY) and [SOG](/user-manual/gaussian-splatting/formats/sog) files. :::tip The [SOG format](/user-manual/gaussian-splatting/formats/sog) is recommended for its efficient compression, resulting in smaller file sizes and faster load times. ::: ## Inspector You can select a GSplat asset in the [Assets Panel](/user-manual/editor/interface/assets) and view it in the [Inspector](/user-manual/editor/interface/inspector). [Image: GSplat Asset Inspector] ## Properties The META section lists the key properties of the GSplat data. | Property | Description | |----------|-------------| | Format | The file format: PLY (`binary_little_endian 1.0`), Compressed PLY, or SOG (read-only). | | Splats | The total number of Gaussians stored in the PLY file (read-only). | | SH Bands | The number of spherical harmonics bands used for view-dependent color (read-only). | | Bound Min | The minimum bounds of the Gaussian splat data in 3D space (read-only). | | Bound Max | The maximum bounds of the Gaussian splat data in 3D space (read-only). | :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## HTML URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/html/ An HTML asset contains HTML code. The code can either be a full HTML page or just partial HTML. You can create a new HTML asset in the Editor or by uploading a file with an `.html` extension. To edit an HTML asset, right click on it in the Editor and select Edit. ## Inspector [Image: HTML Asset Inspector] The HTML asset inspector displays a preview of the HTML code contained in the asset. ## Properties This asset type has no configurable properties in the Inspector. It displays a read-only preview of the HTML code. :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## JSON URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/json/ [JSON](https://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. In PlayCanvas, JSON assets are used to store various types of structured data. Some example use cases are: - Configuration files - Data for procedural generation - Storing game settings - Level design data ## Inspector [Image: JSON Asset Inspector] The JSON asset inspector displays a formatted preview of the JSON data contained in the asset. ## Properties This asset type has no configurable properties in the Inspector. It displays a read-only preview of the JSON data with syntax formatting. :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Material URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/material/ A Material asset defines the visual appearance of a surface when rendered. PlayCanvas uses physically based rendering (PBR) to create realistic materials that respond correctly to lighting. Materials can represent a wide range of surfaces, from smooth plastic to rough wood to shiny metal. ## Inspector You can select a Material asset in the [Assets Panel](/user-manual/editor/interface/assets) and view it in the [Inspector](/user-manual/editor/interface/inspector). [Image: Material Inspector] The Material Inspector is organized into collapsible sections, each controlling different aspects of the material's appearance. ## Texture Transform Controls UV offset, tiling, and rotation for all texture maps. [Image: Texture Transform] | Property | Description | |----------|-------------| | Apply To All Maps | When enabled, the offset, tiling, and rotation values below apply to all texture maps in the material. When disabled, each map can have its own transform settings. | | Offset | The UV offset to apply to texture maps (U, V). | | Tiling | The UV scale/tiling to apply to texture maps (U, V). | | Rotation | The rotation angle (in degrees) to apply to texture maps. | ## Ambient Controls how the material responds to ambient lighting and ambient occlusion. [Image: Ambient] | Property | Description | |----------|-------------| | Ambient Occlusion | A texture containing pre-baked ambient occlusion data. Darker areas receive less ambient light. | | UV Channel | The UV set used to sample the AO texture (UV0 or UV1). | | Color Channel | Which texture channel to read the AO value from (R, G, B, or A). | | Occlude Specular | Controls how AO affects specular reflections: Off, Multiply, or Gloss Based. | | Vertex Color | Use vertex colors for ambient occlusion instead of a texture. | | Color | The ambient tint color multiplied with the scene's global ambient color. | | Intensity | Strength of the ambient occlusion effect (0-1). | ## Diffuse Controls the base color of the material when lit by dynamic light sources. [Image: Diffuse] | Property | Description | |----------|-------------| | Diffuse | The diffuse/albedo texture defining per-pixel color. | | UV Channel | The UV set used to sample the diffuse texture (UV0 or UV1). | | Color Channel | Which texture channels to read (R, G, B, A, or RGB). | | Vertex Color | Use vertex colors for diffuse instead of a texture. | | Color | The diffuse color. If a texture is set, this tints the texture. | ## Specular Controls the specular highlights and reflectivity of the material. The Specular section supports two workflows: Metalness and Specular. [Image: Specular] ### Common Properties | Property | Description | |----------|-------------| | Enable GGX Specular | Enables GGX specular response with anisotropy support for materials like brushed metal. | | Anisotropy | Texture defining per-pixel anisotropy direction (visible when GGX is enabled). | | Anisotropy Intensity | Strength of the anisotropic effect (0-1). | | Anisotropy Rotation | Rotation angle of the anisotropy direction in degrees. | | Use Metalness | Toggle between Metalness workflow (PBR) and Specular workflow (legacy). | ### Metalness Workflow When Use Metalness is enabled: | Property | Description | |----------|-------------| | Metalness | Texture defining per-pixel metalness. White (1) is metal, black (0) is non-metal. | | Vertex Color | Use vertex colors for metalness instead of a texture. | | Metalness | The metalness factor (0-1). Multiplied with the texture if present. | | Use Specular Color and Factor | Enable additional specular color control for non-metallic areas. | | Specular | Specular color texture (visible when Use Specular Color is enabled). | | Specularity Factor | Texture for per-pixel specularity factor. | ### Specular Workflow When Use Metalness is disabled: | Property | Description | |----------|-------------| | Specular | The specular color texture defining highlight color. | | Vertex Color | Use vertex colors for specular instead of a texture. | | Tint | When enabled, the Color below tints the specular texture. | | Color | The specular highlight color. | ### Glossiness | Property | Description | |----------|-------------| | Glossiness | Texture defining per-pixel glossiness/smoothness. | | Vertex Color | Use vertex colors for glossiness instead of a texture. | | Glossiness | The glossiness/shininess value (0-100). Higher values create sharper reflections. | | Invert | Treat the gloss map as a roughness map (inverts the values). | ## Emissive Controls light emission from the material surface. [Image: Emissive] | Property | Description | |----------|-------------| | Emissive | Texture defining per-pixel emission color. | | UV Channel | The UV set used to sample the emissive texture (UV0 or UV1). | | Color Channel | Which texture channels to read (R, G, B, A, or RGB). | | Vertex Color | Use vertex colors for emission instead of a texture. | | Color | The emissive color. If a texture is set, this tints the texture. | | Intensity | Multiplier for the emissive color. Values above 1 create overbright/bloom effects. | ## Opacity Controls material transparency and alpha testing. [Image: Opacity] | Property | Description | |----------|-------------| | Blend Type | How the material blends with the background: None (opaque), Alpha, Additive, Additive Alpha, Screen, Premultiplied Alpha, Multiply, Modulate 2x, Min, Max. | | Opacity | Texture defining per-pixel opacity. | | UV Channel | The UV set used to sample the opacity texture (UV0 or UV1). | | Color Channel | Which texture channel to read the opacity from (R, G, B, or A). | | Vertex Color | Use vertex colors for opacity instead of a texture. | | Intensity | The overall opacity (0-1). 0 is fully transparent, 1 is fully opaque. | | Alpha Test | Pixels with alpha below this threshold are discarded (0-1). | | Alpha To Coverage | Enables alpha-to-coverage for order-independent transparency (requires MSAA). | | Opacity Fades Specular | When enabled, opacity also fades specular reflections. Disable for glass-like materials. | | Opacity Dither | Dithering pattern for opacity: None, Bayer 8, or Blue Noise. | | Opacity Shadow Dither | Dithering pattern for shadow opacity. | | Alpha Fade | Fade factor for materials where Opacity Fades Specular is disabled (0-1). | ## Normals Controls surface detail through normal mapping. [Image: Normals] | Property | Description | |----------|-------------| | Normals | The normal map texture defining per-pixel surface orientation. | | UV Channel | The UV set used to sample the normal texture (UV0 or UV1). | | Bumpiness | Strength of the normal map effect (0-2). 0 has no effect, 1 is standard, 2 is exaggerated. | ## Parallax Adds depth illusion to surfaces using height mapping. Requires a normal map to be set. [Image: Parallax] | Property | Description | |----------|-------------| | Heightmap | The height map texture. White represents high areas, black represents low areas. | | UV Channel | The UV set used to sample the height texture (UV0 or UV1). | | Color Channel | Which texture channel to read the height from (R, G, B, or A). | | Strength | Intensity of the parallax effect (0-2). | ## Clear Coat Adds a secondary specular layer simulating a clear coating (like car paint or lacquered wood). [Image: Clear Coat] | Property | Description | |----------|-------------| | Clear Coat Factor | Intensity of the clear coat layer (0-1). Set to 0 to disable. | | Clear Coat | Texture defining per-pixel clear coat intensity. | | UV Channel | The UV set used to sample the clear coat texture (UV0 or UV1). | | Vertex Color | Use vertex colors for clear coat intensity. | | Vertex Color Channel | Which vertex color channel to use (R, G, B, or A). | | Clear Coat Gloss | Texture defining per-pixel clear coat glossiness. | | Glossiness | Smoothness of the clear coat layer (0-1). | | Invert | Treat the gloss map as a roughness map. | | Clear Coat Normals | Normal map for the clear coat layer (e.g., orange peel effect). | | Bumpiness | Strength of the clear coat normal map (0-2). | ## Sheen Adds soft, velvet-like reflections for fabrics and similar materials. [Image: Sheen] | Property | Description | |----------|-------------| | Use Sheen | Enable sheen specular effects. | | Sheen | Texture defining per-pixel sheen color. | | UV Channel | The UV set used to sample the sheen texture (UV0 or UV1). | | Vertex Color | Use vertex colors for sheen. | | Color | The sheen tint color. | | Sheen Glossiness | Texture defining per-pixel sheen glossiness. | | Glossiness | Smoothness of the sheen effect (0-1). | | Invert | Treat the gloss map as a roughness map. | ## Refraction Controls light bending through transparent materials like glass or water. [Image: Refraction] | Property | Description | |----------|-------------| | Dynamic Refractions | Enable real-time refraction using a grab pass. | | Refraction | Texture defining per-pixel refraction intensity. | | UV Channel | The UV set used to sample the refraction texture (UV0 or UV1). | | Vertex Color | Use vertex colors for refraction intensity. | | Refraction | Amount of light passing through the material (0-1). | | Index Of Refraction | Controls light distortion. Represented as 1.0 / IOR. Common values: glass ~0.67, water ~0.75. | | Dispersion | Strength of chromatic aberration (color separation). 0 means no dispersion. | | Thickness | Texture defining per-pixel material thickness. | | Scale | Thickness multiplier. Affects how much light is absorbed. | | Attenuation | Color of light absorption through the material volume. | | Attenuation Distance | Distance at which light is fully absorbed. | ## Iridescence Creates rainbow-like color shifts seen on soap bubbles, oil slicks, or beetle shells. [Image: Iridescence] | Property | Description | |----------|-------------| | Use Iridescence | Enable iridescent diffraction effects. | | Iridescence | Texture defining per-pixel iridescence intensity. | | UV Channel | The UV set used to sample the iridescence texture (UV0 or UV1). | | Iridescence | Intensity of the iridescence effect (0-1). | | Iridescence Thickness | Texture defining per-pixel thin-film thickness. | | Thickness Minimum | Minimum thin-film thickness in nanometers (nm). | | Thickness Maximum | Maximum thin-film thickness in nanometers (nm). | | Index of Refraction | IOR of the thin-film layer. | ## Environment Controls environment reflections using cube maps or sphere maps. [Image: Environment] | Property | Description | |----------|-------------| | Sphere Map | A sphere map texture for environment reflections (mutually exclusive with Cube Map). | | Cube Map | A cube map texture for environment reflections. If not set, the scene skybox is used. | | Reflectivity | How much environment reflection is visible (0-1). | | Projection | Cube map projection mode: Normal or Box. | | Center | Center point for box projection (X, Y, Z). | | Half Extents | Half-size of the box projection volume (W, H, D). | ## Lightmap Applies pre-baked lighting from a lightmap texture. [Image: Lightmap] | Property | Description | |----------|-------------| | Lightmap | The lightmap texture containing pre-baked diffuse lighting. | | UV Channel | The UV set used to sample the lightmap (typically UV1 for unique UVs). | | Color Channel | Which texture channels to read (R, G, B, A, or RGB). | | Vertex Color | Use vertex colors for lightmap data instead of a texture. | ## Other Additional render state controls. [Image: Other] | Property | Description | |----------|-------------| | Depth Test | When enabled, pixels are only rendered if they pass the depth test (nothing in front). | | Depth Write | When enabled, the material writes to the depth buffer. | | Cull Mode | Which faces to cull: None (render both), Back Faces (default), or Front Faces. | | Use Fog | Apply scene fog settings to this material. | | Use Lighting | Apply dynamic lighting to this material. | | Use Skybox | Use the scene skybox for environment reflections. | | Use Tonemap | Apply tonemapping to this material. | | Vertex Color Gamma | Interpret vertex colors as gamma-space (sRGB) values. | :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). For programmatic material creation, see the [StandardMaterial API](https://api.playcanvas.com/engine/classes/StandardMaterial.html). ::: -------------------------------------------------------------------------------- ## Render URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/render/ A Render asset contains 3D mesh data extracted from imported 3D model files (such as GLB or FBX). It defines the shape and structure of 3D models and is used by the [Render Component](/user-manual/editor/scenes/components/render/) to display geometry in the scene. Render assets are primarily used for: - Defining the shape and structure of 3D models - Applying materials to mesh surfaces ## Inspector The Render asset inspector displays metadata about the mesh and its relationship to the source container asset. ## Properties ### Meta [Image: Render Asset Inspector - Meta] | Property | Description | |----------|-------------| | Vertices | The total number of vertices in the mesh (read-only). | | Triangles | The total number of triangles in the mesh (read-only). | | Meshes | The number of mesh instances contained in the asset (read-only). | | Skinned | Whether the mesh contains skinning data for skeletal animation (read-only). | | Attributes | The vertex attributes present in the mesh data, such as position, normal, UV coordinates (read-only). | | Mesh Compression | The compression format used, if any (e.g., Draco) (read-only). | ### Render [Image: Render Asset Inspector - Render] | Property | Description | |----------|-------------| | Index | The index of this render asset within its source container (read-only). | | Container | A reference to the source container asset (GLB) from which this render was extracted (read-only). | :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Shader URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/shader/ A Shader asset contains GLSL code for custom rendering effects. You can create a new Shader asset by clicking New Shader in the Asset Panel or by uploading a file with an extension of `.vert`, `.frag`, or `.glsl`. To edit a Shader asset, right click on it in the Editor and select Edit. ## Inspector [Image: Shader Asset Inspector] The Shader asset inspector displays a preview of the GLSL shader code contained in the asset. ## Properties This asset type has no configurable properties in the Inspector. It displays a read-only preview of the shader code. :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Sprite URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/sprite/ A Sprite is a 2D graphic that can be rendered into a scene. A Sprite asset is a reference to a [Texture Atlas](/user-manual/editor/assets/inspectors/texture-atlas) and a sequence of frames from that atlas. In this way a sprite can either represent a single image (taken out of the atlas) or a flip-book style animation (multiple frames from the atlas). ## Inspector [Image: Sprite Asset Inspector] ## Properties | Property | Description | |----------|-------------| | Pixels Per Unit | The number of pixels in the sprite image that maps to 1 Unit in the PlayCanvas scene. For example, if `pixelsPerUnit` is 1 and the sprite is 32x32, it will be 32 units across and high when rendered in the scene. By default, a sprite with *Simple* render mode has `pixelsPerUnit` set to 100, meaning a 100x100 sprite will be 1 unit wide/high. *Sliced* sprites default to 1 because they are typically used for UI where 1 sprite pixel should map to 1 screen pixel. | | Render Mode | Controls how the sprite is rendered: **Simple** - the sprite does not use border values; **Sliced** - uses border values to perform [9-sliced](/user-manual/2D/slicing) rendering by stretching; **Tiled** - uses border values to perform [9-sliced](/user-manual/2D/slicing) rendering by tiling. | | Texture Atlas | The Texture Atlas asset that the sprite references. | :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Template URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/template/ A Template (also called a Prefab) is an asset that contains a piece of an Entity hierarchy. It has a root Entity and can have any number of children. A Template is a reusable Entity that you can instantiate dynamically at runtime or place multiple instances of it in your Scene. When you change the Template asset, all instances of the Template will also change. For more information about working with Templates, see [Templates](/user-manual/editor/templates/). ## Inspector {/*[Image: Template Asset Inspector]*/} The Template asset inspector displays an interactive 3D preview of the Template's entity hierarchy. You can rotate the preview by clicking and dragging. ## Properties This asset type has no configurable properties in the Inspector. It provides a visual preview only. :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Text URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/text/ A Text asset is used for storing plain text data. It's versatile and can be used for various purposes such as storing dialogue, configuration data, or any other textual information. You can create a new Text asset in the Editor or by uploading a file with a `.txt` extension. ## Inspector [Image: Text Asset Inspector] The Text asset inspector displays a preview of the text content contained in the asset. ## Properties This asset type has no configurable properties in the Inspector. It displays a read-only preview of the text content. :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Texture Atlas URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/texture-atlas/ A Texture Atlas asset is a texture asset with additional data which describes 'Frames' inside the texture. Frames are regions defined in the texture as a rectangle with a 'pivot' point which sets the positional and rotational center of the frame. Texture Atlases are created by right-clicking on a regular Texture asset and selecting **Create Atlas**, or by changing the default asset settings to enable [Create Atlases](/user-manual/editor/interface/settings/asset-import/). The Texture Atlas is used in combination with the [Sprite asset](/user-manual/editor/assets/inspectors/sprite) to render 2D graphics. ## Inspector [Image: Texture Atlas] ## Properties ### Frames The Frames of a texture atlas are keyed by a unique value, usually an integer string. The format of a frame is: ```javascript { rect: [0, 0, 0, 0], // u,v,width,height - width and height in pixels pivot: [0, 0], // x,y - as a proportion 0-1 border: [0, 0, 0, 0] // left, bottom, right, top - in pixels } ``` ### Texture Properties In addition to frame data, the Texture Atlas contains the same properties as a [Texture asset](/user-manual/editor/assets/inspectors/texture). :::tip To use this asset in scripts, see [Asset Attributes](/user-manual/scripting/script-attributes/esm/#asset-attribute). ::: -------------------------------------------------------------------------------- ## Texture URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/texture/ A texture is an image that can be assigned to a [material](/user-manual/editor/assets/inspectors/material) and then applied to a graphical primitive. ## Importing Textures There are 3 ways you can import texture assets into PlayCanvas: 1. Drag and drop images into the Assets panel. 2. Select 'Upload' from the context menu in the Assets panel and select an image using the file browser. 3. Import an FBX file that embeds textures. Supported image formats are: * JPG * PNG * AVIF * WEBP * GIF * TGA * BMP * TIF * HDR * EXR Imported JPG, PNG, AVIF, WebP and GIF files remain in their original format. GIF, TGA, BMP and TIF image types will be converted to JPG or PNG on import. If the imported image has transparency, it will be converted to PNG. Otherwise, it will be converted to JPG. HDR and EXR are [high dynamic range](https://en.wikipedia.org/wiki/High-dynamic-range_imaging) formats. Images of these types are converted to PNG on import and marked as being stored in RGBM format. RGBM essentially stores a multiplier for RGB values in the PNG's alpha channel, enabling the compression of an HDR format into a low dynamic range format. By default, imported images will be resized to the nearest power of two. For example, an image that is 323x414 will be resized to 256x512 on import. This is done because the graphics engine cannot utilize mipmapping with non-power of two textures. However, this behavior can be overridden by disabling the 'Textures POT' setting in the Asset Import panel before importing a non-power of two texture. ## Texture Properties Selecting a texture's thumbnail in the Assets panel will load it into the Inspector panel. Note that you can multi-select textures and edit the whole selection simultaneously in the Inspector. A texture shares the standard set of asset properties (ID, name, tags and so on). But it also has some texture-specific properties. [Image: Texture Properties] ### Texture Filtering Texture filtering gives control over how the color of a texture mapped pixel is calculated. 'Point' applies no filtering whereas 'Linear' will interpolate the color of a texel with those of its neighbors. This produces better visual results, particularly as a texture is minimized (where the texture occupies fewer pixels on the screen than it has texels). ### Anisotropy When textures are viewed on surfaces at an oblique angle, quality can suffer and they can appear blurred. To fix this problem, you can set a value for anisotropy. See how different anisotropy values can affect the appearance of a texture: [Image: Anisotropy] Note that as anisotropy increases, the cost of sampling the texture on the GPU also increases. ### Texture Addressing The texture addressing properties give you control over how a texture is sampled for texture coordinates outside the range 0 to 1. See how the different modes affect the sprite below: [Image: Addressing] ## Max Texture Size Different devices can support different texture sizes. Using [WebGL report](https://webglreport.com/) on the device and browser, we can see the max size supported. For example, this is from a MacBook Pro 16 inch (2020) laptop with Chrome which shows support up to 16384x16384. Macbook Pro WebGL report Whereas on a Samsung S7 mobile device, only 4096x4096 is supported. Samsung S7 WebGL report If the engine attempts to utilize a texture that exceeds the max texture size reported by WebGL, it will resize it down to this maximum size at runtime. Note that this is only done for texture loaded from images (PNG, JPG, AVIF, WebP, GIF). Compressed textures cannot be resized at runtime and will simply fail to render if they are too large for the device. If you would like to avoid downsizing at runtime, at the time of writing (Fri 23 Oct 2020), 4096x4096 is very widely supported with some developers even opting for 2048x2048 which is guaranteed to work everywhere. -------------------------------------------------------------------------------- ## WASM Module URL: https://developer.playcanvas.com/user-manual/editor/assets/inspectors/wasm/ Wasm Modules (also known as WebAssembly Modules) contain compiled executable code for the web. A Wasm module comprises three parts: * the binary executable file * the JavaScript glue code file * an optional fallback asm.js These files can be added to the project either by dragging and dropping the files into the Assets Panel or by selecting 'Upload' from the Assets Panel context menu. Please note that PlayCanvas Editor currently supports [Emscripten](https://emscripten.org/) compiled Wasm Modules only. ## Wasm Module Properties Once the files have been added to the project, select the Wasm Module to display its properties in the Inspector Panel: [Image: Wasm Module Properties] ### Name Name must match the module name defined in the glue and fallback script. This name is used to instantiate the module at load time. ### Glue script This is the JavaScript glue code required to execute Wasm code. ### Fallback script This is the optional fallback asm.js script to use when WebAssembly is not supported. -------------------------------------------------------------------------------- ## Asset Viewers URL: https://developer.playcanvas.com/user-manual/editor/assets/viewers/ Some of the assets have viewer tools that can help inspect them more closely. Assets that can be viewed in these will have the option to 'Open in Viewer' in the inspector and context menu. [Image: Open in Viewer option] Clicking on either of these options will open the viewer with the asset in a new tab. ## Model Viewer [Image: Model Viewer Preview] (Model: Copyright 2021 Wayfair LLC. [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) International) The [open source Model Viewer](https://github.com/playcanvas/model-viewer) is available for the following asset types: - Model (Source) that are GLBs - Model - Container - Animation The Model Viewer is useful for inspecting the model node hierarchy, morph targets and debugging animation issues. ## Texture Tool [Image: Texture Tool Preview] The [open source Texture Tool](https://github.com/playcanvas/texture-tool) is available for the following asset types: - Texture - Texture Atlas -------------------------------------------------------------------------------- ## Editor API URL: https://developer.playcanvas.com/user-manual/editor/editor-api/ :::warning The Editor API is a beta feature. Please use caution when using on live projects. ::: The Editor has a user accessible API that is currently in beta which can be used to help automate and extend the base functionality. The API is not yet considered stable and may change in the future as we continue development. However, it is unlikely that API will change a lot from its current state. The Editor API is open sourced on [GitHub](https://github.com/playcanvas/editor-api). The API documentation can be found [here](https://api.playcanvas.com/editor/). ## Automation Example The API can be accessed via the browser's devtools console allowing for automation of repetitive tasks. In the example below, we are using the Editor to find all the Entities that have the tag 'red' and disabling them by running code in the browser console. Editor API code: ```javascript (function() { const entities = editor.api.globals.entities.root.listByTag('red'); for (const entity of entities) { entity.set('enabled', false); } })(); ``` ## Extending Editor Functionality It is possible to add extra functionality to the Editor and create custom interfaces such as adding buttons. This can be done via a number of ways such as browser extensions or [user scripts](https://en.wikipedia.org/wiki/Userscript). User scripts is the more accessible out of the two which allows you to run custom code on top of the Editor. Below we have an example where a button has been added to the [Viewport](/user-manual/editor/interface/viewport) to generate and randomly place boxes into the scene. The PlayCanvas team are currently using the [Violentmonkey](https://violentmonkey.github.io/) open source browser extension to manage user scripts. Once the browser extension has been installed, adding your own or another developer's user script is very straightforward. Steps can be found in [Violentmonkey's documentation](https://violentmonkey.github.io/guide/creating-a-userscript/). The code for the above user script is: ```javascript // ==UserScript== // @name Example Script // @namespace Violentmonkey Scripts // @match https://playcanvas.com/editor/scene/* // @grant none // @version 1.0 // @author - // @description 20/10/2021, 11:40:21 // ==/UserScript== (function() { async function generateBoxes(count, position, radius) { // create box entity const box = editor.api.globals.entities.create({ parent: editor.api.globals.entities.root }); // find box material asset const boxMaterial = editor.api.globals.assets.findOne(asset => asset.get('name') === 'boxMaterial'); // add render component box.addComponent('render', { type: 'box', materialAssets: [boxMaterial.get('id')] }); // add a number of boxes around a point in the scene let offset = new pc.Vec3(); let rotation = new pc.Quat(); const result = []; for (let i = 0; i < count; i++) { const boxCopy = await box.duplicate(); boxCopy.set('name', 'Box ' + (i + 1)); offset.set(1, 0, 0); rotation.setFromEulerAngles(0, pc.math.random(-360, 360), 0); offset = rotation.transformVector(offset); offset.scale(pc.math.random(-radius, radius)); boxCopy.set('position', [position.x + offset.x, position.y + offset.y, position.z + offset.z]); result.push(boxCopy); } // delete original box box.delete(); return result; } function createButton() { const btn = new pcui.Button({ text: 'Generate Boxes' }); btn.style.position = 'absolute'; btn.style.bottom = '10px'; btn.style.right = '10px'; editor.call('layout.viewport').append(btn); let boxes; btn.on('click', () => { // delete existing boxes if (boxes) { editor.api.globals.entities.delete(boxes); boxes = null; } generateBoxes(10, new pc.Vec3(), 10).then(result => { boxes = result; }); }); } // Wait until the Editor is available before adding the button editor.once('load', () => createButton()); })(); ``` Let's break down the important areas of the script: At the top is the informational header about the script if you do share the script with other users. The important line is the `@match` attribute which controls which URLs the script is loaded on. In this case, it is set to load on any PlayCanvas scene. More information on how to change this can be found in [Violentmonkey's documentation](https://violentmonkey.github.io/api/matching/). ```javascript // ==UserScript== // @name Example Script // @namespace Violentmonkey Scripts // @match https://playcanvas.com/editor/scene/* // @grant none // @version 1.0 // @author - // @description 20/10/2021, 11:40:21 // ==/UserScript== ``` This is private Editor API to wait for an event when the Editor has fully loaded. Using the event ensures that the Editor API is accessible before the code to extend Editor features is run. ```javascript // Wait until the Editor is available before adding the button editor.once('load', () => createButton()); ``` The button created is from the [PCUI](https://github.com/playcanvas/pcui) framework library that the Editor is also using. Again, there is some private API use to get the Viewport DOM to attach the button to. ```javascript function createButton() { const btn = new pcui.Button({ text: 'Generate Boxes' }); btn.style.position = 'absolute'; btn.style.bottom = '10px'; btn.style.right = '10px'; editor.call('layout.viewport').append(btn); let boxes; btn.on('click', () => { // delete existing boxes if (boxes) { editor.api.globals.entities.delete(boxes); boxes = null; } generateBoxes(10, new pc.Vec3(), 10).then(result => { boxes = result; }); }); } ``` -------------------------------------------------------------------------------- ## Engine Compatibility URL: https://developer.playcanvas.com/user-manual/editor/engine-compatibility/ ## Introduction The Editor supports two major release streams of the engine: - The latest release of engine v1.x.x (**Engine V1**) - This supports WebGL1 and WebGL2, and receives critical bug fixes. It does not receive any new features. - The latest release of engine v2.x.x (**Engine V2**) - This supports WebGL2 and WebGPU but not WebGL1 for rendering. It receives both new features and fixes. You are free to switch between these at any time. ### Switching projects between Engine V1 and V2 This process will involve migration and updating of scripts given differences in our Engine API between Engine V1 and V2. All details regarding the engine changes can be found [here](/user-manual/engine/migrations) To initiate this navigate to the settings panel and click the `SWITCH TO ENGINE V2` button to convert your project to using Engine V2 (This will require a confirmation before converting). If you wish to switch back, there is a `SWITCH TO ENGINE V1` button in the same location for Project V2. :::important It is recommended to create a checkpoint before switching engines. ::: :::warning Once the switch has been confirmed, **all users** in the current project will be reloaded. ::: #### Scripting Given the changes in API for the engine you may wish to test your project in the launcher with Engine V1 or V2. You can do this by enabling the Force Engine V2 or Force Engine V1 checkboxes in the launcher options: Additionally, conditionally checking the Engine version at runtime will allow your script to be made compatible with both versions of the engine during the transition time. :::ai When behavior differs between Engine versions, use the **[Editor MCP Server](/user-manual/editor/mcp-server/)** to reproduce the same scenario in each. An AI assistant can correlate logs and captures with affected scripts and APIs to suggest a focused fix. ::: #### Gamma and Tonemap These settings were previously found under the rendering section of the Settings panel. However, in Engine V2, these have been moved to be set per camera. Each camera component will now have these additional fields: The viewport settings are now located inside the EDITOR section of the Settings panel: :::note If you change the settings per camera and switch back to Project V1, your per-camera settings will be lost. ::: #### sRGB Textures For Engine V2, textures must be set as sRGB or not, depending on their use case. The textures that store color data, such as diffuse and emissive maps, should use sRGB for accurate color representation. This is found under the texture asset panel as shown above. These will be automatically set. However, if there are conflicts, the console will display them: Click on the console message to open up the conflicting reference. If you wish to use the same texture for both sRGB and not, it is advised to duplicate your texture to cover both cases. -------------------------------------------------------------------------------- ## Common Questions URL: https://developer.playcanvas.com/user-manual/editor/faq/ ## How do I add a component? To add a **component** to an Entity, select the Entity and then click **Add Component** in the **Inspector** or right click on the Entity and select a component from the Add Component context menu. [Learn more](/user-manual/editor/scenes/components/) ## How do I add a script? You can use JavaScript to control the behavior of entities. Select any entity, add a script component and create a new script asset. [Learn more](/user-manual/editor/scripting/managing-scripts/) ## How do I change the background color? To change the background color of your scene, you should update the Clear Color property of the camera in your scene. You could also try adding a [skybox](/user-manual/editor/assets/inspectors/cubemap/) to your scene. [Learn more](/user-manual/editor/scenes/components/camera/) ## How do I change the material of a model? Every surface on a 3D model is rendered using a **material**. The material defines the properties of that surface, such as its color, shininess, bumpiness etc. You can create a new material and drag and drop it on your model or you can select its existing materials and edit their properties in the Inspector. [Learn more](/user-manual/editor/assets/inspectors/material/) ## How do I create a cubemap? Cubemaps are a special type of texture asset. They are formed from 6 texture assets where each texture represents the face of a cube. To create a cubemap click on the ** Add** button in the Assets panel and select **New Cubemap**. Then drag 6 textures in the cubemap inspector. To take advantage of Physically Based Rendering make sure you click **Prefilter** after setting the 6 textures. [Learn more](/user-manual/editor/assets/inspectors/cubemap/) ## How do I create an Entity? You can create a new Entity by clicking on the Add button in the Hierarchy panel or right click on an Entity and use the **New Entity** menu item. ## How do I create a light? You can create a light by adding a **Light** component to an Entity. You can also right click on an Entity and select New Entity / Directional Light to create a new directional light and similarly for spot lights and omni lights. [Learn more](/user-manual/editor/scenes/components/light/) ## How do I create a material? Every surface on a 3D model is rendered using a **material**. The material defines the properties of that surface, such as its color, shininess, bumpiness etc. To create a material click on the ** Add** button in the Assets panel and then select **New Material**. [Learn more](/user-manual/editor/assets/inspectors/material/) ## How do I create a new shader? You can create a new shader asset from the asset panel. Click **Add Asset -> Shader**. [View tutorial](http://developer.playcanvas.com/tutorials/custom-shaders/) ## How do I create a shape like a box or sphere? You can add primitive shapes like boxes, spheres and others by adding a **Render Component** on an Entity and changing its type to the desired shape. You can also right click on an Entity and select New Entity/Box to add a box (similarly for other shapes). [Learn more](/user-manual/editor/scenes/components/render/) ## How do I create a skybox? To create a skybox for your scene you first need to create a [Cubemap asset](/user-manual/editor/assets/inspectors/cubemap/). Then you can drag and drop the Cubemap inside the 3D viewport, or you can go to the Scene Settings and drag the Cubemap in the Skybox field. [Learn more](/user-manual/editor/interface/settings/rendering/) ## How do I delete an asset? To delete an asset select it and press **Delete** or right click on it and select Delete. ## How do I delete an Entity? You can delete an Entity by selecting it and pressing **Delete**. Alternatively you can click on the Delete button in the Hierarchy panel or right click on the Entity and select Delete from the context menu. ## How do I duplicate an Entity? To duplicate an Entity use the Duplicate button in the Hierarchy panel or press **Ctrl+D**. You can also copy and paste an Entity. To copy press **Ctrl+C** and to paste **Ctrl+V**. ## How do I play an animation? To play an animation of a 3D model you need to create an Entity with a [Model Component](/user-manual/editor/scenes/components/model/) and an [Animation Component](/user-manual/editor/scenes/components/animation/). The **Model Component** will render your model and the **Animation Component** will play animations. To render the model drag a model Asset in the Asset field of the Model Component. To play animations drag Animation Assets on the Assets field of the Animation Component. ## How do I play a sound? To play sounds you need to add a [Sound component](/user-manual/editor/scenes/components/sound/) to an Entity. Then you can create slots to play [Audio assets](/user-manual/editor/assets/inspectors/audio/). Simply click "Add Slot" and drag an Audio Asset on the Asset field. In order to hear the sounds you also need to add an [AudioListener component](/user-manual/editor/scenes/components/audiolistener/) to an Entity - usually to the Camera Entity. You can create Audio assets by dragging audio files from your computer into the Assets panel. [View tutorial](/tutorials/basic-audio/) ## How do I remove a component? To remove a component, select the Entity and then click on the ** Delete** button in the Inspector next the component’s title. ## How do I render a 3D model? To render a 3D model you need to add a **Model Component** to an Entity and drag a **Model Asset** on the Asset field. Alternatively you can drag and drop a Model Asset from the Assets Panel into the 3D Viewport. [Learn more](/user-manual/editor/scenes/components/model/) ## How do I move / rotate / scale an Entity? To move an Entity, select it and then move it using the ** Translate tool**. To rotate it use the ** Rotate tool** and to scale it use the ** Scale tool**. Switch between the Translate / Rotate / Scale tools by pressing 1 / 2 / 3 respectively. ## How do I upload assets? To upload Assets simply drag and drop files from your computer into the Assets panel. Your files will be processed by the server and will appear shortly after in the Assets Panel. [Learn more](/user-manual/editor/assets/importing/) ## How do I use physics? To give physical properties to an Entity you need to add a [Collision component](/user-manual/editor/scenes/components/collision/) to it and a [RigidBody component](/user-manual/editor/scenes/components/rigidbody/). The Collision component gives a physical shape to the Entity and the RigidBody component makes the Entity be simulated by the physics engine. You can change the default [gravity](/user-manual/editor/interface/settings/physics/) in the Scene Settings. [View tutorial](/tutorials/collision-and-triggers/) ## How do I use real-time shadows? Real-time shadows are rendered for each light source that has **Cast Shadows** enabled. To enable shadows, select an Entity with a Light component and enable Cast Shadows. You also need to enable Cast Shadows on any Model components in your scene. [Learn more](/user-manual/graphics/lighting/shadows/) -------------------------------------------------------------------------------- ## Getting Started URL: https://developer.playcanvas.com/user-manual/editor/getting-started/ If you are new to the PlayCanvas Editor, this section should get you up to speed quickly. -------------------------------------------------------------------------------- ## The Editor Workflow URL: https://developer.playcanvas.com/user-manual/editor/getting-started/workflow/ Building 3D web apps with the PlayCanvas Editor is easy. ## Create and upload assets [Image: assets] PlayCanvas supports a wide variety of industry standard asset formats. For example, upload images, 3D models, audio files or custom text or binary file formats. ## Construct your scene [Image: scene] The PlayCanvas Editor is a visual building tool which is used to construct scenes. Build a hierarchy of entities using built in components like 3D models, collision, particle effects and more. ## Add interactivity [Image: script] Using web standard Javascript attach custom behaviors to your entities. Add interactivity on any scale from a simple click handler or orbit camera to a full massively multiplayer online game. ## Publish your application [Image: publish] When your application is ready for sharing a simple one-click publish will get your application live on the internet hosted by PlayCanvas for free. Alternatively download your application for self-hosting on your own web server. -------------------------------------------------------------------------------- ## Your First App URL: https://developer.playcanvas.com/user-manual/editor/getting-started/your-first-app/ Developing applications in the PlayCanvas Editor is easy and fun. Let's spend a few minutes learning the basics. We'll recreate the following simple 3D app: [Interactive Demo] *Use the arrow keys to move the red ball around.* To begin, navigate to your PROJECTS page. [Image: Projects Page] Select the NEW button to create a new project: [Image: New Project] Enter `My First App` as the project name. The description is optional and can be filled out later. Hit CREATE. With your project created, we can dive right into the Editor - simply hit the EDITOR button: [Image: Editor Button] When you first open the Editor, you should find that a minimal scene has been created for you: [Image: Editor] Specifically, you have a camera (to render the scene), a box sitting on a plane and a light (to illuminate the 3D objects). You can easily change the box to another shape, like a sphere. To do this, select the Box entity in the HIERARCHY panel. In the Inspector panel on the right, change the Type property of the MODEL component from Box to Sphere. To be complete, rename the Entity from Box to Sphere too! [Image: Box To Sphere] But our sphere is a slightly boring gray color. Let's color it red! To do this, we must create a material by hitting the **+** icon in the ASSETS panel: [Image: Create Material] Select the material and its properties will appear in the Inspector panel to the right. Expand the DIFFUSE section and click on the color swatch to edit the color to red: [Image: Red Material] Next, we must assign the material to the sphere. You can do this with a simple drag and drop operation: [Image: Drag And Drop Material] Now let's set up the Camera entity. Select it in the HIERARCHY panel: [Image: Editor Camera Selected] Notice the little preview window that has appeared for the selected camera. Let's edit the camera's position and rotation to view the cube from directly in front. Edit the camera's position and rotation with the values below: [Image: Camera Transform] Next, let's make the sphere controllable with the arrow keys on the keyboard. To do this, we must create a script. Right click the Sphere entity and select `Add Component -> Script`. [Image: Add Script Component] A script component will appear in the Inspector on the Sphere entity. To create a script asset on the script component, enter the name `movement.js`. [Image: Create Script Asset] Hit Enter and your script will be created. [Image: Edit Script] Now hit EDIT to open the Code Editor. You'll see the following skeleton script: To make the sphere controllable, let's add some code to the `update` function. Copy and paste the code below: When the code is updated, save the script using CTRL+S (or CMD+S on Mac) and close the Code Editor tab. You are now ready to preview your app by opening the Launch page. To do this, hit the Launch button in the top right of the Editor's 3D view. [Image: Launch Button] The Launch page opens in a new tab. When it opens, try pressing the 4 arrow keys to move the sphere around. [Image: Launch Page] :::tip There is a 'Live Link' between the Editor and the Launch page. Any change you make in the Editor will be reflected in the Launch page in real time! It can be convenient to place the Launch page side by side with the Editor while you are working. [Image: Editor Live Link] ::: The final step is to publish your app so you can share it with others. To do this, click on the button in the left hand side toolbar. [Image: Publish Button] This will open up the Publishing dialog. Here you can publish a build (or even download a build for self-hosting). [Image: Publish] Click the PUBLISH TO PLAYCANVAS option. You can then configure your published app. [Image: Publish New Build] Leave the defaults, scroll down and select PUBLISH NOW. [Image: Builds] You now have a URL for your published build! Feel free to share it with the world on Twitter or Facebook! And so, that is the process from start to finish for building and publishing a PlayCanvas application. In this quick introduction, we have touched on the basics. Now explore the rest of the User Manual to learn some more advanced topics. Good luck and have fun! -------------------------------------------------------------------------------- ## Editor Interface URL: https://developer.playcanvas.com/user-manual/editor/interface/ [Image: Editor Interface] This is the main interface to the PlayCanvas Editor. You can see labeled the main areas: * [**Toolbar**](toolbar.md) Commonly used commands are available on the toolbar for quick access. * [**Hierarchy**](hierarchy.md) A hierarchical view of the Entities that make up the open Scene. Use this to select, delete and re-parent Entities. * [**Inspector**](inspector.md) Detailed properties of the selected [Entity](/user-manual/glossary#entity), [Asset](/user-manual/glossary#asset) or [Component](/user-manual/glossary#component). * [**Viewport**](viewport.md) A 3D view onto your scene, use this view to select, position and orientate Entities. * [**Assets**](assets.md) A view of all the Assets in the current Project. You can search for assets by name, filter by type and also drag and drop assets to various slots or in the Design View. -------------------------------------------------------------------------------- ## Assets Panel URL: https://developer.playcanvas.com/user-manual/editor/interface/assets/ The Assets Panel manages all of the Assets that are available in your project. From here, you can create, upload, delete, inspect and edit any Asset. [Image: Assets Panel] The Assets Panel provides powerful features for organizing and managing your project's assets, including: - **Folder organization** - Create a hierarchy of folders to organize assets - **Search and filter** - Find assets by name, ID, tags, or type - **Drag and drop** - Move assets between folders or into the viewport - **Copy and paste** - Share assets between projects - **Reference checking** - See where assets are used in your scene For detailed documentation on all Assets Panel features, see the [Assets section](/user-manual/editor/assets/). -------------------------------------------------------------------------------- ## Hierarchy Panel URL: https://developer.playcanvas.com/user-manual/editor/interface/hierarchy/ [Image: Hierarchy Panel] The Hierarchy panel shows you a tree view of your entire Scene which is made up from a hierarchy of Entities. A Scene will always contain the Root Entity at the top of the tree. All the other Entities you see here on the right have been added by the developer. The Hierarchy panel is great for quickly finding Entities as all the Entities in your Scene will be visible all the time. Clicking on an Entity in the Hierarchy will select it. ## Creating and Destroying Entities Once an Entity is selected in the Hierarchy, you can create a new child Entity or delete the Selection. You can do this, either using the buttons in the top right of the Hierarchy panel, or by opening the context menu via a right click operation. ## Organizing the Hierarchy The order in which Entities are listed in the tree view is important. As the Scene is a hierarchy, Entities can be *children* of another Entity -- their *parent* -- and the transform matrix of a parent Entity is applied to all of its children. If you move or rotate a parent Entity, all children will move or rotate underneath the parent. This is very useful for simplifying the manipulation of many Entities. The structure of the Hierarchy can be edited via drag and drop. Simply select and drag any Entity in the Hierarchy. In this way, you can quickly reorder or reparent Entities. When you reparent an Entity in the Editor, its world-space transform (position, rotation, and scale) will be preserved so you won't see the Entity move, rotate, or change size after you change its parent. If you do not want that behavior, hold Ctrl (or Cmd on Mac). :::note Scale preservation works best when parent entities use uniform scaling. When non-uniform scale is combined with rotation in the hierarchy, the world scale becomes an approximation and may not be perfectly preserved. ::: ## Searching the Hierarchy Near the top of the Hierarchy panel is a Search box which you can use to dynamically filter the content of the Entity tree. [Image: Hierarchy Panel Search] By default, the search will filter based on entity names with 'Smart Search' enabled. Smart Search is fuzzy, which means it matches names that are similar to the search string rather than exactly the same. This is useful if you can't quite remember the name of the Entity you are searching for. You can customize the search by clicking the magnifying glass: [Image: Hierarchy Panel Search Options] ## Duplicating Entities You can duplicate Entities by selecting them and hitting Ctrl+D (or Cmd+D on Mac) or by right clicking and selecting Duplicate. A copy of each Entity will be created right next to its original. ## Copying / Pasting Entities If you wish to paste Entities under a new parent you can select them and hit Ctrl+C (or Cmd+C on Mac) to copy them, then select the new parent and then Ctrl+V (or Cmd+V on Mac) to paste them under the selected parent. You can also use the Copy and Paste options when you right click on the selected Entities. You can also copy and paste Entities between different Scenes or even different Projects. Just follow the same steps to copy Entities and then go to the desired Scene, select the desired parent and paste the Entities. The Editor will try to match any Asset references on the pasted Entities by path in the new Project. For example, if you are copy-pasting an Entity with a Model component that references a Model Asset called `mymodel.fbx` then when you paste the Entity in the other Project, the Editor will try to find an Asset named `mymodel.fbx` in the same folder. If a matching Asset is not found it will be left as missing so that you can fix it manually. -------------------------------------------------------------------------------- ## Inspector Panel URL: https://developer.playcanvas.com/user-manual/editor/interface/inspector/ [Image: Inspector Panel] The Inspector panel shows attribute values for the currently selected item. Depending on what you have selected, you will see different inspector panels. Some available selections are: * **Entity/Component Inspector** * **Texture Inspector** * **Material Inspector** * **Cubemap Inspector** Modifying these values is how you specify how your [Entity](/user-manual/glossary#entity) behaves. For example, you can set which model to render for a Model Component, or what color a light is. Some attributes are simple text or numbers in which case a standard text field or slider control will be used. Other values may require a more specialized input method. For example, choosing an Asset highlights available Assets in the asset panel. Some values can be manipulated via the viewport, for example, the Translate, Rotate and Scale values can be edited by moving and Entity dragging the relevant [Gizmo](/user-manual/glossary#gizmo) around in the viewport. When running both a game and the Editor simultaneously changes to attributes will be transmitted to Entities in the running application. An excellent way of iterating on values is to launch your game using the Play button, then place the Editor and the game tabs side by side and tweak values in the Editor as you watch and play the game. ## Copying and Pasting Attributes The Inspector supports copying and pasting attribute values across entities and assets, making it easy to duplicate configurations and speed up your workflow.