0

I am currently using Ursina Game Engine and am trying to make a basic FPS game. In the game, there is obviously a gun and a bullet.

The system I have for shooting the gun isn't working. First, it isn't moving forward the way I want it, and second, it isn't able to detect collision sufficiently.

I am wondering how I can make the gun shoot a bullet forward properly, and also how I can make it tell me when it hits something.

Here is the code I am using:

def shoot():
    print(globalvar.currentmag, globalvar.total_ammo)
    if globalvar.currentmag > 0:
        bullet = Entity(parent=weapon, model='cube', scale=0.1, color=color.brown, collision = True, collider = 'box')
        gunshot_sfx = Audio('Realistic Gunshot Sound Effect.mp3')
        gunshot_sfx.play()
        bullet.world_parent = scene
        bullet.y = 2
        for i in range(3000):
            bullet.position=bullet.position+bullet.right*0.01
        globalvar.currentmag -= 1
        hit_info = bullet.intersects()
        print(hit_info)

        if hit_info.hit:
            print("bullet hit")
            destroy(bullet, delay=0)
        destroy(bullet, delay=1)

    else:
        reload()

I have tried using the raycast method in Ursina but that did not work.

martineau
  • 119,623
  • 25
  • 170
  • 301
OHTYCH 100
  • 57
  • 1
  • 7
  • 1
    Please supply the expected [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) (MRE). We should be able to copy and paste a contiguous block of your code, execute that file, and reproduce your problem along with tracing output for the problem points. This lets us test our suggestions against your test data and desired output. Show where the intermediate results differ from what you expected. "did not work" is not a problem specification. – Prune Jun 24 '21 at 23:57
  • I don't know how Ursina works, but it looks like after running that for loop the bullet is going to be so far off the screen before the first frame is even rendered. – hostingutilities.com Jun 25 '21 at 00:40
  • You need to figure out how Ursula triggers the next frame to be rendered so that you can update the position once per frame instead of thousands of times per frame. – hostingutilities.com Jun 25 '21 at 00:47

1 Answers1

1

Don't update the bullet's position right after you create it. Instead, use its animate_position() method to let Ursina update it. Then you can check for collisions in the global update() function. Make sure that all involved entities have a collider and that they're accessible globally.

bullet = None
def input(key):
    global bullet
    if key == 'left mouse down':
        bullet = Entity(parent=weapon, model='cube', scale=.1, color=color.black, collider='box')
        bullet.world_parent = scene
        bullet.animate_position(bullet.position+(bullet.forward*500), curve=curve.linear, duration=2)
        destroy(bullet, delay=2)

def update():
    if bullet and bullet.intersects(wall).hit:
        hit_info = bullet.intersects(wall)
        print('hit wall')
        destroy(bullet)

I adapted this example from the demo code in the FirstPersonController class. I'm not sure if there's a way without specifying the other entity when calling bullet.intersects(). I think it should work because the hit_info object has various properties, among them entities but I couldn't get it to work myself.

Jan Wilamowski
  • 3,308
  • 2
  • 10
  • 23