[SOLVED] Scene Fade In / Out Transition Not Working Correctly

I’ve been trying to code in a scene transition code. It works mostly fine, except when it’s supposed to fade out. When you are put into the level, the scene is shown to be very dark, which indicates that the dark image element overlay (through using the 2D screen), still isn’t completely transparent. I want the dark image overlay to decrease it’s opacity when the scene is played, but I can’t seem to find a solution to my problem. Here’s the code I’m using to switch scenes. (Quick Sidenote: When I say scenes, I mean subroots. A subroot is basically a root for a different part of the game in the same scene. Usually, I disable / enable these subroots in order to go from let’s say the title screen, to the scene the main game is located at. If you want a more visual example, go to the editor.)

ChangeScene (Subroot) Code:

var ChangeScene = pc.createScript('changeScene');

ChangeScene.attributes.add("cs", { type: 'entity', title: 'Current Scene' });
ChangeScene.attributes.add("ns", { type: 'entity', title: 'New Scene' });
ChangeScene.attributes.add("useCard", { type: 'boolean', title: 'Use Transition?' });
ChangeScene.attributes.add("tcard", { type: 'entity', title: 'Current Scene Card' });
ChangeScene.attributes.add("tcardn", { type: 'entity', title: 'New Scene Card' });
ChangeScene.attributes.add("tspeed", { type: 'number', default: 0.1, title: 'Transition Speed' });

var lightsOut = false;
var lightsOn = false;

// initialize code called once per entity
ChangeScene.prototype.initialize = function() {
    this.entity.element.on('mouseenter', this.onEnter, this);
    this.entity.element.on('mouseleave', this.onLeave, this);
    this.entity.element.on('click', this.onClick, this);
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this);
    this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this);

// update code called every frame
ChangeScene.prototype.update = function(dt) {
    if (lightsOut === true) {
        this.tcard.element.opacity += this.tspeed;
        if (this.tcard.element.opacity >= 1) {
            this.tcard.element.opacity = 1;
            this.cs.enabled = false;
            this.ns.enabled = true;
            lightsOn = true;
    if (lightsOn === true) {
        this.tcardn.element.opacity -= this.tspeed;
        if (this.tcardn.element.opacity <= 0) {
            this.tcardn.element.opacity = 0;   
            lightsOn = false;
            lightsOut = false;

ChangeScene.prototype.onEnter = function(event) {
    document.body.style.cursor = 'pointer';  

ChangeScene.prototype.onLeave = function(event) {
    document.body.style.cursor = 'default';  

ChangeScene.prototype.onClick = function(e) {
    if (this.useCard === false) {
        this.cs.enabled = false;
        this.ns.enabled = true;
        this.tcard.enabled = false;
        this.tcardn.enabled = false;
    else if (this.useCard === true) {
        lightsOut = true;

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

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

Link To Editor: https://playcanvas.com/editor/scene/920602

Still need help on fixing this. Anyone got a solution?

Hi, I don’t use the editor and I don’t know how exactly the scripts work in it but I can see that the changeScene.js is a component of PlayButton entity and this.cs is set to a root entity of the PlayButton entity. If you set this.cs.enabled = false (as you do when this.tcard.element.opacity >= 1) the script stops running and that’s the reason why you see the black overlay in your second scene (this.tcardn.element.opacity is 0.9 never change because the script is not called anymore).


Hmm, makes, sense. Thank you. I’ll see if making a fade in script in the new game scene does naything.

You were right! I rearranged my code so that I use an entity outside of title to fade in the new scene.