What's a good way to know WHAT entity I picked


#1

I’m using the raycasting method at the moment but here is something I tried, but it didn’t work. What am I not seeing?

TapObject.attributes.add('idleAnim',{type:'entity'});
TapObject.attributes.add('attackAnim',{type:'entity'});
var idle = true;

this.app.systems.rigidbody.raycastFirst(from, to, function (result) {
        var pickedEntity = result.entity;

        if(pickedEntity === this.idleAnim){
            idle = false;
        } else if (pickedEntity === this.attackAnim) {
            idle=true;
        }
        
    });

The frame buffer method seems a legit way of controlling what is being clicked, but I have a feeling there may be a simpler solution.

Perhaps making a script that can be attached per entity versus the camera? Or some use of arrays? I do not know much about arrays, or ways to use the ray tracing technique to solve this problem. I’ll keep digging but would love some help on this. :smiley: thanks.


[SOLVED] Is there a way to detect a mobile device?
#2

and for the record i do have the intializing code i just didn’t include it so you can get to the root of the problem which is somewhere found in the if(pickedEntity === this.idleAnim)

Because I have simple code now that makes it do what I want, but the issue is it doesn’t matter what entity I click on.


#3

3 ways off the top of my head:

  • Raycasting using physics objects with a physics system (either ammo.js which is what PlayCanvas supports natively or one of the other major Javascript physics library. If using ammo.js, then you will need to enable physics in the project settings and give each entity a rigidbody and collider that you would like to raycast against) Example here.

  • Using the framebuffer Example here.

  • Using the shapes library which supports AABB, OBB and spheres. Example here

There are others but these are the 3 that are inherently built into PlayCanvas.

Edit: Re-reading this, I’m not 100% sure what you are asking. Raycasting returns the entity that it ‘hits’ so you know what entity you picked.


#4

So this is a piggy back off of what my other post was about.

I want to know that I’m pressing the UP value then make things go UP

versus the DOWN value making things go down.

The way I have the code work now basically treats ALL THINGS AS UP VALUES. Make sense?

I want to know that when I pick entity 1, it will return a specific function, instead of treating all entities equally.


#5

So in my pseudo code the logic I had in mind was something like

If the resulting entity that was clicked === a specific attributed entity I have added to this script, then do a thing.


#6

It seems like the last option you sent works the way I would intend, but I don’t know for sure.

Because I can see that only the BOX will get spheres, where the plane does not. What I like about that project example as well is that it doesn’t need a collision box. It seems pretty focused on the attributed ‘Box Entity’

This is idea because I think if I can backwards engineer this to be instead of ‘Box Entity’ I can have it be ‘Up’ ‘Down’ ‘etc’ Then use the functions within the script to do unique functions based on what was actually ray casted.

Thoughts?


#7

Please do not make multiple posts in a row, when you can edit previous post and add comment if nobody yet answered after it.

Best way to get better and coding and development logic, is to learn from tutorials https://developer.playcanvas.com/en/ and User Manual.


#8

Are you trying to make on-screen controls? If so, you probably better off use the sprite buttons like Will has done here for the UI in Flappy Birds (Start button on the title screen) https://playcanvas.com/project/375389/overview/flappy-bird


#9

Yes the answer seems to clearly be in the example that Will did, @yaustar
It’s overwhelming but I’ll try to decipher this the best I can, thanks very much!

Also sorry for the spam! Got way too excited. Keep in mind I have been pretty good about scouring the User Manual, but it has quite a bit of info, I’m just taking bit by bit on as it comes. Thanks again for your time and patience. I understand some of my questions may be super easy possibly to answer I’m just clueless to a lot of this.

I’ll keep at it.


#10

Spent almost 2 hours trying to figure this ish out.

And well I got it to do as I was hoping. I wanted to understand the code, not to simply copy and paste, so I think I got a good handle on it.

Here is a gif of how I got the code to work for me. Simple touch the dudes they change animations.
With this problem solved, for now, I think I’ll be able to make Ultra Mech Show Down now lol.

Here is the code as I made it now for anyone who is interested, for the future.

var Button = pc.createScript('button');
//Attributes to help me decide and control what each button can do. 
Button.attributes.add('words',{type:'string'});
Button.attributes.add('idleAnim',{type:'entity'});
Button.attributes.add('attackAnim',{type:'entity'});

Button.prototype.initialize = function() {
    this.min = new pc.Vec3();
    this.max = new pc.Vec3();
    
    this.mouseDownListener = function(e) {
        this.press(e.clientX, e.clientY);
    }.bind(this);
    this.mouseUpListener = function(e) {
        this.release();
    }.bind(this);
    
    this.touchStartListener = function (e) {
        var touch = e.changedTouches[0];
        this.press(touch.clientX, touch.clientY);
    }.bind(this);
    this.touchEndListener = function (e) {
        this.release();
    }.bind(this);
    window.addEventListener('mousedown', this.mouseDownListener, false);
    window.addEventListener('mouseup', this.mouseUpListener, false);
    window.addEventListener('touchstart', this.touchStartListener, false);
    window.addEventListener('touchend', this.touchEndListener, false);
};

Button.prototype.checkForClick = function (x,y){
    
    var cameraEntity = this.app.root.findByName('Camera');
    var aabb = this.entity.model.model.meshInstances[0].aabb;
    cameraEntity.camera.worldToScreen(aabb.getMin(), this.min);
    cameraEntity.camera.worldToScreen(aabb.getMax(), this.max);
    if ((x >= this.min.x) && (x <= this.max.x) &&
        (y >= this.max.y) && (y <= this.min.y)) {
        return true;
    }
    return false;
};

//This code is simply testing if it was pressed. And if so print to console the attributed String and change animations 
Button.prototype.press = function (x, y) {
    if (this.checkForClick(x, y)) {
        console.log(this.words);
        this.idleAnim.enabled = false;
        this.attackAnim.enabled = true;
    } 
};

Button.prototype.release = function () {
  
    this.idleAnim.enabled = true;
    this.attackAnim.enabled = false;
    
};