Personalized Name Puzzle Customizer Developing WIP (text-mesh.js)

Hello everybody, I would like to ask some support and will be very happy for your suggestions, help and advices!

I want to create customizer for name puzzle for kids.
The logic next:

  1. client enter the name, script generates 3d text.
  2. client select color scheme, script should change color(material) of each letter according to script scenario.
  3. client select if he want additional engraving on the back of the plate.
  4. client can add pegs for the letters.
  5. client approve product and image is being generated send via api with all selected values to our shop.

I started to work on it and learned many tutorials here and on the forum, but however I hope there can be some things community can help to understand if this possible and how can I implement it.

step 1.
Based on text-mesh.js script generates text that entered to html input field and when ENTER pressed script regenerates 3d text in viewport (this is step 1.)

//this code takes value from html input, put it into TextMesh.text attribute and recreates 3d text
TextMesh.prototype.update = function(dt) {
      if (pc.app.keyboard.isPressed(pc.KEY_ENTER)) {
        this.text = document.getElementById("name").value;
        this.createText();
      }
};

step 2.
I can change color of the whole name, but unfortunately I don’t understand, how can I apply different materials randomly to child elements (each letter).
I tried to set it with those commands:

this.material="1"; //this one change whole TextMesh material, this is good
this.entity._children[0].material="2"; // this one apply attribute that undefined previously, but it don't change the material of the selected child element

question 1 How to apply different material each letter separately?

step 3.
I guess I need to create plate at first and make it size dynamically changing based on the width of the 3d text generated.
I hope to find in Documentation something like, Dimension or Length instead of Position (LocalScale):

this.entity.getPosition();
this.entity.getLocalScale();

question 2 How can I get the width(one axis length) of selected object?

Link to the editor project:
https://playcanvas.com/editor/project/1157431

Link to the Launch(result) project:
https://launch.playcanvas.com/1890395?debug=true

I will be very happy to have help, advices, suggestions and will update this post during development and probably will have more questions soon…

Hi @Serjozha and welcome!

Maybe the example project below can help you with this.

https://developer.playcanvas.com/en/tutorials/switching-materials-at-runtime/

1 Like

Hi @Albertos Thank you for reply, I’ve tried this method already but got an error in console that It’s not possible to read properties of undefined (reading ‘length’)…

What is exactly undefined? Can you share the complete error?

i’ve added code from ‘switching-materials-at-runtime’ and got the error as on the screenshot below:

when I tried to debug, I used command on initializing:

TextMesh.prototype.initialize = function () {
....//some code
console.log(this.materials.length);
....//some code
}

and also see the same error that it cannot read properties of undefined, I guess it’s materials

at the moment trying to set value with

this.material.resource

but I don’t understand if this can set or only get values, seems changing values in code, but not in the viewport…

You are probably missing the attribute materials that is used in the example project to add the two example materials.

You cannot copy/paste code from an example project directly into your own project. You need to study the example project to be able to know what the code does and how you can use it in your own project.

1 Like

Ok, thank you @Albertos !
I will study example more detailed to be able to implement it in my project!
Hopefully return soon with results!

1 Like

Hi again, @Albertos , thanks for advice again!
Managed to change color based on the “switching-materials-at-runtime”

But still don’t have luck to change materials for every letter, don’t understand how to select this children elements and set material to each letter separately

PlayCanvas_Changing Material

Well done! :ok_hand:

It’s a bit complicated, because I don’t know how text-mesh.js exactly works.

If the text mesh is a parent entity and each letter is a child entity, then you might be able to change the line below a bit, but that’s just a guess.

// all letters
var renders = this.entity.findComponents('render');
// only first letter
var renders = this.entity.children[0].findComponents('render');
1 Like

Hi everyone, once again!
Dear @Albertos Thank You very much for the advice to the right path to develop!
I’ve managed to select each letter and run function to change every letter according to chosen color combination by user.

Also as you can see from .gif I’ve developed engraving and pegs for each letter adding and combining text-mesh.js for this.

Also managed to create a screenshots.
Mostly code for manipulation as a basis I took here from free tutorials and example.
The hardest part were to understand the workflow of the PlayCanvas, to be honest I fell in love with it and the result!

Some minor changes, probably will be made in the future…

Now I’m pretty happy with the results,

PUZZL CUSTOMIZER

but unfortunately I can’t run it outside of PlayCanvas hosting, that make this work useless…
I’ve downloaded the .zip file and when running from my server I see black screen in the viewport and in the console I see :

  1. Error loading binary resource: ARLRDBD.ttf.bin [403] (playcanvas-stable.min.js:6 Error loading binary resource: )
  2. Error while loading scene JSON 1890395.json: First argument to DataView constructor must be an ArrayBuffer
    TypeError: First argument to DataView constructor must be an ArrayBuffer (start.js:213 )
  3. loading.js:33 Uncaught TypeError: Cannot read properties of null (reading ‘parentElement’)

error screenshot:


browser screenshot:

I see that there is problem to .ttf.bin font, that should be loaded to the PlayCanvas as suggested by text-mesh.js developer Will, but I have no idea how to solve it and in which direction to think with it.

Thank you for your help and advices again!!

1 Like

Wow! That looks very good! :star_struck:

I assume it will be some kind of coat rack? :innocent:

Users that are be able to help with the self-hosting problem can reply in the topic below.
https://forum.playcanvas.com/t/cant-run-project-on-my-server/

1 Like

Oh wait, it will be a puzzle ofcourse! :upside_down_face:

1 Like

Thank you!! Dear @Albertos feeling some feedback helped me to believe that I can do it, because I really was close to refuse this task in some points ^:))

When kid will grow up and move to his own place maybe he/she can use it as a coat rack as well )))

1 Like

OK, the problem with self-hosing for this projected was that default NGINX server configuration deny access to .bin files. (error 403)
Using text-mesh requires uploading fonts with “cheat”, renaming .ttf extending it with .ttf.bin and than renaming in PlayCanvas back to .ttf, but when deploying project font still saved in assets files as a .ttf.bin, that by default not allowed to use by server.

So when allowing .bin in server configuration (NGINX or APACHE) to project location will give ability to run the PlayCanvas project, HURRAY!

1 Like

Also sharing code below I used for nginx site configuration (/etc/nginx/sites-available/domain.com):
inside

server {
#your code goes here…
}

location /PUZZL/{
    root /var/www/domain.com/htdocs/;

    location ~*^.+\.(bin) {
        access_log off;
        log_not_found off;
      }
    }

this will give access only for the folder DOMAIN.COM/PUZZL/ path for all the .bin extensions
for user browser