I still don't get how to make a main menu


#6

To be able to call your game scripts from an outer context (like the buttons, they are in the HTML document context, not the PlayCanvas app context), you have to declare static functions.

So let’s see, this is how a standard playcanvas script looks like:

var Rotate = pc.createScript('rotate');

Rotate.attributes.add('speed', { type: 'number', default: 10 });

// initialize code called once per entity
Rotate.prototype.initialize = function() {
    this.local = false; // choose local rotation or world rotation
};

// update code called every frame
Rotate.prototype.update = function(dt) {
    if (this.local) {
        this.entity.rotateLocal(0, this.speed * dt, 0);
    } else {
        this.entity.rotate(0, this.speed * dt, 0);
    }
};

Rotate.prototype.RotateSpecified = function(degrees){
     this.entity.rotate(0, degrees, 0);
};

// swap method called for script hot-reloading
// inherit your script state here
Rotate.prototype.swap = function(old) {
    this.local = old.local;
};

Now, you can’t call anything on that script from another script directly, because it has its own context.

To call it, you would need to create a static reference to this script’s context. How?

As easy as this:

// initialize code called once per entity
Rotate.prototype.initialize = function() {
    this.local = false; // choose local rotation or world rotation
    Rotate.instance = this; // expose the Rotate script with a static instance variable.
};

Now, from a HTML perspective, you could call “Rotate.instance.RotateSpecified(90);” on the DOM “onclick” event, and it would work successfully, because it is a direct reference to “Rotate.prototype” context.

Like this:

<button onclick="Rotate.instance.RotateSpecified(90)">Rotate!</button>

I hope this example has helped you out. Coding can be confusing and frustrating when you’re new to it. But just give it time and learn about how does it all works.

Now, I don’t personally create static references inside the scripts themselves, I just create a “Manager” script where I set all of the references so it’s more comprehensible and quicker to access. But the example above is the simplest way I could think of.


#7

Hey! im doing a layout for a main menu for the game right now ok? But i cant bc i got removed from development XD


#8

Here is an example of the html element:

<div id="container">
    <div class = "division" id = "left">
        Advertisement
    </div>
    <div class = "division" id = "middle">
        <div id = "title">Amature game</div>
        <form method="get">
        name: <input type="text" name="name"><br>
        <input type="submit" value="Play">
        </form>    
    </div>
    <div class = "division" id = "right"></div>
</div>

Here is an Example of the css element:

.#container{
    margin-top: 10px;
    width: 636px;
    transform: scale(1);
    transform-origin: bottom;
}

.division{
    background-color: #222;
    padding-radius: 5px;
    opacity: 0.8;
}

.title{
font-size: 5em;
color: black;
}

#left{
    background-color: rgba(0,0,0,.5);
    border-radius: 5px;
    box-sizing: border-box;
    margin-right: 30px;
    width: 300px;
}

#middle{
}

#right{

}

Here is the JS:

var overlay = pc.createScript('overlay');

overlay.attributes.add("css",{type:"asset", assetType:"css", title:"css"});
overlay.attributes.add('html', {type: 'asset', assetType:'html', title: 'HTML Asset'});

overlay.prototype.initialize = function(){
    var self = this;
    var style = document.createElement('style');
    document.head.appendChild(style);
    style.innerHTML = this.css.resource || '';
    
    
    // append to body
    // can be appended somewhere else
    // it is recommended to have some container element
    // to prevent iOS problems of overfloating elements off the screen

    
    this.div = document.createElement("div");
    this.div.classList.add('container');
    this.div.innerHTML = this.html.resource || "";
    document.body.appendChild(this.div);
};

overlay.prototype.update = function(){
    
};

This second overlay is unnecessary but its here:

var overlay2 = pc.createScript('overlay2');

overlay2.attributes.add("sceneId", {type: "string", default: "0", title: "Scene ID to Load"});


// initialize code called once per entity
overlay2.prototype.initialize = function() {
    this.entity.button.on("click",this.changeScenes,this);
};

// update code called every frame
overlay2.prototype.update = function(dt) {
    
};

overlay2.prototype.changeScenes = function() {
    // Get a reference to the current root object
    var oldHierarchy = this.app.root.findByName ('Root');
    
    // Load the new scene. The scene ID is found by loading the scene in the editor and 
    // taking the number from the URL
    // e.g. If the URL when Scene 1 is loaded is: https://playcanvas.com/editor/scene/475211
    // The ID is the number on the end (475211)
    this.loadScene (this.sceneId, function () {
        // Once the new scene has been loaded, destroy the old one
        oldHierarchy.destroy ();
    });
};

overlay2.prototype.loadScene = function (id, callback) {
    // Get the path to the scene
    var url = id  + ".json";
    
    // Load the scenes entity hierarchy
    this.app.loadSceneHierarchy(url, function (err, parent) {
        if (!err) {
            callback(parent);
        } else {
            console.error (err);
        }
    });
};
// swap method called for script hot-reloading
// inherit your script state here
// overlay2.prototype.swap = function(old) { };

// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/

Here is what my layout for the screen looks like:
05%20AM%20-%20Edited
Here is an example what it looks like when u start the game:
The camera rotates around the map but if u dont want to show the map just put a screen in ur html and css and put the play button on that screen.
05%20AM%20-%20Edited%20(1)
Let me know if this helps!


#9

You could also use different scenes for your main menu. Check out our game at www.crazygames.com/games/space-escape. Is this the sort of main menu you want?


#10

I have a test scene with a menu that uses Bootstrap: https://playcanvas.com/editor/scene/708562

You can use this library and vanilla JavaScript to work with the DOM. You can also use Vue.js, for example.


#11

buti i dont use any of those libraries I only know basic javascript


#12

You do not need any kind of library to directly work with the DOM, DOM = Any HTML Element.

You can easily access all DOM’s by setting an id in HTML and just using document.getElementById('whatever-id').somevalue.


#13

um ok i guess i could try


#14

If u want i can make one for u. then u could just use javascript to work it


#15

I would rather you show me how to do it because im the type of person to wanna do things for myself.


#16

Ok ill add you to the project then ill show u two in one health and menu then u can use it to make ur own!


#17

ok
thnx again man theyll hopefully help


#18

you dont have to use html, you could just use playcanvas elements to create ui, look up 2d screen.


#19

dude i already know button i just want the buttons to link to the game when a button is pressed it goes from the main menu to the game


#20

As a few forum members are having trouble with this, I’ve made a full example with the PlayCanva UI system and the newer API for getting the scene URLs.

This shows how to listen for the button events and loading/unloading scenes that don’t require the use of asset ids making it more robust when forking and maintaining scenes.

https://playcanvas.com/project/606575/overview


From HTML menu to first person
#21

um ok thnx ill try it


#22

wooahh you actually didi it finally now i can make a cool looking main menu thnx


#23

OHHHHH ok i see what u mean now thx! that was really confusing


#24

Yep thts the easiest way


#25

@yaustar Thanks! I will use this sample for now (Credit Do To You) But i will change it when i make my own script ok? I feel i should still make my own i dont like it being done for me but at least now someone can use it for help rn. :slight_smile: