Scale Mode "Blend" for Camera Space (World Space) Screen


#1

Hi fellow devs,

since I couldn’t figure out how to render a Spine animation within a screen space GUI (HERE), I ended up writing a Camera Space GUI script.

A camera space GUI is a world space GUI which is set in front of the camera with a fixed distance, so it looks like a screen space GUI (but can render Spine animations).

This is my script, which I add on a world space GUI that is parented under a camera:

var CameraSpaceGui = pc.createScript('cameraSpaceGui');

CameraSpaceGui.attributes.add('cameraEntity', {
    title: 'Camera',
    type: 'entity'
});

CameraSpaceGui.attributes.add('distance', {
    title: 'Distance to camera',
    type: 'number'
});

// initialize code called once per entity
CameraSpaceGui.prototype.initialize = function() 
{
    this._registerEvents();
    
    this._rescale();
};

CameraSpaceGui.prototype._registerEvents = function()
{
    this.resizeListener = this._rescale.bind(this);

    window.addEventListener('resize', this.resizeListener);
    
    this.on('destroy', this._deregisterEvents);
};

CameraSpaceGui.prototype._deregisterEvents = function()
{
    window.removeEventListener('resize', this.resizeListener);
};

CameraSpaceGui.prototype.resizeListener = function()
{
    window.removeEventListener('resize', this.resizeListener);
};

CameraSpaceGui.prototype._rescale = function()
{
    // adapt screen resolution
    var nativeWidth = window.innerWidth * window.devicePixelRatio;
    var nativeHeight = window.innerHeight * window.devicePixelRatio;    
        
    this.entity.screen.resolution = new pc.Vec2(nativeWidth, nativeHeight);
    
    // set position and scale
    this.entity.setLocalPosition(0,0,-this.distance);

    // set needed scale at given distance
    var frustumHeightAtDistance = 2.0 * this.distance * Math.tan(this.cameraEntity.camera.fov * 0.5 * pc.math.DEG_TO_RAD);
    var scale = 1 / nativeHeight * frustumHeightAtDistance;
    
    this.entity.setLocalScale(scale,scale,1);   
};

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

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

Currently it resizes itself properly to the device screen resolution. But I couldn’t figure out how to also automatically rescale its child elements, like the screen space GUI does when having scale mode set to “blend”.

The PlayCanvas Screen Component prohibits this for world space cameras -.-

How can one let the child elements adjust their scale, like in a screen space GUI?

Any hints appreciated,
Rene


Spine Animation in Screenspace GUI