Change object when an actual object itself is clicked

Hi, I have a script which changes the colour of an object when the mouse button is clicked. Which works great. To edit this script so that it only changes the object when the actual object is clicked itself. How would I go about that?

thanks

var Texturechange = pc.createScript('texturechange');

Texturechange.prototype.initialize = function() {
    
};

Texturechange.prototype.update = function(dt) {
    
};

Texturechange.attributes.add('redMaterial', {
    type: 'asset',
    assetType: 'material'
});

Texturechange.attributes.add('greenMaterial', {
    type: 'asset',
    assetType: 'material'
});

Texturechange.prototype.initialize = function() {
    this.pos = new pc.Vec3();
    this.app.mouse.disableContextMenu();
    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this);
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this);
};

Texturechange.prototype.onMouseMove = function (event) {
 
};

Texturechange.prototype.onMouseDown = function (event) {

    if (event.button === pc.MOUSEBUTTON_LEFT) {
        

        this.entity.model.meshInstances[0].material = this.redMaterial.resource;
    }

 

};

Hi @jono3d! On the page below there are two ways explained how you can achieve this in combination with your own code.

https://developer.playcanvas.com/en/tutorials/entity-picking/

1 Like

Hi @jono3d,

You can do this pretty easily using physics and raycasting. Here is a quick demo I slapped together using elements of your code:

Here is the script I am using:

var Raycast = pc.createScript('raycast');


Raycast.attributes.add('redMaterial', {
    type: 'asset',
    assetType: 'material'
});

Raycast.attributes.add('greenMaterial', {
    type: 'asset',
    assetType: 'material'
});

Raycast.prototype.initialize = function() {
    var app = this.app;
    
    if (!this.entity.camera) {
        console.error('This script must be applied to an entity with a camera component.');
        return;
    }

    // Add a mousedown event handler
	app.mouse.on(pc.EVENT_MOUSEDOWN, this.mouseDown, this); 
    
};

Raycast.prototype.mouseDown = function (e) {
    this.doRaycast(e.x, e.y);
    
};

Raycast.prototype.doRaycast = function (screenX, screenY) {
    // The pc.Vec3 to raycast from (the position of the camera)
    var app = this.app;
    var self = this;
    var from = this.entity.getPosition();

    // The pc.Vec3 to raycast to (the click position projected onto the camera's far clip plane)
    var to = this.entity.camera.screenToWorld(screenX, screenY, this.entity.camera.farClip);

    // Raycast between the two points and return the closest hit result
    var result = this.app.systems.rigidbody.raycastFirst(from, to);

    // If there was a hit, store the entity
    if (result) {
    	result.entity.model.meshInstances[0].material = this.redMaterial.resource;
        
    }
};

https://playcanvas.com/editor/scene/1128152

If you look closely, I:

  • Added the script to the camera
  • Imported Ammo.js from the settings menu
  • Applied a Collision Component to the Cube
  • Applied a Rigidbody component to the cube
  • Chose the ‘Red Material’ In the editor

Upon Launching the project you will see that clicking on the cube and only the cube will turn it red. This demo does not change back to the green material or use the green material in any way, but you should see enough here to give you an idea of edit you can make to make it suitable for your use.

I hope this is helpful.

3 Likes