Modify Picker_raycast script

Credit to @Albertos for the code.

changes I want to make:

Make it so I can set the rotation and position I want it to go to when I pick it up

Make it so if I just click the right mouse I drop the entity, but if I hold the right mouse I throw it forward.

Make it so I can press F to pick it up not the left mouse.

var PickerRaycast = pc.createScript('pickerRaycast');

// initialize code called once per entity
PickerRaycast.prototype.initialize = function() {
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onSelect, this);
    
    this.on('destroy', function() {
        this.app.mouse.off(pc.EVENT_MOUSEDOWN, this.onSelect, this);
    }, this);

    this.dragging = false;
    this.pickedEntity = null;
    this.raycastDistance = 5;
};

PickerRaycast.prototype.onSelect = function (event) {
    // check if not already dragging
    if (!this.dragging) {
        // create raycast to check if there is an entity to drag
        var screenCenterX = (this.app.graphicsDevice.width / 2) * this.app.graphicsDevice.maxPixelRatio;
        var screenCenterY = (this.app.graphicsDevice.height / 2) * this.app.graphicsDevice.maxPixelRatio;
        var start = this.entity.camera.screenToWorld(screenCenterX, screenCenterY, this.entity.camera.nearClip);
        var end = this.entity.camera.screenToWorld(screenCenterX, screenCenterY, this.raycastDistance);

        this.app.systems.rigidbody.raycastFirst(start, end, function (result) {
            // check if entity is pickable
            if (result.entity.tags.has('pickable')) {
                // start dragging
                this.dragging = true;

                // get entity
                this.pickedEntity = result.entity;

                // get correct position and rotation to drag
                var dragPosition = this.pickedEntity.getPosition();
                var dragRotation = this.pickedEntity.getRotation();

                // change rigidbody type to be able to drag
                this.pickedEntity.rigidbody.type = 'kinematic';

                // make entity part of player
                this.pickedEntity.reparent(this.entity);

                // apply correct position and rotation 
                this.pickedEntity.setPosition(dragPosition);
                this.pickedEntity.setRotation(dragRotation);
            }
        }.bind(this));
    }
    // if already dragging prepare entity for release
    else {
        // get correct position and rotation to drop
        var dropPosition = this.pickedEntity.getPosition();
        var dropRotation = this.pickedEntity.getRotation();

        // make entity part of world
        this.pickedEntity.reparent(this.app.root.findByName('Root'));

        // apply correct position and rotation 
        this.pickedEntity.setPosition(dropPosition);
        this.pickedEntity.setRotation(dropRotation);

        // change rigidbody type back to original
        this.pickedEntity.rigidbody.type = 'dynamic';

        // end dragging
        this.dragging = false;
    }
};

I’m not sure what you mean by this, but if you look at the script you can find a place where the position and rotation are set. You can change this with your own position and rotation.

For this you need to create something to detect if the mouse is hold or not. You can use I timer for this. There are some topics on the forum about how to create a timer.

This requires you to split the current onSelect function into two separate functions. One to pick up and one to drop. Another option is to let the current onSelect function know if you want to pick up or drop.

This is what I have to set the rotation and position of it. What I meant is I want it to go to a certain place when it re parents to the player.

// apply correct position and rotation 
                this.pickedEntity.setLocalPosition(-2.702,1.629,18.765);
                this.pickedEntity.setLocalRotation(-99.84,-57.7,18.21);

Does that not give the correct result? Maybe you can try to use setLocalEulerAngles instead of setLocalRotation. Be aware currently it’s both local, so based on the position and rotation of the player entity.

@Albertos I have made it so the rotation is correct with the angles, but what function would I use to do the position?

The picked entity is following the movements of the player, so if you want to set the picked entity for example on the hands of the player, you can use setLocalPosition, like you already did.

It did not work, I can’t even see the entity

Not sure what could be wrong. Try to set a child entity of the player in the editor on the right position and use the values of that position in your script.

So all I do is create a entity in the player and that’s it? just want to make sure nothing needs to be done to the script about the child entity.

Sorry, it has to be a child entity of the camera entity. Set the right position and use this position in your script.

Still won’t work

Here is the link if you wan’t to take a look

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

Your setup looks correct to me.

Then what could be the problem?

I’m not at home so I can’t test your project. Can you show the current result?

Screenshot 2022-06-11 7.34.12 PM
See the shadow of the hammer, that is the problem I don’t know about the X & Z position though. All I can see is the issue is the Y position.

It seems my prediction was correct. The error was the Y position was to high. It is good now.

I’m not sure how the Y position can be too high if you take the correct value from the editor, but I’m glad it’s working for you now.

Thanks!

When I pick it up how would I disable the collision and when I put it down I enable the collision?

pickedEntity.collision.enabled = false;
pickedEntity.collision.enabled = true;