Virtual Art Exhibition - trigger and window - HALP

Virtual Art Exhibition - tigger and window - HALP

Hey guys,
I’m an art student from Poznan, Poland. Due to the pandemic every gallery, museum is closed and shows are cancelled. So we’re trying to move our show to virtual reality. I’m good with doing 3d models, lighting, textures and such… but I’m no coder. I need help, someone who could help me or tell me how to implement my idea. And it’s fairly simple - while approaching an artwork I need a window to appear with a picture and text. I’m starting with FPM Example. So I understand I need a ‘box’ - an entity with collision component to detect when user approaches and then calls a window - which displays text in .html file. With either ‘close’ button or to simply dissapear when player moves out of trigger.

Thanks,
Nick

Hi @MAC_x64 and welcome!

Art galleries can work great with Playcanvas, the editor makes it very easy to do scene setup. I’ve worked on this project were we’ve done something similar:


http://schwittek.com/clients/lenox/

To your question, to detect when the user is close to an entity you can use triggers, take a look at this tutorial:

https://developer.playcanvas.com/en/tutorials/collision-and-triggers/

For the text/image you can use either HTML/CSS on a modal window or use Playcanvas UI elements:

https://developer.playcanvas.com/en/tutorials/?tags=ui

Thank you for your quick reply!
I’ve managed to create a window on a side of the screen.


A bunch of questions:
How do I refer to the image? seems not to be working.

How do I use this (below) to enable/disable the CSS/HTML window I’ve just created? :see_no_evil: I have no idea what commands do I need to simply turn in on and off and then on again. Also can I use this somehow so the trigger tells the window script witch HTML file to load? Or do I need to do a new script for each window/work?

Detector.prototype.initialize = function() {
    this.entity.collision.on('triggerenter', function (entity) {
        console.log(entity.name + ' has entered trigger volume.');
    });
    this.entity.collision.on('triggerleave', function (entity) {
        console.log(entity.name + ' has left trigger volume.');
    });
};```

If you are using HTML then the easiest way would be to host your images externally to your server and link their urls.

Otherwise you will have to write a system when you get the url of a Playcanvas hosted image asset and replace it in your HTML. This can be complex.

So for HTML/CSS I imagine you used some code from the tutorial project, right? Somewhere in that code the HTML gets added/enabled to the page like this:

document.body.appendChild(this.div);

You can create below that two Playcanvas events that can be used to add/remove the HTML when requested by any other script:

document.body.appendChild(this.div);
var isEnabled = true;

this.app.on('htmlWindow:enable', function(){

    if( isEnabled === false ){
        document.body.appendChild(this.div);
        isEnabled = true;
    }
}, this);

this.app.on('htmlWindow:disable', function(){

    if( isEnabled === true ){
        document.body.removeChild(this.div);
        isEnabled = false;
    }
}, this);

Now you can call these two new events in your triggers script:

this.entity.collision.on('triggerenter', function (entity) {
    this.app.fire('htmlWindow:enable');
}, this);
this.entity.collision.on('triggerleave', function (entity) {
    this.app.fire('htmlWindow:disable');
}, this);

Hang on a sec, are you trying to do this in VR with headsets or VR as in 3D environment?

If you are looking to do this in VR headsets, then you can’t use HTML to display text as it won’t render in VR. You would have to use PlayCanvas’ UI system.

Oh no, I’m just using First Person Movement as template. Re-build gallery in 3d as it is in reality and allow people to walk around on their screens.

This works perfectly! Awesome! Thank you!

The stupidest thing I can ask now is: The window is open when I launch the app. How to start the game with the window closed? Sorry for being silly, I’m really a noob here. I have to do 13 more of those :joy:
This is my code for the window:

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

okno.attributes.add('css', {type: 'asset', assetType:'css', title: 'CSS'});
okno.attributes.add('html', {type: 'asset', assetType:'html', title: 'Pracka-HTML'});

okno.prototype.initialize = function () {
	var style = document.createElement('style');

	document.head.appendChild(style);
	style.innerHTML = this.css.resource || '';

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

    document.body.appendChild(this.div);
	var isEnabled = true;
    
	this.app.on('html-pracka1:enable', function() {

		if( isEnabled === false ){
			document.body.appendChild(this.div);
			isEnabled = true;
		}
	}, this);

	this.app.on('html-pracka1:disable', function() {

		if( isEnabled === true ){
			document.body.removeChild(this.div);
			isEnabled = false;
		}
	}, this);



};

Great, you just need to remove a line (did so below, commented out) and change the isEnabled var to be false initially:

okno.prototype.initialize = function () {
	var style = document.createElement('style');

	document.head.appendChild(style);
	style.innerHTML = this.css.resource || '';

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

        //document.body.appendChild(this.div);
	var isEnabled = false;
    
	this.app.on('html-pracka1:enable', function() {

		if( isEnabled === false ){
			document.body.appendChild(this.div);
			isEnabled = true;
		}
	}, this);

	this.app.on('html-pracka1:disable', function() {

		if( isEnabled === true ){
			document.body.removeChild(this.div);
			isEnabled = false;
		}
	}, this);
};

Thanks! I had the same idea to remove that line - but didn’t change the isEnabled var :joy:

1 Like