Can someone give me a code to make my game's player's gun shoot an object as a projectile?

I added a handgun model to my player. I would like it to where whenever a specific key is pressed (Such as the space bar) the gun creates an entity that has a constant forward motion until it collides with another object. When the bullet collides with an object it should be deleted.

1 Like

Have a look at laser.js from my game:
http://simplesix.sdfgeoff.space/Scripts/laser.js

You can shoot a laser by calling … “shootLaser” with some positions (and if the shooter is the player or not - used for collision masks).
When it collides with an object it spawns a small particle and dissapears (and then a little later, the rest of it dissapears).

Not all the code is there as my game has ended up with worse code layout than I hoped, but I hope things are relatively self-explanatory.

Also, this probably isn’t the suggested method, but it works. If someone has a better method, I’m keen to hear it.

I do not know how your code works, can you please explain it?

Pretty much:

  • It creates an object, moves it to a certain location and then starts it moving.

Create an entity:

lobj = new pc.Entity();
    lobj.name = "Laser"
    app.systems.model.addComponent(lobj, {
        type: "asset",
        asset: app.assets.find('Laser.json', "model")
    });

Move it into location

    lobj.translate(pos);
    lobj.rotate(rot);
    lobj.translateLocal(pos_offset);

Add Collision/physics

    lobj.addComponent('collision', {type:'capsule', 
                                    radius:0.08, 
                                    height:0.6, 
                                    axis:2});
    if (player == true){ //Shot by player: collide with Drones
        
        lobj.addComponent('rigidbody', {type:'kinematic',
                                        group: PLAYER_WEAP_GROUP,
                                        mask: (pc.BODYGROUP_STATIC | DRONE_GROUP)
                                        });
    } else { //Shot by drone: collide with player
        lobj.addComponent('rigidbody', {type:'kinematic',
                                        group: DRONE_WEAP_GROUP,
                                        mask: (pc.BODYGROUP_STATIC | PLAYER_GROUP)
                                        });
    }

Add to scene

    lobj.rigidbody.syncEntityToBody();
    app.root.addChild(lobj);

Set it’s initial speeds

    lobj.rigidbody.linearVelocity = loc2glob(new pc.Vec3(0,-LASER_SPEED,0), lobj);
    lobj.rigidbody.angularVelocity = loc2glob(new pc.Vec3(0,200,0), lobj);

Set up a collision callback. On a collision it will run the function ‘this.collide’

    lobj.collision.on('collisionstart', this.collide);
1 Like

A couple of corrections to your code snippets, @sdfgeoff:

  1. app.systems.model.addComponent(lobj,… should be lobj.addComponent(‘model’,… You’re using the old notation there.
  2. syncEntityToBody is not longer API. Instead, use entity.rigidbody.teleport to move an physically simpulated entity around explicitly. In your example, you can simply drop the function call.

Finally, what are the loc2glob calls?

Thanks for your feedback Will.

  1. Thanks, I’ll change that
  2. Ok

loc2glob. It takes in a local vector and an entity and returns a global vector. If I simply set the velocity to a vector [0,speed,0], it will travel the same direction regardless of which way the gun is fired. By passing in an object of the correct rotation (I’ve already rotated lobj), it results in it moving forwards.
It is possible there is API for this, but I couldn’t find it.