How do I programmatically add a script to an entity without the editor?

I notice there are some questions with the same topic, but they all use the playcanvas editor.

I am using playcanvas engine without the editor, and here is my folder structure:

├── app.js
├── camera.js
├── index.html
└── libs
    └── playcanvas-stable.js

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <style>
   body {
       margin: 0;
       padding: 0;
   }
  </style>
  <script src="/libs/playcanvas-stable.js"></script>
</head>
<body>
  <canvas id="application"></canvas>
  <script src="/app.js"></script>
</body>
</html>

camera.js

pc.script.create('Camera', function (context) {
  var Camera = function (entity) {
    this.entity = entity;
  };

  Camera.prototype = {
    update: function (dt) {
      console.log(dt); // do not trigger.
    }
  };

  return Camera;
});

app.js

var canvas = document.getElementById('application');
var app = new pc.Application(canvas, {});
app.start();

app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);

var cameraEntity = new pc.Entity();
cameraEntity.addComponent('camera');
app.root.addChild(cameraEntity);
app.systems.script.addComponent(cameraEntity, {
  scripts: [{
    name: 'Camera',
    url: './camera.js'
  }]
}); // not work.

I found most posts mention to use context.systems.script.addComponent(entity, { scripts: [] }) to add script to entity programmatically, but I am failed.

Can anyone tell me how to do it ? thanks.

1 Like

In your case, it’s as simple as directly creating the script with the cameraEntity like this:

// add the scripts component that will hold the scripts for this entity
cameraEntity.addComponent("script");
// create the script
cameraEntity.script.create('camera', function(context){
     // script content here
});

I am however getting this error:

script ‘camera’ is not found, awaiting it to be added to registry

So just going to wait and see if someone knows the right answer.

2 Likes

I found the right answer at Adding a script component at run time.

Just do these steps:

// camera.js
var Camera = pc.createScript('camera');
Camera.prototype.update = function (dt) {
  console.log(dt);
};

// app.js
app.assets.loadFromUrl('./camera.js', 'script', function (err, asset) {
  cameraEntity.addComponent('script');
  cameraEntity.script.create('camera');
});

Then it can print the dt from Camera.prototype.update.

7 Likes

Nice done,thx for your help my friend:)