Create a download(export) button/function for the 3d model

Hi guys,
I would like to know if it is possible to create the project I have conceived using PlayCanvas. In short, the user must assemble a model from the proposed tool and download this model to his PC.
The main question is to create a download button for the created model.
I found information only in downloading screenshots and I hope that it is possible to download the model as well.

Hi @Alexei_Dobrynovich and welcome,

There isn’t official support for exported models from a PlayCanvas scene.

There is this work in progress glTF exporter by @will (I think it needs an older PlayCanvas engine to launch): PlayCanvas 3D HTML5 Game Engine

Some other users have also played with OBJ export (for mesh geometry export, no material/texture support).

Actually, we have a fully supported glTF exporter here:

It was written by @mvaligursky.

1 Like

So nice, I knew I had to tag Will on this! Very happy that this is officially available :clap:

1 Like

See an example here:

It has limited material support though, only handles the basic material properties. Try to export the glb file from the example, and view it in the viewer: PlayCanvas glTF Viewer


Thank you all for your help @Leonidas , @will , @mvaligursky .
After seeing your answers, I took the plunge and learned JS. Outcome. I was able to make a download button.
But there is one but. The bundle downloads everything below in the hierarchy. Here is a working example (See scene 2)([PlayCanvas | HTML5 Game Engine]).

I tried to do it using Application Events, but it gives an error (Uncaught TypeError: this.downloadGlb is not a function).

`Export.prototype.initialize = function() {
const exporter = new GltfExporter();
const buffer = exporter.buildGlb(this.entity);

var onPlayerMove = function(x, y) {
};'ruun', onPlayerMove);

this.on('destroy', function() {'player:move', onPlayerMove);


ButtonLogic.prototype.initialize = function() {


    this.entity.button.on('click', function() {'ruun');


    }, this);


There was another attempt to pass true to the (onPlayerMove) function, to make a while loop that executed this.downloadGlb(buffer);. But I couldn’t interact with the (onPlayerMove) function.

Sorry, I don’t understand what you mean here

At startup, only model (mod _a) is exported. Therefore, I need to bind the export script to the root so that two models are exported (mod_a and mod_b).

The way I would do this is to have an Entity as the parent of all the other entities that you want to export.

Then pass that to buildGlb function


var Export = pc.createScript('export');
Export.attributes.add('NEntity', { type: 'entity'});
Export.prototype.downloadGlb = function (buffer) {
    var element = document.createElement('a');
    var blob = new Blob([ buffer ], { type: "application/octet-stream" });
    element.href = URL.createObjectURL(blob); = 'scene.glb'; = 'none';

// initialize code called once per entity
Export.prototype.initialize = function() {
    this.entity.button.on('click', function() {
        const exporter = new GltfExporter();
        const buffer = exporter.buildGlb('NEntity');
    }, this);

I hope I understood you and did as you suggested. But it gives an error. Or did I make a mistake somewhere?


This should be:

        const buffer = exporter.buildGlb(this.NEntity);

New error.
I added you to the project (maybe this will help you better understand)

        const buffer = exporter.buildGlb(this.ENntity);

You made a typo. This should be:

        const buffer = exporter.buildGlb(this.NEntity);
1 Like

I am very sorry for such mistakes. I looked for about two minutes and could not find a difference in your example (vision leads). :sweat_smile:
Thank you very much for your help!