Bug? Error when trying to load a new texture from code

So I have written some code to dynamically load textures while playing the game, I tried following the example for the Facebook API:

Specifically this is the code that fails for me:

var asset = new pc.Asset(photo.id, "texture", {
       url: photo.images[0].source
 });

app.assets.load(asset);       

I tried simplifying the call to make sure it was not something I added, and even this simple instruction causes the same error:

app.assets.load(new pc.Asset('test', 'texture', { url: 'https://c1.staticflickr.com/9/8873/18598400202_3af67ef38f_q.jpg' }));

The error points here:

Uncaught TypeError: Cannot read property '_loader' of null
    at Asset.getPreferredFile (playcanvas-stable.dbg.js:45784)
    at AssetRegistry.load (playcanvas-stable.dbg.js:46079)
    at <anonymous>:1:12

And this is exactly the line in the framework code that fails:

var app = this.registry._loader._app;

Apparently this.registry is null.

Looks like a bug to me, but maybe I’m doing something wrong here?

Hi @mariogarranz,

Are you using the Playcanvas engine directly or through an editor built project? Indeed it seems that the app instance with all the resource loaders haven’t been fully initialized prior calling your code.

If that isn’t the case, have you tried the following method?

1 Like

I launched the project from the editor, the function is then called a couple of seconds after the game is running (it needs to wait for other promises to resolve first), so I don’t think it’s a matter of timing.

If I just run it manually from the console, I get the same error (I exposed app as a global variable for testing).

I will try the alternative method you suggest.

1 Like

Little update:

1 - Trying it from a build I have the same issue.

2 - loadFromUrl seems to work, however I cannot assign a name to the asset if I use this method, which is something I would like to do to be able to find the asset later through AssetRegistry.find. Manually replacing the asset name does not work, I assume the AssetRegistry has a key-value structure and does not iterate through the asset names to find it.

Right, so if you want a custom name, then you have to create the pc.Asset instance yourself then. Much like you’ve already found out, here is the correct way to do that:

var asset = new pc.Asset("My Asset Name", "texture", {
  url: "https://c1.staticflickr.com/9/8873/18598400202_3af67ef38f_q.jpg",
});

this.app.assets.add(asset);

asset.ready(
  function () {
    console.log(this.app.assets.find("My Asset Name"));
  }.bind(this)
);

this.app.assets.load(asset);
1 Like

Right, but that brings us back to the bug that started this post: AssetRegistry.load is failing :sweat_smile:

I’ve tried this code on an empty project, passing it your image url and it worked correctly.

Both inside a pc script and directly in the console. Can you provide a project url that reproduces your issue?

1 Like

So I was trying to create a new project to show the error and checked your code. Apparently this is what was missing:

this.app.assets.add(asset);

Which is weird, because the official example here doesn’t call AssetRegistry.add.

The issue is now solved, thanks a lot! :slight_smile:

1 Like

You are right, nice catch!

Would you like to submit an issue about it on the docs repo?

1 Like

Sure, thanks!

1 Like